@acorex/platform 20.8.12 → 20.8.14

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 (123) hide show
  1. package/{types/acorex-platform-auth.d.ts → auth/index.d.ts} +2 -14
  2. package/{types/acorex-platform-common.d.ts → common/index.d.ts} +30 -302
  3. package/{types/acorex-platform-core.d.ts → core/index.d.ts} +44 -188
  4. package/{types/acorex-platform-domain.d.ts → domain/index.d.ts} +412 -744
  5. package/fesm2022/acorex-platform-auth.mjs +27 -125
  6. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  7. package/fesm2022/{acorex-platform-common-common-settings.provider-Bi1RYif5.mjs → acorex-platform-common-common-settings.provider-DVvuLUfF.mjs} +32 -30
  8. package/fesm2022/acorex-platform-common-common-settings.provider-DVvuLUfF.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-common.mjs +205 -711
  10. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-core.mjs +127 -420
  12. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-domain.mjs +830 -561
  14. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-builder.mjs +114 -634
  16. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs → acorex-platform-layout-components-binding-expression-editor-popup.component-CSxCnzwU.mjs} +9 -9
  18. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CSxCnzwU.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-layout-components.mjs +877 -3362
  20. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-designer.mjs +204 -456
  22. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-layout-entity.mjs +10062 -14672
  24. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  25. package/fesm2022/acorex-platform-layout-views.mjs +171 -413
  26. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  27. package/fesm2022/acorex-platform-layout-widget-core.mjs +441 -507
  28. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  29. package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs → acorex-platform-layout-widgets-button-widget-designer.component-CPBzE96V.mjs} +10 -10
  30. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-CPBzE96V.mjs.map +1 -0
  31. package/fesm2022/{acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs → acorex-platform-layout-widgets-file-list-popup.component-Dtv6U3df.mjs} +76 -21
  32. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-Dtv6U3df.mjs.map +1 -0
  33. package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs → acorex-platform-layout-widgets-image-preview.popup-QxJfswhK.mjs} +7 -6
  34. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-QxJfswhK.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs → acorex-platform-layout-widgets-page-widget-designer.component-CVdssZBD.mjs} +12 -12
  36. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-CVdssZBD.mjs.map +1 -0
  37. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BCxE0RTB.mjs +111 -0
  38. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BCxE0RTB.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DVaZN9QN.mjs} +5 -5
  40. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DVaZN9QN.mjs.map +1 -0
  41. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-DPGHgXa6.mjs} +4 -4
  42. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-DPGHgXa6.mjs.map +1 -0
  43. package/fesm2022/{acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs → acorex-platform-layout-widgets-text-block-widget-designer.component-CdiNW691.mjs} +6 -6
  44. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-CdiNW691.mjs.map +1 -0
  45. package/fesm2022/acorex-platform-layout-widgets.mjs +3408 -5611
  46. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  47. package/fesm2022/acorex-platform-native.mjs +7 -8
  48. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  49. package/fesm2022/acorex-platform-runtime.mjs +166 -391
  50. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  51. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-D4hU2SCE.mjs +160 -0
  52. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-D4hU2SCE.mjs.map +1 -0
  53. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D2CtNrSn.mjs +1716 -0
  54. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D2CtNrSn.mjs.map +1 -0
  55. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BVTklnzs.mjs +120 -0
  56. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BVTklnzs.mjs.map +1 -0
  57. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs → acorex-platform-themes-default-entity-master-single-view.component-rGsMVAZj.mjs} +23 -16
  58. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-rGsMVAZj.mjs.map +1 -0
  59. package/fesm2022/{acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs → acorex-platform-themes-default-error-401.component-53VB-PS_.mjs} +4 -4
  60. package/fesm2022/acorex-platform-themes-default-error-401.component-53VB-PS_.mjs.map +1 -0
  61. package/fesm2022/{acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs → acorex-platform-themes-default-error-404.component-DVF9soT5.mjs} +4 -4
  62. package/fesm2022/acorex-platform-themes-default-error-404.component-DVF9soT5.mjs.map +1 -0
  63. package/fesm2022/acorex-platform-themes-default-error-offline.component-CwNNHzZn.mjs +19 -0
  64. package/fesm2022/acorex-platform-themes-default-error-offline.component-CwNNHzZn.mjs.map +1 -0
  65. package/fesm2022/acorex-platform-themes-default.mjs +61 -1784
  66. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  67. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs → acorex-platform-themes-shared-icon-chooser-column.component-TJ9PWHMY.mjs} +6 -6
  68. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-TJ9PWHMY.mjs.map +1 -0
  69. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BHcKkIx0.mjs} +6 -6
  70. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BHcKkIx0.mjs.map +1 -0
  71. package/fesm2022/{acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs → acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs} +25 -24
  72. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +1 -0
  73. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-BUPs84MI.mjs +65 -0
  74. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-BUPs84MI.mjs.map +1 -0
  75. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BotknoHn.mjs +64 -0
  76. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BotknoHn.mjs.map +1 -0
  77. package/fesm2022/acorex-platform-themes-shared.mjs +305 -408
  78. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  79. package/fesm2022/acorex-platform-workflow.mjs +100 -359
  80. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  81. package/fesm2022/acorex-platform.mjs.map +1 -1
  82. package/{types/acorex-platform-layout-builder.d.ts → layout/builder/index.d.ts} +38 -160
  83. package/{types/acorex-platform-layout-components.d.ts → layout/components/index.d.ts} +125 -854
  84. package/{types/acorex-platform-layout-designer.d.ts → layout/designer/index.d.ts} +18 -96
  85. package/{types/acorex-platform-layout-entity.d.ts → layout/entity/index.d.ts} +65 -848
  86. package/{types/acorex-platform-layout-views.d.ts → layout/views/index.d.ts} +47 -80
  87. package/{types/acorex-platform-layout-widget-core.d.ts → layout/widget-core/index.d.ts} +197 -274
  88. package/{types/acorex-platform-layout-widgets.d.ts → layout/widgets/index.d.ts} +124 -608
  89. package/{types/acorex-platform-native.d.ts → native/index.d.ts} +7 -0
  90. package/package.json +36 -36
  91. package/runtime/index.d.ts +307 -0
  92. package/{types/acorex-platform-themes-default.d.ts → themes/default/index.d.ts} +4 -113
  93. package/{types/acorex-platform-themes-shared.d.ts → themes/shared/index.d.ts} +4 -5
  94. package/{types/acorex-platform-workflow.d.ts → workflow/index.d.ts} +81 -162
  95. package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs +0 -116
  102. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs +0 -160
  107. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs.map +0 -1
  108. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs +0 -120
  109. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +0 -1
  113. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +0 -19
  114. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs.map +0 -1
  118. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs +0 -94
  119. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs.map +0 -1
  120. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs +0 -86
  121. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +0 -1
  122. package/types/acorex-platform-runtime.d.ts +0 -571
  123. /package/{types/acorex-platform.d.ts → index.d.ts} +0 -0
@@ -1,14 +1,11 @@
1
1
  import * as i5 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Injectable, inject, input, model, signal, computed, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
