@acorex/platform 20.3.0-next.19 → 20.3.0-next.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import * as i1 from '@acorex/platform/layout/widget-core';
7
7
  import { AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
8
8
  import * as i2 from '@acorex/components/form';
9
9
  import { AXFormComponent, AXFormModule } from '@acorex/components/form';
10
- import { isEqual, get } from 'lodash-es';
10
+ import { isEqual, get, cloneDeep } from 'lodash-es';
11
11
  import { AXPExpressionEvaluatorService } from '@acorex/platform/core';
12
12
  import { Subject, debounceTime, distinctUntilChanged, startWith } from 'rxjs';
13
13
  import * as i2$1 from '@acorex/components/button';
@@ -232,8 +232,11 @@ class BaseContainerBuilder {
232
232
  }
233
233
  // Remove name and path from options
234
234
  const { name: _, path: __, ...cleanOptions } = widgetOptions;
235
- child.options(cleanOptions);
235
+ // IMPORTANT: Apply inheritance context BEFORE setting options
236
+ // This ensures that inherited properties (readonly, disabled, etc.) are applied first
237
+ // Then user-provided options will override them if explicitly set
236
238
  child.withInheritanceContext(this.inheritanceContext);
239
+ child.options(cleanOptions);
237
240
  this.ensureChildren();
238
241
  this.containerState.children.push(child.build());
239
242
  return this;
@@ -712,10 +715,11 @@ class FormFieldBuilder extends LayoutContainerMixin {
712
715
  child.path(widgetPath);
713
716
  // Remove name from options since it's now in state
714
717
  const { name: _, ...cleanOptions } = (options || {});
715
- child.options(cleanOptions);
716
718
  child.withInheritanceContext(this.inheritanceContext);
717
- this.ensureChildren();
718
- this.containerState.children.push(child.build());
719
+ child.options(cleanOptions);
720
+ // IMPORTANT: Store the widget builder, don't build it yet!
721
+ // This allows properties set after this method (like disabled, readonly) to be applied
722
+ this.childWidget = child;
719
723
  this.hasWidget = true;
720
724
  return this;
721
725
  }
@@ -755,6 +759,62 @@ class FormFieldBuilder extends LayoutContainerMixin {
755
759
  customWidget(type, options) {
756
760
  return this.addSingleWidget(type, options);
757
761
  }
762
+ // Override property setters to propagate changes to child widget
763
+ disabled(condition) {
764
+ super.disabled(condition);
765
+ if (this.childWidget) {
766
+ this.childWidget.withInheritanceContext(this.inheritanceContext);
767
+ }
768
+ return this;
769
+ }
770
+ readonly(condition) {
771
+ super.readonly(condition);
772
+ if (this.childWidget) {
773
+ this.childWidget.withInheritanceContext(this.inheritanceContext);
774
+ }
775
+ return this;
776
+ }
777
+ visible(condition) {
778
+ super.visible(condition);
779
+ if (this.childWidget) {
780
+ this.childWidget.withInheritanceContext(this.inheritanceContext);
781
+ }
782
+ return this;
783
+ }
784
+ direction(direction) {
785
+ super.direction(direction);
786
+ if (this.childWidget) {
787
+ this.childWidget.withInheritanceContext(this.inheritanceContext);
788
+ }
789
+ return this;
790
+ }
791
+ mode(mode) {
792
+ super.mode(mode);
793
+ if (this.childWidget) {
794
+ this.childWidget.withInheritanceContext(this.inheritanceContext);
795
+ }
796
+ return this;
797
+ }
798
+ // Override withInheritanceContext to pass it to the child widget if it exists
799
+ withInheritanceContext(context) {
800
+ // Call parent implementation first
801
+ super.withInheritanceContext(context);
802
+ // If we have a child widget, update its inheritance context too
803
+ if (this.childWidget) {
804
+ this.childWidget.withInheritanceContext(this.inheritanceContext);
805
+ }
806
+ return this;
807
+ }
808
+ // Override build() to build the child widget at the last moment
809
+ build() {
810
+ // Build the child widget and add it to children before building the form field
811
+ if (this.childWidget) {
812
+ this.ensureChildren();
813
+ this.containerState.children.push(this.childWidget.build());
814
+ }
815
+ // Call parent build
816
+ return super.build();
817
+ }
758
818
  }
759
819
  /**
760
820
  * Fieldset Container Builder - Liskov Substitution Principle
@@ -1039,7 +1099,8 @@ class WidgetBuilder {
1039
1099
  return this;
1040
1100
  }
1041
1101
  options(options) {
1042
- this.widgetState.options = options;
1102
+ // Merge options instead of replacing to preserve inherited properties
1103
+ this.widgetState.options = { ...this.widgetState.options, ...options };
1043
1104
  return this;
1044
1105
  }
1045
1106
  layout(value) {
@@ -1101,21 +1162,23 @@ class WidgetBuilder {
1101
1162
  this.inheritanceContext = mergeInheritanceContext(context);
1102
1163
  // Apply inherited properties to widget state
1103
1164
  const resolved = resolveInheritedProperties(context, this.inheritanceContext);
1104
- if (resolved.mode && !this.widgetState.mode) {
1165
+ // Always apply inherited properties (remove the conditions that check if already set)
1166
+ // This allows properties to be updated when inheritance context changes
1167
+ if (resolved.mode) {
1105
1168
  this.widgetState.mode = resolved.mode;
1106
1169
  }
1107
1170
  if (!this.widgetState.options)
1108
1171
  this.widgetState.options = {};
1109
- if (resolved.disabled !== undefined && !this.widgetState.options['disabled']) {
1172
+ if (resolved.disabled !== undefined) {
1110
1173
  this.widgetState.options['disabled'] = resolved.disabled;
1111
1174
  }
1112
- if (resolved.readonly !== undefined && !this.widgetState.options['readonly']) {
1175
+ if (resolved.readonly !== undefined) {
1113
1176
  this.widgetState.options['readonly'] = resolved.readonly;
1114
1177
  }
1115
- if (resolved.direction !== undefined && !this.widgetState.options['direction']) {
1178
+ if (resolved.direction !== undefined) {
1116
1179
  this.widgetState.options['direction'] = resolved.direction;
1117
1180
  }
1118
- if (resolved.visible !== undefined && !this.widgetState.options['visible']) {
1181
+ if (resolved.visible !== undefined) {
1119
1182
  this.widgetState.options['visible'] = resolved.visible;
1120
1183
  }
1121
1184
  return this;
@@ -1527,6 +1590,10 @@ class AXPLayoutRendererComponent {
1527
1590
  * Internal context signal for reactivity
1528
1591
  */
1529
1592
  this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
1593
+ /**
1594
+ * Initial context for reset functionality
1595
+ */
1596
+ this.initialContext = {};
1530
1597
  //#endregion
1531
1598
  //#region ---- Effects ----
1532
1599
  /**
@@ -1576,7 +1643,10 @@ class AXPLayoutRendererComponent {
1576
1643
  //#region ---- Lifecycle Methods ----
1577
1644
  ngOnInit() {
1578
1645
  // Initialize internal context with input context
1579
- this.internalContext.set(this.context() ?? {});
1646
+ const ctx = this.context() ?? {};
1647
+ this.internalContext.set(ctx);
1648
+ // Store initial context for reset functionality
1649
+ this.initialContext = cloneDeep(ctx);
1580
1650
  // Setup RxJS streams for context management
1581
1651
  this.setupContextStreams();
1582
1652
  }
@@ -1651,6 +1721,25 @@ class AXPLayoutRendererComponent {
1651
1721
  rules: [],
1652
1722
  };
1653
1723
  }
1724
+ /**
1725
+ * Clear the form context
1726
+ */
1727
+ clear() {
1728
+ // Clear internal context
1729
+ this.internalContext.set({});
1730
+ // Update the model signal
1731
+ this.context.set({});
1732
+ }
1733
+ /**
1734
+ * Reset the form to its initial state
1735
+ */
1736
+ reset() {
1737
+ // Reset to initial context
1738
+ const resetContext = cloneDeep(this.initialContext);
1739
+ this.internalContext.set(resetContext);
1740
+ // Update the model signal
1741
+ this.context.set(resetContext);
1742
+ }
1654
1743
  //#endregion
1655
1744
  //#region ---- RxJS Stream Setup ----
1656
1745
  /**