5
- import { provideCommandSetups, AXPCommandService } from '@acorex/platform/runtime';
4
+ import { Injectable, inject, input, model, signal, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
6
5
  import { AXPopupService } from '@acorex/components/popup';
7
- import * as i4 from '@acorex/platform/core';
8
- import { AXPHookService, AXPExpressionEvaluatorService, AXPComponentSlotModule, AXPContextStore } from '@acorex/platform/core';
9
6
  import * as i1 from '@acorex/platform/layout/widget-core';
10
- import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule, AXPWidgetRegistryService } from '@acorex/platform/layout/widget-core';
11
- import { cloneDeep, isNil, set, isEqual, merge } from 'lodash-es';
7
+ import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
8
+ import { cloneDeep, isNil, set, isEqual } from 'lodash-es';
12
9
  import * as i2 from '@acorex/components/form';
13
10
  import { AXFormComponent, AXFormModule } from '@acorex/components/form';
14
11
  import { Subject, debounceTime, distinctUntilChanged, startWith } from 'rxjs';
@@ -20,35 +17,9 @@ import * as i3 from '@acorex/components/loading';
20
17
  import { AXLoadingModule } from '@acorex/components/loading';
21
18
  import { AXBasePageComponent } from '@acorex/components/page';
22
19
  import * as i6 from '@acorex/core/translation';
23
- import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
24
- import { AXP_ENTITY_DEFINITION_CRUD_SERVICE } from '@acorex/platform/domain';
25
-
26
- //#region ---- Imports ----
27
- //#endregion
28
- //#region ---- Before open ----
29
- /**
30
- * Runs after dialog options and context are prepared and **before** footer customization and popup open.
31
- * Listeners may mutate {@link AXPLayoutBuilderDialogBeforeOpenPayload.context} by reference.
32
- */
33
- const AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY = 'layout-builder.dialog.before-open';
34
- //#endregion
35
- //#region ---- Footer actions ----
36
- /**
37
- * Runs after builder-defined footer actions exist and **before** the dialog opens.
38
- * Listeners receive the live `actions.footer.prefix` / `suffix` arrays (same references as the dialog)
39
- * so they may push, splice, filter, or replace items. They may also mutate {@link AXPLayoutBuilderDialogFooterPayload.context} by reference.
40
- */
41
- const AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY = 'layout-builder.dialog.config';
42
- //#endregion
43
- //#region ---- Context updates (after open) ----
44
- /**
45
- * Runs whenever the dialog layout builder context changes (debounced upstream), **after** the popup is visible.
46
- * Use for side effects that depend on live context (for example values updated by widgets after render).
47
- * Payload mirrors `AXPDialogRendererComponent` semantics: {@link AXPLayoutBuilderDialogContextChangedPayload.getContext},
48
- * {@link AXPLayoutBuilderDialogContextChangedPayload.patchContext}, and optional loading state.
49
- */
50
- const AXP_LAYOUT_BUILDER_DIALOG_CONTEXT_CHANGED_HOOK_KEY = 'layout-builder.dialog.context-changed';
51
- //#endregion
20
+ import { AXTranslationModule } from '@acorex/core/translation';
21
+ import * as i4 from '@acorex/platform/core';
22
+ import { AXPExpressionEvaluatorService, AXPComponentSlotModule } from '@acorex/platform/core';
52
23
 
53
24
  class AXPLayoutConversionService {
54
25
  constructor() {
@@ -188,10 +159,6 @@ class AXPLayoutConversionService {
188
159
  if (!editorWidget.mode) {
189
160
  editorWidget.mode = fieldMode;
190
161
  }
191
- const hintOpts = field.description != null &&
192
- (typeof field.description !== 'string' || field.description.trim().length > 0)
193
- ? { hint: field.description, hintDisplayMode: 'note' }
194
- : {};
195
162
  return {
196
163
  type: 'form-field',
197
164
  name: field.path,
@@ -199,8 +166,8 @@ class AXPLayoutConversionService {
199
166
  options: {
200
167
  label: field.title,
201
168
  badge: field.badge,
169
+ description: field.description,
202
170
  showLabel: true,
203
- ...hintOpts,
204
171
  },
205
172
  children: [editorWidget], // The editor widget becomes a child of form-field
206
173
  };
@@ -243,7 +210,7 @@ class AXPLayoutConversionService {
243
210
  path: formFieldNode.name || editorWidget.name || `field-${Date.now()}`,
244
211
  title: formFieldNode.options?.['label'],
245
212
  badge: formFieldNode.options?.['badge'],
246
- description: formFieldNode.options?.['hint'],
213
+ description: formFieldNode.options?.['description'],
247
214
  widget: editorWidget,
248
215
  mode: formFieldNode.mode,
249
216
  };
@@ -256,16 +223,9 @@ class AXPLayoutConversionService {
256
223
  const keyParts = [];
257
224
  keyParts.push(`groups:${formDefinition.groups.length}`);
258
225
  formDefinition.groups.forEach((group, groupIndex) => {
259
- // Include group.mode so view vs edit (or mixed) layouts do not share a cached widget tree.
260
- const groupModePart = group.mode ?? '_';
261
- keyParts.push(`g${groupIndex}:${group.name}:${group.parameters.length}:${groupModePart}`);
262
- keyParts.push(`gL${groupIndex}:${JSON.stringify(group.title ?? null)}:${JSON.stringify(group.description ?? null)}`);
226
+ keyParts.push(`g${groupIndex}:${group.name}:${group.parameters.length}`);
263
227
  group.parameters.forEach((param, paramIndex) => {
264
- // Field mode must be part of the key; otherwise metadata forms that only differ by
265
- // view/edit (same paths and widget types) incorrectly reuse the first cached tree.
266
- const fieldModePart = param.mode ?? '_';
267
- keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}:${fieldModePart}`);
268
- keyParts.push(`pL${groupIndex}.${paramIndex}:${JSON.stringify(param.title ?? null)}:${JSON.stringify(param.description ?? null)}:${JSON.stringify(param.badge ?? null)}`);
228
+ keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}`);
269
229
  });
270
230
  });
271
231
  if (formDefinition.mode) {
@@ -326,10 +286,10 @@ class AXPLayoutConversionService {
326
286
  }
327
287
  return Math.abs(hash).toString(36); // Convert to base36 for shorter string
328
288
  }
329
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
330
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
289
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
290
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
331
291
  }
332
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
333
293
  type: Injectable,
334
294
  args: [{
335
295
  providedIn: 'root',
@@ -439,18 +399,17 @@ function getNestedValue(obj, path) {
439
399
  class AXPLayoutBuilderService {
440
400
  constructor() {
441
401
  this.popupService = inject(AXPopupService);
442
- this.hookService = inject(AXPHookService, { optional: true }) ?? undefined;
443
402
  }
444
403
  /**
445
404
  * Create a new layout builder
446
405
  */
447
406
  create() {
448
- return new LayoutBuilder(this.popupService, this.hookService);
407
+ return new LayoutBuilder(this.popupService);
449
408
  }
450
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
451
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
409
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
410
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
452
411
  }
453
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
454
413
  type: Injectable,
455
414
  args: [{
456
415
  providedIn: 'root',
@@ -463,9 +422,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
463
422
  * Open/Closed: Extensible through container delegates
464
423
  */
465
424
  class LayoutBuilder {
466
- constructor(popupService, hookService) {
425
+ constructor(popupService) {
467
426
  this.popupService = popupService;
468
- this.hookService = hookService;
469
427
  this.root = {
470
428
  children: [],
471
429
  mode: 'edit',
@@ -535,7 +493,7 @@ class LayoutBuilder {
535
493
  if (!this.popupService) {
536
494
  throw new Error('LayoutBuilder requires AXPopupService to create dialogs. Please inject it in the service constructor.');
537
495
  }
538
- const container = new DialogContainerBuilder(this.popupService, this.hookService);
496
+ const container = new DialogContainerBuilder(this.popupService);
539
497
  if (delegate) {
540
498
  delegate(container);
541
499
  }
@@ -560,21 +518,11 @@ class LayoutBuilder {
560
518
  return this;
561
519
  }
562
520
  build() {
563
- const r = this.root;
564
- const node = {
565
- type: r.type,
566
- ...(r.mode !== undefined ? { mode: r.mode } : {}),
567
- ...(r.children !== undefined ? { children: r.children } : {}),
568
- ...(r.options !== undefined ? { options: r.options } : {}),
569
- ...(r.name !== undefined ? { name: r.name } : {}),
570
- ...(r.path !== undefined ? { path: r.path } : {}),
571
- ...(r.visible !== undefined ? { visible: r.visible } : {}),
572
- ...(r.defaultValue !== undefined ? { defaultValue: r.defaultValue } : {}),
573
- ...(r.triggers !== undefined ? { triggers: r.triggers } : {}),
574
- ...(r.meta !== undefined ? { meta: r.meta } : {}),
575
- ...(r.valueTransforms !== undefined ? { valueTransforms: r.valueTransforms } : {}),
521
+ return {
522
+ type: this.root.type,
523
+ children: this.root.children,
524
+ mode: this.root.mode,
576
525
  };
577
- return node;
578
526
  }
579
527
  /**
580
528
  * Converts the built widget node to JSON string
@@ -643,7 +591,6 @@ class BaseContainerBuilder {
643
591
  'number-editor',
644
592
  'select-editor',
645
593
  'lookup-editor',
646
- 'entity-definition-provider-editor',
647
594
  'selection-list-editor',
648
595
  'date-time-editor',
649
596
  'toggle-editor',
@@ -746,30 +693,32 @@ class BaseContainerMixin extends BaseContainerBuilder {
746
693
  class LayoutContainerMixin extends BaseContainerMixin {
747
694
  layout(value) {
748
695
  // Map layout intent to grid item sizing so containers like `form-field`
749
- // can span multiple columns/rows inside grid/fieldset layouts.
696
+ // can span multiple columns inside grid/fieldset layouts.
750
697
  if (!this.containerState.options)
751
698
  this.containerState.options = {};
752
699
  if (typeof value === 'number') {
700
+ // Direct numeric shorthand → colSpan
753
701
  this.containerState.options.colSpan = value;
754
702
  }
755
703
  else if (value) {
704
+ // Try to extract grid positioning from breakpoint positions
756
705
  const positions = value.positions;
757
706
  if (positions) {
758
- const placement = positions?.lg ?? positions?.xl ?? positions?.xxl ?? positions?.md ?? positions?.sm;
759
- if (placement) {
760
- const opts = this.containerState.options;
761
- if (placement.colSpan != null)
762
- opts.colSpan = placement.colSpan;
763
- if (placement.colStart != null)
764
- opts.colStart = placement.colStart;
765
- if (placement.colEnd != null)
766
- opts.colEnd = placement.colEnd;
767
- if (placement.rowSpan != null)
768
- opts.rowSpan = placement.rowSpan;
769
- if (placement.rowStart != null)
770
- opts.rowStart = placement.rowStart;
771
- if (placement.rowEnd != null)
772
- opts.rowEnd = placement.rowEnd;
707
+ // Resolve the best breakpoint (prefer lg, then fallback to others)
708
+ const bp = positions?.lg ?? positions?.xl ?? positions?.xxl ?? positions?.md ?? positions?.sm;
709
+ if (bp) {
710
+ if (bp.colSpan != null)
711
+ this.containerState.options.colSpan = bp.colSpan;
712
+ if (bp.colStart != null)
713
+ this.containerState.options.colStart = bp.colStart;
714
+ if (bp.colEnd != null)
715
+ this.containerState.options.colEnd = bp.colEnd;
716
+ if (bp.rowSpan != null)
717
+ this.containerState.options.rowSpan = bp.rowSpan;
718
+ if (bp.rowStart != null)
719
+ this.containerState.options.rowStart = bp.rowStart;
720
+ if (bp.rowEnd != null)
721
+ this.containerState.options.rowEnd = bp.rowEnd;
773
722
  }
774
723
  }
775
724
  }
@@ -988,7 +937,6 @@ class WidgetContainerMixin extends ChildContainerMixin {
988
937
  'number-editor',
989
938
  'select-editor',
990
939
  'lookup-editor',
991
- 'entity-definition-provider-editor',
992
940
  'selection-list-editor',
993
941
  'date-time-editor',
994
942
  'toggle-editor',
@@ -1044,73 +992,12 @@ class FlexContainerBuilder extends WidgetContainerMixin {
1044
992
  * Grid Container Builder - Liskov Substitution Principle
1045
993
  * Extends WidgetContainerMixin to inherit all common functionality
1046
994
  */
1047
- /**
1048
- * Extracts flat grid-item options from AXPGridLayoutOptions for grid-item-layout widget.
1049
- * Uses first available breakpoint (lg, xl, md, sm).
1050
- */
1051
- /**
1052
- * Deep-merges grid breakpoint buckets so sequential fluent calls (e.g. setColumns then setGap)
1053
- * do not wipe sibling keys under options.grid.default.
1054
- */
1055
- function mergeAXPGridContainerOptions(prev, patch) {
1056
- const next = { ...(prev ?? {}), ...patch };
1057
- if (prev?.grid?.default || patch.grid?.default) {
1058
- next.grid = {
1059
- ...(prev?.grid ?? {}),
1060
- ...(patch.grid ?? {}),
1061
- default: {
1062
- ...(prev?.grid?.default ?? {}),
1063
- ...(patch.grid?.default ?? {}),
1064
- },
1065
- };
1066
- }
1067
- return next;
1068
- }
1069
- function toGridItemOptions(layoutOptions) {
1070
- if (!layoutOptions?.positions)
1071
- return { colSpan: 12 };
1072
- const positions = layoutOptions.positions;
1073
- const placement = positions['lg'] ?? positions['xl'] ?? positions['xxl'] ?? positions['md'] ?? positions['sm'];
1074
- if (!placement)
1075
- return { colSpan: 12 };
1076
- const opts = {};
1077
- if (placement['colSpan'] != null)
1078
- opts['colSpan'] = placement['colSpan'];
1079
- if (placement['colStart'] != null)
1080
- opts['colStart'] = placement['colStart'];
1081
- if (placement['colEnd'] != null)
1082
- opts['colEnd'] = placement['colEnd'];
1083
- if (placement['rowSpan'] != null)
1084
- opts['rowSpan'] = placement['rowSpan'];
1085
- if (placement['rowStart'] != null)
1086
- opts['rowStart'] = placement['rowStart'];
1087
- if (placement['rowEnd'] != null)
1088
- opts['rowEnd'] = placement['rowEnd'];
1089
- if (Object.keys(opts).length === 0)
1090
- opts['colSpan'] = 12;
1091
- return opts;
1092
- }
1093
995
  class GridContainerBuilder extends WidgetContainerMixin {
1094
996
  constructor() {
1095
997
  super('grid-layout');
1096
998
  }
1097
999
  setOptions(options) {
1098
- this.containerState.options = mergeAXPGridContainerOptions(this.containerState.options, options);
1099
- return this;
1100
- }
1101
- item(layoutOptions, delegate) {
1102
- const fieldset = new FieldsetContainerBuilder();
1103
- fieldset.withInheritanceContext(this.inheritanceContext);
1104
- delegate(fieldset);
1105
- const fieldsetNode = fieldset.build();
1106
- const gridItemOptions = toGridItemOptions(layoutOptions);
1107
- const gridItemNode = {
1108
- type: 'grid-item-layout',
1109
- options: gridItemOptions,
1110
- children: [fieldsetNode],
1111
- };
1112
- this.ensureChildren();
1113
- this.containerState.children.push(gridItemNode);
1000
+ this.containerState.options = { ...this.containerState.options, ...options };
1114
1001
  return this;
1115
1002
  }
1116
1003
  // Individual fluent methods for Grid
@@ -1541,7 +1428,7 @@ class ListWidgetBuilder extends WidgetContainerMixin {
1541
1428
  * Uses composition instead of inheritance for cleaner separation
1542
1429
  */
1543
1430
  class DialogContainerBuilder {
1544
- constructor(popupService, hookService) {
1431
+ constructor(popupService) {
1545
1432
  this.dialogState = {
1546
1433
  type: 'flex-layout', // This will be overridden when content layout exists
1547
1434
  children: [],
@@ -1564,7 +1451,6 @@ class DialogContainerBuilder {
1564
1451
  else {
1565
1452
  this.popupService = inject(AXPopupService);
1566
1453
  }
1567
- this.hookService = hookService ?? inject(AXPHookService, { optional: true }) ?? undefined;
1568
1454
  }
1569
1455
  setOptions(options) {
1570
1456
  this.dialogState.dialogOptions = { ...this.dialogState.dialogOptions, ...options };
@@ -1605,12 +1491,7 @@ class DialogContainerBuilder {
1605
1491
  return this;
1606
1492
  }
1607
1493
  onAction(handler) {
1608
- this.dialogState.dialogOptions ??= {
1609
- title: '',
1610
- size: 'md',
1611
- closeButton: false,
1612
- };
1613
- this.dialogState.dialogOptions.onAction = handler;
1494
+ (this.dialogState.dialogOptions ??= {}).onAction = handler;
1614
1495
  return this;
1615
1496
  }
1616
1497
  addCustomAction(action) {
@@ -1659,42 +1540,22 @@ class DialogContainerBuilder {
1659
1540
  const dialogNode = this.build();
1660
1541
  // Import the dialog renderer component dynamically
1661
1542
  const { AXPDialogRendererComponent } = await Promise.resolve().then(function () { return dialogRenderer_component; });
1662
- this.dialogState.dialogOptions ??= {};
1663
- if (this.dialogState.dialogOptions.context == null || typeof this.dialogState.dialogOptions.context !== 'object') {
1664
- this.dialogState.dialogOptions.context = {};
1665
- }
1666
- const initialContext = this.dialogState.dialogOptions.context;
1667
- this.dialogState.actions ??= { footer: { prefix: [], suffix: [] } };
1668
- this.dialogState.actions.footer ??= { prefix: [], suffix: [] };
1669
- this.dialogState.actions.footer.prefix ??= [];
1670
- this.dialogState.actions.footer.suffix ??= [];
1671
- const hookService = this.hookService;
1672
- if (hookService) {
1673
- const beforePayload = {
1674
- context: initialContext,
1675
- dialogOptions: this.dialogState.dialogOptions,
1676
- };
1677
- await hookService.runAsync(AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY, beforePayload);
1678
- }
1543
+ // Collect default values from widget tree and merge into initial context
1544
+ const initialContext = this.dialogState.dialogOptions?.context || {};
1545
+ //TODO remove using collectDefaultValues and use initialContext directly for now:
1546
+ const contextWithDefaults = collectDefaultValues(dialogNode, initialContext);
1679
1547
  // Create dialog configuration
1680
1548
  const dialogConfig = {
1681
1549
  title: this.dialogState.dialogOptions?.title || '',
1682
- //TODO: why we need message?
1683
- //message: this.dialogState.dialogOptions?.message,
1550
+ message: this.dialogState.dialogOptions?.message,
1684
1551
  context: initialContext,
1685
1552
  definition: dialogNode,
1686
- metadata: this.dialogState.dialogOptions.metadata,
1687
1553
  actions: this.dialogState.actions,
1688
1554
  onAction: this.dialogState.dialogOptions?.onAction,
1689
1555
  };
1690
- //
1691
- if (hookService) {
1692
- await hookService.runAsync(AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY, dialogConfig);
1693
- }
1694
1556
  // The Promise resolves when user clicks an action button
1695
1557
  return new Promise(async (resolve) => {
1696
- let flag = false;
1697
- await this.popupService.open(AXPDialogRendererComponent, {
1558
+ this.popupService.open(AXPDialogRendererComponent, {
1698
1559
  title: dialogConfig.title,
1699
1560
  size: this.dialogState.dialogOptions?.size || 'md',
1700
1561
  closeButton: this.dialogState.dialogOptions?.closeButton || false,
@@ -1703,14 +1564,10 @@ class DialogContainerBuilder {
1703
1564
  data: {
1704
1565
  config: dialogConfig,
1705
1566
  callBack: (result) => {
1706
- flag = true;
1707
1567
  resolve(result);
1708
1568
  },
1709
1569
  },
1710
1570
  });
1711
- if (!flag) {
1712
- resolve({ success: false });
1713
- }
1714
1571
  });
1715
1572
  }
1716
1573
  }
@@ -1912,19 +1769,10 @@ class ActionBuilder {
1912
1769
  return this;
1913
1770
  }
1914
1771
  custom(action) {
1915
- const position = action.position ?? 'suffix';
1916
- if (position === 'prefix') {
1917
- if (!this.dialogBuilder['dialogState'].actions.footer.prefix) {
1918
- this.dialogBuilder['dialogState'].actions.footer.prefix = [];
1919
- }
1920
- this.dialogBuilder['dialogState'].actions.footer.prefix.push(action);
1921
- }
1922
- else {
1923
- if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
1924
- this.dialogBuilder['dialogState'].actions.footer.suffix = [];
1925
- }
1926
- this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
1772
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
1773
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
1927
1774
  }
1775
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
1928
1776
  return this;
1929
1777
  }
1930
1778
  }
@@ -2073,27 +1921,22 @@ class AXPLayoutRendererComponent {
2073
1921
  /**
2074
1922
  * Form definition containing groups and fields OR widget tree
2075
1923
  */
2076
- this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
1924
+ this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : []));
2077
1925
  /**
2078
1926
  * Form context/model data
2079
1927
  */
2080
- this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
1928
+ this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
2081
1929
  /**
2082
1930
  * Form appearance and density styling (normal, compact, spacious)
2083
1931
  */
2084
- this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
1932
+ this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : []));
2085
1933
  /**
2086
1934
  * Default form mode. Can be overridden by section/group and field.
2087
1935
  */
2088
- this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
1936
+ this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
2089
1937
  //#endregion
2090
1938
  //#region ---- Widget Tree Conversion ----
2091
- this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
2092
- /**
2093
- * Prefer explicit {@link AXPWidgetNode.mode} on the root node (e.g. dialog flex `mode('view')`)
2094
- * so nested widgets resolve view vs edit correctly; fall back to the layout `mode` input.
2095
- */
2096
- this.effectiveRenderMode = computed(() => this.widgetTree()?.mode ?? this.mode(), ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : /* istanbul ignore next */ []));
1939
+ this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : []));
2097
1940
  /**
2098
1941
  * Convert layout data to widget tree when inputs change
2099
1942
  */
@@ -2118,7 +1961,7 @@ class AXPLayoutRendererComponent {
2118
1961
  if (!isEqual(prev, tree)) {
2119
1962
  this.widgetTree.set(tree);
2120
1963
  }
2121
- }, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : /* istanbul ignore next */ []));
1964
+ }, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : []));
2122
1965
  //#endregion
2123
1966
  //#region ---- Outputs ----
2124
1967
  /**
@@ -2131,12 +1974,12 @@ class AXPLayoutRendererComponent {
2131
1974
  this.validityChange = output();
2132
1975
  //#endregion
2133
1976
  //#region ---- Properties ----
2134
- this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
2135
- this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
1977
+ this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : []));
1978
+ this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : []));
2136
1979
  /**
2137
1980
  * Internal context signal for reactivity
2138
1981
  */
2139
- this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : /* istanbul ignore next */ []));
1982
+ this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
2140
1983
  /**
2141
1984
  * Initial context for reset functionality
2142
1985
  */
@@ -2149,7 +1992,7 @@ class AXPLayoutRendererComponent {
2149
1992
  this.#contextSyncEffect = effect(() => {
2150
1993
  const ctx = this.context() ?? {};
2151
1994
  this.contextUpdateSubject.next(ctx);
2152
- }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : /* istanbul ignore next */ []));
1995
+ }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
2153
1996
  /**
2154
1997
  * Effect to handle widget tree status changes
2155
1998
  */
@@ -2158,7 +2001,7 @@ class AXPLayoutRendererComponent {
2158
2001
  if (widgetTree) {
2159
2002
  this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
2160
2003
  }
2161
- }, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : /* istanbul ignore next */ []));
2004
+ }, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : []));
2162
2005
  }
2163
2006
  //#endregion
2164
2007
  //#region ---- Lifecycle Methods ----
@@ -2298,67 +2141,40 @@ class AXPLayoutRendererComponent {
2298
2141
  isWidgetNode(data) {
2299
2142
  return data && typeof data === 'object' && 'type' in data && typeof data.type === 'string';
2300
2143
  }
2301
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2302
- 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: `
2144
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2145
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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: `
2303
2146
  <ax-form>
2304
2147
  <axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
2305
2148
  @if (widgetTree()) {
2306
- <ng-container
2307
- axp-widget-renderer
2308
- [node]="widgetTree()!"
2309
- [mode]="effectiveRenderMode()"
2310
- ></ng-container>
2149
+ <ng-container axp-widget-renderer [node]="widgetTree()!" [mode]="mode()"></ng-container>
2311
2150
  }
2312
2151
  </axp-widgets-container>
2313
2152
  </ax-form>
2314
- `, 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 }); }
2153
+ `, 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 }); }
2315
2154
  }
2316
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
2155
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
2317
2156
  type: Component,
2318
- args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
2157
+ args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [CommonModule, AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
2319
2158
  <ax-form>
2320
2159
  <axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
2321
2160
  @if (widgetTree()) {
2322
- <ng-container
2323
- axp-widget-renderer
2324
- [node]="widgetTree()!"
2325
- [mode]="effectiveRenderMode()"
2326
- ></ng-container>
2161
+ <ng-container axp-widget-renderer [node]="widgetTree()!" [mode]="mode()"></ng-container>
2327
2162
  }
2328
2163
  </axp-widgets-container>
2329
2164
  </ax-form>
2330
2165
  `, styles: [":host{display:block;width:100%}\n"] }]
2331
2166
  }], 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 }] }] } });
2332
2167
 
2333
- /** Registration key for {@link AXPPreviewWidgetFieldCommand}; lives alone so `LayoutBuilderModule` can reference it without static-importing the command implementation. */
2334
- const AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY = 'Widget:Preview';
2335
-
2336
2168
  class LayoutBuilderModule {
2337
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2338
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
2339
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, providers: [
2340
- AXPLayoutBuilderService,
2341
- provideCommandSetups([
2342
- {
2343
- key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
2344
- command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
2345
- },
2346
- ]),
2347
- ], imports: [CommonModule, AXPLayoutRendererComponent] }); }
2169
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2170
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
2171
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LayoutBuilderModule, providers: [AXPLayoutBuilderService], imports: [CommonModule, AXPLayoutRendererComponent] }); }
2348
2172
  }
2349
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, decorators: [{
2173
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: LayoutBuilderModule, decorators: [{
2350
2174
  type: NgModule,
2351
2175
  args: [{
2352
2176
  imports: [CommonModule, AXPLayoutRendererComponent],
2353
- providers: [
2354
- AXPLayoutBuilderService,
2355
- provideCommandSetups([
2356
- {
2357
- key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
2358
- command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
2359
- },
2360
- ]),
2361
- ],
2177
+ providers: [AXPLayoutBuilderService],
2362
2178
  exports: [AXPLayoutRendererComponent],
2363
2179
  }]
2364
2180
  }] });
@@ -2370,25 +2186,17 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2370
2186
  super(...arguments);
2371
2187
  this.result = new EventEmitter();
2372
2188
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
2373
- this.commandService = inject(AXPCommandService);
2374
- this.hookService = inject(AXPHookService, { optional: true });
2375
- this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
2189
+ this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
2376
2190
  // This will be set by the popup service automatically - same as dynamic-dialog
2377
2191
  this.callBack = () => { };
2378
- this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : /* istanbul ignore next */ []));
2192
+ this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : []));
2379
2193
  // Aggregated actions for footer rendering
2380
- this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
2381
- this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : /* istanbul ignore next */ []));
2382
- /**
2383
- * Correlate layout context snapshots for distributed hooks (`layout-builder.dialog.context-changed`).
2384
- */
2385
- this.contextChangedHooksSessionKey = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
2386
- ? crypto.randomUUID()
2387
- : `layout-dialog-ctx-${Date.now()}-${Math.random().toString(36).slice(2)}`;
2194
+ this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : []));
2195
+ this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : []));
2388
2196
  //#endregion
2389
2197
  //#region ---- View Accessors ----
2390
2198
  // Access the internal layout renderer to reach the widgets container injector
2391
- this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : /* istanbul ignore next */ []));
2199
+ this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : []));
2392
2200
  this.#eff = effect(() => {
2393
2201
  let count = 0;
2394
2202
  this.aggregateAndEvaluateActions();
@@ -2409,48 +2217,22 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2409
2217
  this.aggregateAndEvaluateActions();
2410
2218
  }, 200);
2411
2219
  }
2412
- }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
2220
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : []));
2413
2221
  }
2414
2222
  //#endregion
2415
2223
  //#region ---- Lifecycle ----
2416
2224
  ngOnInit() {
2417
2225
  this.context.set(this.config?.context || {});
2418
- void this.invokeLayoutContextChangedHooks();
2419
2226
  }
2420
2227
  #eff;
2421
2228
  //#endregion
2422
2229
  handleContextChanged(event) {
2423
2230
  this.context.set(event);
2424
2231
  this.aggregateAndEvaluateActions();
2425
- void this.invokeLayoutContextChangedHooks();
2426
2232
  }
2427
2233
  handleContextInitiated(event) {
2428
2234
  this.context.set(event);
2429
2235
  this.aggregateAndEvaluateActions();
2430
- void this.invokeLayoutContextChangedHooks();
2431
- }
2432
- async invokeLayoutContextChangedHooks() {
2433
- const meta = this.config?.metadata;
2434
- if (!this.hookService) {
2435
- return;
2436
- }
2437
- const payload = {
2438
- sessionKey: this.contextChangedHooksSessionKey,
2439
- getContext: () => (this.context() ?? {}),
2440
- metadata: meta,
2441
- patchContext: (partial) => {
2442
- const merged = merge({}, this.context(), partial);
2443
- this.context.set(merged);
2444
- this.layoutRenderer()?.updateContext(merged);
2445
- },
2446
- setLoading: (loading) => this.isDialogLoading.set(loading),
2447
- };
2448
- try {
2449
- await this.hookService.runAsync(AXP_LAYOUT_BUILDER_DIALOG_CONTEXT_CHANGED_HOOK_KEY, payload);
2450
- }
2451
- catch {
2452
- // Hook providers are best-effort; avoid breaking the dialog lifecycle.
2453
- }
2454
2236
  }
2455
2237
  footerPrefixActions() {
2456
2238
  return this.footerPrefix();
@@ -2465,53 +2247,35 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2465
2247
  return this.isDialogLoading();
2466
2248
  }
2467
2249
  async executeAction(action) {
2468
- const cmd = this.resolveActionCommandName(action.command);
2469
- if (this.shouldValidateBeforeAction(cmd)) {
2250
+ const cmd = action.command;
2251
+ if (cmd !== 'cancel') {
2470
2252
  const isValid = await this.layoutRenderer()?.validate();
2471
2253
  if (!isValid?.result) {
2472
2254
  return;
2473
2255
  }
2474
2256
  }
2475
- //TODO: matin, why we need this? maybe we can remove it?
2476
- if (cmd?.startsWith('widget:')) {
2257
+ if (typeof cmd === 'string' && cmd.startsWith('widget:')) {
2477
2258
  const parsed = this.parseWidgetCommand(cmd);
2478
2259
  if (parsed.widgetName && parsed.action) {
2479
- await this.invokeWidget(parsed.widgetName, parsed.action, {});
2260
+ await this.executeWidgetApi(parsed.widgetName, parsed.action);
2480
2261
  await this.aggregateAndEvaluateActions();
2481
2262
  return;
2482
2263
  }
2483
2264
  }
2484
- if (cmd && this.commandService.exists(cmd)) {
2485
- const dialogRef = this.createDialogRef(cmd);
2486
- const integration = (this.config.metadata ?? {});
2487
- try {
2488
- const cmdResult = await this.commandService.execute(cmd, { dialogRef, integration });
2489
- if (!cmdResult?.success) {
2490
- return;
2491
- }
2492
- if (this.shouldKeepDialogOpenAfterCommandResult(cmdResult)) {
2493
- return;
2494
- }
2495
- this.callBack(cmdResult);
2496
- await this.closeWithOptionalSkipValidate(cmdResult);
2497
- }
2498
- catch (error) {
2499
- console.error('Error executing action', cmd, error);
2500
- }
2501
- return;
2502
- }
2503
2265
  const context = this.context();
2504
2266
  const onAction = this.config?.onAction;
2505
2267
  if (onAction) {
2506
- const dialogRef = this.createDialogRef(cmd);
2268
+ const dialogRef = {
2269
+ close: (res) => this.close(res),
2270
+ context: () => this.context(),
2271
+ action: () => cmd ?? undefined,
2272
+ setLoading: (loading) => this.isDialogLoading.set(loading),
2273
+ };
2507
2274
  try {
2508
2275
  this.isDialogLoading.set(true);
2509
2276
  const result = await Promise.resolve(onAction(dialogRef));
2510
- if (this.shouldKeepDialogOpenAfterCommandResult(result)) {
2511
- return;
2512
- }
2513
2277
  this.callBack(result);
2514
- await this.closeWithOptionalSkipValidate(result);
2278
+ this.close(result);
2515
2279
  }
2516
2280
  catch {
2517
2281
  // Handler threw: stay open for retry, actions remain clickable
@@ -2529,74 +2293,15 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2529
2293
  this.data.action = result.action;
2530
2294
  }
2531
2295
  this.callBack({
2532
- ...this.createDialogRef(cmd),
2533
- action: () => result.action,
2534
- });
2535
- // Without `onAction`, only the configured cancel action dismisses the dialog (not submit/custom).
2536
- if (cmd === 'cancel') {
2537
- await this.close(result);
2538
- }
2539
- }
2540
- /** Whether the layout form should be validated before running this footer command. */
2541
- shouldValidateBeforeAction(cmd) {
2542
- if (!cmd || cmd === 'cancel' || cmd === 'entity-form-done') {
2543
- return false;
2544
- }
2545
- if (cmd.startsWith('widget:')) {
2546
- return false;
2547
- }
2548
- if (this.commandService.exists(cmd)) {
2549
- return false;
2550
- }
2551
- return true;
2552
- }
2553
- /** True when a footer handler or command result asks to leave the dialog open (`keepDialogOpen` on the result or `result.data`). */
2554
- shouldKeepDialogOpenAfterCommandResult(result) {
2555
- if (!result || typeof result !== 'object') {
2556
- return false;
2557
- }
2558
- const top = result;
2559
- if (top.keepDialogOpen === true) {
2560
- return true;
2561
- }
2562
- if (top.data != null && typeof top.data === 'object' && 'keepDialogOpen' in top.data) {
2563
- return top.data.keepDialogOpen === true;
2564
- }
2565
- return false;
2566
- }
2567
- createDialogRef(actionCmd) {
2568
- return {
2569
2296
  close: (res) => {
2570
- void this.closeWithOptionalSkipValidate(res);
2297
+ this.close(res);
2571
2298
  },
2572
2299
  context: () => this.context(),
2573
- action: () => actionCmd,
2574
- setLoading: (loading) => this.isDialogLoading.set(loading),
2575
- patchContext: (partial) => {
2576
- const merged = merge({}, this.context(), partial);
2577
- this.context.set(merged);
2578
- this.layoutRenderer()?.updateContext(merged);
2300
+ action: () => result.action,
2301
+ setLoading: (loading) => {
2302
+ this.isDialogLoading.set(loading);
2579
2303
  },
2580
- invokeWidget: (widgetName, method, opts) => this.invokeWidget(widgetName, method, opts ?? {}),
2581
- };
2582
- }
2583
- async closeWithOptionalSkipValidate(result) {
2584
- if (result && typeof result === 'object' && result.skipValidate) {
2585
- this.result.emit(result);
2586
- await super.close(result);
2587
- return;
2588
- }
2589
- await this.close(result);
2590
- }
2591
- /** Resolves footer/widget action command to a string (e.g. `cancel`, `submit`, `widget:...`). */
2592
- resolveActionCommandName(command) {
2593
- if (typeof command === 'string') {
2594
- return command;
2595
- }
2596
- if (command && typeof command === 'object' && 'name' in command) {
2597
- return command.name;
2598
- }
2599
- return undefined;
2304
+ });
2600
2305
  }
2601
2306
  parseWidgetCommand(cmd) {
2602
2307
  // Expected 'widget:<widgetName>.<action>'
@@ -2608,7 +2313,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2608
2313
  return {};
2609
2314
  return { widgetName: rest.slice(0, dot), action: rest.slice(dot + 1) };
2610
2315
  }
2611
- async invokeWidget(widgetName, apiMethod, opts) {
2316
+ async executeWidgetApi(widgetName, apiMethod) {
2612
2317
  if (!this.widgetCoreService)
2613
2318
  return;
2614
2319
  try {
@@ -2618,20 +2323,16 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2618
2323
  if (typeof fn === 'function') {
2619
2324
  await Promise.resolve(fn({
2620
2325
  close: (result) => {
2621
- void this.closeWithOptionalSkipValidate(result);
2326
+ this.close(result);
2622
2327
  },
2623
2328
  context: () => this.context(),
2624
2329
  setLoading: (loading) => {
2625
- (opts.setLoading ?? ((v) => this.isDialogLoading.set(v)))(loading);
2330
+ this.isDialogLoading.set(loading);
2626
2331
  },
2627
2332
  }));
2628
- // Footer predicates (e.g. wizard step) must refresh when the widget advances outside executeAction (e.g. dialogRef.invokeWidget after entity-form continue).
2629
- await this.aggregateAndEvaluateActions();
2630
2333
  }
2631
2334
  }
2632
- catch {
2633
- //
2634
- }
2335
+ catch { }
2635
2336
  }
2636
2337
  async close(result) {
2637
2338
  if (result) {
@@ -2681,7 +2382,6 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2681
2382
  zone: 'footer',
2682
2383
  placement,
2683
2384
  scope: a.scope,
2684
- predicateApiWidgetName: a.predicateApiWidgetName,
2685
2385
  });
2686
2386
  const prefix = (footer?.prefix || []).map((a) => mapOne(a, 'prefix'));
2687
2387
  const suffix = (footer?.suffix || []).map((a) => mapOne(a, 'suffix'));
@@ -2691,18 +2391,16 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2691
2391
  const out = [];
2692
2392
  for (const a of actions) {
2693
2393
  const parsed = typeof a.command === 'string' ? this.parseWidgetCommand(a.command) : {};
2694
- const widgetNameForApi = parsed.widgetName ?? a.predicateApiWidgetName;
2695
- const api = widgetNameForApi ? await this.resolveApi(widgetNameForApi) : undefined;
2394
+ const api = parsed.widgetName ? await this.resolveApi(parsed.widgetName) : undefined;
2696
2395
  const scope = {
2697
2396
  api,
2698
- widget: { name: widgetNameForApi },
2397
+ widget: { name: parsed.widgetName },
2699
2398
  dialog: { context: this.context() },
2700
2399
  context: this.context(),
2701
2400
  };
2702
2401
  const disabled = await this.evalBool(a.disabled, scope);
2703
2402
  const hidden = await this.evalBool(a.hidden, scope);
2704
- const resolvedTitle = (await this.evalActionTitle(a.title, scope)) ?? a.title;
2705
- out.push({ ...a, disabled, hidden, title: resolvedTitle });
2403
+ out.push({ ...a, disabled, hidden });
2706
2404
  }
2707
2405
  return out;
2708
2406
  }
@@ -2720,25 +2418,6 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2720
2418
  }
2721
2419
  return value;
2722
2420
  }
2723
- /** Resolves footer action title when it contains {{ ... }} (e.g. wizard labels from dialog context). */
2724
- async evalActionTitle(value, scope) {
2725
- if (value == null || typeof value !== 'string' || !value.includes('{{')) {
2726
- return value;
2727
- }
2728
- try {
2729
- const result = await this.expressionEvaluator.evaluate(value, scope);
2730
- if (typeof result === 'string' && result.length > 0) {
2731
- return result;
2732
- }
2733
- if (result != null && result !== false) {
2734
- return String(result);
2735
- }
2736
- }
2737
- catch {
2738
- //
2739
- }
2740
- return value;
2741
- }
2742
2421
  async resolveApi(widgetName) {
2743
2422
  try {
2744
2423
  await this.widgetCoreService?.waitForWidget(widgetName, 2000);
@@ -2749,13 +2428,10 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2749
2428
  return undefined;
2750
2429
  }
2751
2430
  }
2752
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2753
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPDialogRendererComponent, isStandalone: true, selector: "axp-dialog-renderer", outputs: { result: "result" }, providers: [AXPContextStore], viewQueries: [{ propertyName: "layoutRenderer", first: true, predicate: AXPLayoutRendererComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2431
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2432
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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: `
2754
2433
  <axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
2755
2434
  <div class="ax-p-4">
2756
- <!-- @if (config.message) {
2757
- <p class="ax-mb-4 ax-leading-relaxed">{{ config.message | translate | async }}</p>
2758
- } -->
2759
2435
  <axp-layout-renderer
2760
2436
  [layout]="config.definition"
2761
2437
  [context]="context()"
@@ -2779,13 +2455,8 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2779
2455
  [color]="action.color"
2780
2456
  (onClick)="executeAction(action)"
2781
2457
  >
2782
- @if (isFormLoading()) {
2783
- <ax-loading></ax-loading>
2784
- }
2785
2458
  <ax-prefix>
2786
- @if (action.icon) {
2787
- <ax-icon [icon]="action.icon"></ax-icon>
2788
- }
2459
+ <i class="{{ action.icon }}"></i>
2789
2460
  </ax-prefix>
2790
2461
  </ax-button>
2791
2462
  }
@@ -2804,7 +2475,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2804
2475
  }
2805
2476
  @if (action.icon) {
2806
2477
  <ax-prefix>
2807
- <ax-icon [icon]="action.icon"></ax-icon>
2478
+ <ax-icon icon="{{ action.icon }}"></ax-icon>
2808
2479
  </ax-prefix>
2809
2480
  }
2810
2481
  </ax-button>
@@ -2813,9 +2484,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2813
2484
  </ax-suffix>
2814
2485
  </ax-footer>
2815
2486
  }
2816
- `, 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 }); }
2487
+ `, 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" }] }); }
2817
2488
  }
2818
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
2489
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
2819
2490
  type: Component,
2820
2491
  args: [{
2821
2492
  selector: 'axp-dialog-renderer',
@@ -2829,14 +2500,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2829
2500
  AXTranslationModule,
2830
2501
  AXPComponentSlotModule,
2831
2502
  ],
2832
- providers: [AXPContextStore],
2833
- changeDetection: ChangeDetectionStrategy.OnPush,
2834
2503
  template: `
2835
2504
  <axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
2836
2505
  <div class="ax-p-4">
2837
- <!-- @if (config.message) {
2838
- <p class="ax-mb-4 ax-leading-relaxed">{{ config.message | translate | async }}</p>
2839
- } -->
2840
2506
  <axp-layout-renderer
2841
2507
  [layout]="config.definition"
2842
2508
  [context]="context()"
@@ -2860,13 +2526,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2860
2526
  [color]="action.color"
2861
2527
  (onClick)="executeAction(action)"
2862
2528
  >
2863
- @if (isFormLoading()) {
2864
- <ax-loading></ax-loading>
2865
- }
2866
2529
  <ax-prefix>
2867
- @if (action.icon) {
2868
- <ax-icon [icon]="action.icon"></ax-icon>
2869
- }
2530
+ <i class="{{ action.icon }}"></i>
2870
2531
  </ax-prefix>
2871
2532
  </ax-button>
2872
2533
  }
@@ -2885,7 +2546,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2885
2546
  }
2886
2547
  @if (action.icon) {
2887
2548
  <ax-prefix>
2888
- <ax-icon [icon]="action.icon"></ax-icon>
2549
+ <ax-icon icon="{{ action.icon }}"></ax-icon>
2889
2550
  </ax-prefix>
2890
2551
  }
2891
2552
  </ax-button>
@@ -2905,190 +2566,9 @@ var dialogRenderer_component = /*#__PURE__*/Object.freeze({
2905
2566
  AXPDialogRendererComponent: AXPDialogRendererComponent
2906
2567
  });
2907
2568
 
2908
- //#region ---- Imports ----
2909
- /**
2910
- * `customWidget` only forwards keys from its options bag into the built node via `addSingleWidget`.
2911
- * Designer / configurator persist `defaultValue` (and other extended fields) on the widget node root;
2912
- * spreading `options` alone drops them, so preview never applied defaults.
2913
- */
2914
- /**
2915
- * Widget options are sometimes persisted with an extra nesting (`options.options`) when context
2916
- * was merged incorrectly. Flatten so list/data-source resolution sees `dataSource` at the top level.
2917
- */
2918
- function optionsBagForPreview(node) {
2919
- const raw = (node.options ?? {});
2920
- const inner = raw['options'];
2921
- if (inner !== undefined && typeof inner === 'object' && !Array.isArray(inner)) {
2922
- const { options: _nested, ...rest } = raw;
2923
- return { ...rest, ...inner };
2924
- }
2925
- return { ...raw };
2926
- }
2927
- function extendedNodePropsForPreview(node) {
2928
- const out = {};
2929
- if (node.defaultValue !== undefined) {
2930
- out['defaultValue'] = node.defaultValue;
2931
- }
2932
- if (node.triggers !== undefined) {
2933
- out['triggers'] = node.triggers;
2934
- }
2935
- if (node.meta !== undefined) {
2936
- out['meta'] = node.meta;
2937
- }
2938
- if (node.valueTransforms !== undefined) {
2939
- out['valueTransforms'] = node.valueTransforms;
2940
- }
2941
- if (node.visible !== undefined) {
2942
- out['visible'] = node.visible;
2943
- }
2944
- if (node.mode !== undefined) {
2945
- out['mode'] = node.mode;
2946
- }
2947
- if (node.children !== undefined) {
2948
- out['children'] = node.children;
2949
- }
2950
- return out;
2951
- }
2952
- //#endregion
2953
- //#region ---- Command ----
2954
- /**
2955
- * Opens a dialog that previews a widget configuration (same behavior as the preview button on
2956
- * `axp-widget-field-configurator`). Invoked from that component and from entity list actions.
2957
- */
2958
- class AXPPreviewWidgetFieldCommand {
2959
- constructor() {
2960
- this.formBuilderService = inject(AXPLayoutBuilderService);
2961
- this.widgetRegistry = inject(AXPWidgetRegistryService);
2962
- this.translationService = inject(AXTranslationService);
2963
- this.crudService = inject(AXP_ENTITY_DEFINITION_CRUD_SERVICE, { optional: true });
2964
- }
2965
- async execute(input) {
2966
- try {
2967
- const merged = this.mergeInvocation(input);
2968
- const currentWidget = this.normalizeWidget(merged['widget'] ?? merged['interface']);
2969
- if (!currentWidget?.type) {
2970
- return {
2971
- success: false,
2972
- message: {
2973
- text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data',
2974
- },
2975
- };
2976
- }
2977
- const fieldName = String(merged['fieldName'] ?? merged['name'] ?? 'Field');
2978
- const rawTitle = (merged['fieldTitle'] ?? merged['title']);
2979
- const fieldTitleLabel = this.resolveFieldTitleLabel(rawTitle, fieldName);
2980
- const dialogTitle = (await this.resolveWidgetDisplayTitle(currentWidget.type)) || currentWidget.type || fieldTitleLabel;
2981
- const previewWidgetOptions = {
2982
- ...optionsBagForPreview(currentWidget),
2983
- name: fieldName,
2984
- ...extendedNodePropsForPreview(currentWidget),
2985
- };
2986
- const dialogOutcome = await this.formBuilderService
2987
- .create()
2988
- .dialog((dialog) => {
2989
- dialog
2990
- .setTitle(dialogTitle)
2991
- .setSize('md')
2992
- .setCloseButton(true)
2993
- .setContext({})
2994
- .content((layoutBuilder) => {
2995
- layoutBuilder.formField(fieldTitleLabel, (formField) => {
2996
- formField.customWidget(currentWidget.type, previewWidgetOptions);
2997
- });
2998
- })
2999
- .setActions((actions) => actions.cancel('@general:actions.close.title'));
3000
- })
3001
- .show();
3002
- const cancelled = this.isCancelDialogOutcome(dialogOutcome);
3003
- return {
3004
- success: !cancelled,
3005
- message: { text: '' },
3006
- };
3007
- }
3008
- catch (error) {
3009
- const message = error instanceof Error ? error.message : 'Unknown error';
3010
- return {
3011
- success: false,
3012
- message: { text: message },
3013
- };
3014
- }
3015
- }
3016
- mergeInvocation(input) {
3017
- const contextOptions = input.__context__?.options;
3018
- const ctxData = input.__context__?.data;
3019
- const { __context__: _ctx, ...rest } = input;
3020
- return {
3021
- ...(ctxData ?? {}),
3022
- ...(contextOptions ?? {}),
3023
- ...rest,
3024
- };
3025
- }
3026
- normalizeWidget(raw) {
3027
- if (raw == null)
3028
- return null;
3029
- if (typeof raw === 'string') {
3030
- const t = raw.trim();
3031
- return t ? { type: t, options: {} } : null;
3032
- }
3033
- if (typeof raw === 'object' && !Array.isArray(raw) && 'type' in raw) {
3034
- const w = raw;
3035
- return w.type ? cloneDeep(w) : null;
3036
- }
3037
- return null;
3038
- }
3039
- resolveFieldTitleLabel(raw, fallback) {
3040
- let source = fallback;
3041
- if (raw !== undefined && raw !== null) {
3042
- if (typeof raw === 'string') {
3043
- if (raw.trim() !== '') {
3044
- source = raw;
3045
- }
3046
- }
3047
- else if (typeof raw === 'object' && !Array.isArray(raw) && Object.keys(raw).length > 0) {
3048
- source = raw;
3049
- }
3050
- }
3051
- return this.translationService.resolve(source);
3052
- }
3053
- isCancelDialogOutcome(outcome) {
3054
- if (outcome == null) {
3055
- return false;
3056
- }
3057
- const ref = outcome;
3058
- if (typeof ref.action !== 'function') {
3059
- return false;
3060
- }
3061
- return ref.action() === 'cancel';
3062
- }
3063
- async resolveWidgetDisplayTitle(widgetType) {
3064
- const crud = this.crudService;
3065
- if (crud) {
3066
- const interfaces = await crud.listInterfaces();
3067
- const iface = interfaces.find((d) => d.name === widgetType);
3068
- return iface?.title ?? iface?.name;
3069
- }
3070
- const config = this.widgetRegistry.getOptional(widgetType);
3071
- if (!config) {
3072
- return undefined;
3073
- }
3074
- const resolved = this.translationService.resolve(config.title);
3075
- return resolved || undefined;
3076
- }
3077
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3078
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand }); }
3079
- }
3080
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
3081
- type: Injectable
3082
- }] });
3083
-
3084
- var previewWidgetField_command = /*#__PURE__*/Object.freeze({
3085
- __proto__: null,
3086
- AXPPreviewWidgetFieldCommand: AXPPreviewWidgetFieldCommand
3087
- });
3088
-
3089
2569
  /**
3090
2570
  * Generated bundle index. Do not edit.
3091
2571
  */
3092
2572
 
3093
- export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, AXPPreviewWidgetFieldCommand, AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY, AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY, AXP_LAYOUT_BUILDER_DIALOG_CONTEXT_CHANGED_HOOK_KEY, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY, LayoutBuilderModule };
2573
+ export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, LayoutBuilderModule };
3094
2574
  //# sourceMappingURL=acorex-platform-layout-builder.mjs.map