@acorex/platform 21.0.0-next.70 → 21.0.0-next.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-common.mjs +11 -0
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +332 -76
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +563 -44
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +83 -67
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +543 -237
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +319 -66
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +54 -6
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +198 -91
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +13 -14
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-shared.mjs +50 -30
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-common.d.ts +11 -0
- package/types/acorex-platform-core.d.ts +137 -47
- package/types/acorex-platform-layout-builder.d.ts +90 -13
- package/types/acorex-platform-layout-components.d.ts +21 -17
- package/types/acorex-platform-layout-entity.d.ts +63 -10
- package/types/acorex-platform-layout-views.d.ts +68 -6
- package/types/acorex-platform-layout-widget-core.d.ts +43 -8
- package/types/acorex-platform-layout-widgets.d.ts +21 -6
- package/types/acorex-platform-themes-default.d.ts +24 -4
- package/types/acorex-platform-themes-shared.d.ts +6 -0
- package/types/acorex-platform-workflow.d.ts +1 -1
|
@@ -65,6 +65,9 @@ class AXPWidgetCoreService {
|
|
|
65
65
|
return [AXPPageStatus.Processing, AXPPageStatus.Submitting, AXPPageStatus.Rendering].includes(this.status());
|
|
66
66
|
}, ...(ngDevMode ? [{ debugName: "isBusy" }] : /* istanbul ignore next */ []));
|
|
67
67
|
this.registeredWidgetsCount = signal(0, ...(ngDevMode ? [{ debugName: "registeredWidgetsCount" }] : /* istanbul ignore next */ []));
|
|
68
|
+
/** Bumped when a widget reports dirty-state changes via `api().isDirty()`. */
|
|
69
|
+
this.dirtyWidgetsRevision = signal(0, ...(ngDevMode ? [{ debugName: "dirtyWidgetsRevision" }] : /* istanbul ignore next */ []));
|
|
70
|
+
this.dirtyWidgetsRevisionSignal = this.dirtyWidgetsRevision.asReadonly();
|
|
68
71
|
}
|
|
69
72
|
get variables() {
|
|
70
73
|
return this.variables$();
|
|
@@ -168,6 +171,22 @@ class AXPWidgetCoreService {
|
|
|
168
171
|
listRegisteredWidgetNames() {
|
|
169
172
|
return Array.from(this.widgets.keys());
|
|
170
173
|
}
|
|
174
|
+
/** Notifies listeners that a widget's composite dirty state may have changed. */
|
|
175
|
+
notifyWidgetDirtyChanged() {
|
|
176
|
+
this.dirtyWidgetsRevision.update((value) => value + 1);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Returns whether any registered widget reports dirty state via `api().isDirty()`.
|
|
180
|
+
*/
|
|
181
|
+
hasDirtyWidgets() {
|
|
182
|
+
for (const widget of this.widgets.values()) {
|
|
183
|
+
const isDirty = widget.api()?.['isDirty'];
|
|
184
|
+
if (typeof isDirty === 'function' && isDirty()) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
171
190
|
ngOnDestroy() { }
|
|
172
191
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWidgetCoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
173
192
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWidgetCoreService }); }
|
|
@@ -484,7 +503,7 @@ class AXPValueWidgetComponent extends AXPLayoutBaseWidgetComponent {
|
|
|
484
503
|
this.detectFullPath();
|
|
485
504
|
// Set defaultValue if it exists and the path doesn't exist in context
|
|
486
505
|
if (!isNil(this.defaultValue) && this.fullPath() && !this.contextService.hasValue(this.fullPath())) {
|
|
487
|
-
this.setValue(this.defaultValue);
|
|
506
|
+
this.setValue(this.defaultValue, { origin: 'system' });
|
|
488
507
|
}
|
|
489
508
|
}
|
|
490
509
|
//
|
|
@@ -497,7 +516,7 @@ class AXPValueWidgetComponent extends AXPLayoutBaseWidgetComponent {
|
|
|
497
516
|
}
|
|
498
517
|
return rawValue;
|
|
499
518
|
}
|
|
500
|
-
setValue(value) {
|
|
519
|
+
setValue(value, options) {
|
|
501
520
|
if (this.node.valueTransforms?.setter) {
|
|
502
521
|
value = this.node.valueTransforms?.setter(value);
|
|
503
522
|
}
|
|
@@ -515,10 +534,14 @@ class AXPValueWidgetComponent extends AXPLayoutBaseWidgetComponent {
|
|
|
515
534
|
return;
|
|
516
535
|
}
|
|
517
536
|
if (this.fullPath()) {
|
|
518
|
-
this.contextService.update(this.fullPath(), value);
|
|
537
|
+
this.contextService.update(this.fullPath(), value, { origin: options?.origin ?? 'user' });
|
|
519
538
|
this.onValueChanged.next({ sender: this });
|
|
520
539
|
}
|
|
521
540
|
}
|
|
541
|
+
/** Persists a user-initiated value change into the shared context store. */
|
|
542
|
+
setUserValue(value) {
|
|
543
|
+
this.setValue(value, { origin: 'user' });
|
|
544
|
+
}
|
|
522
545
|
detectFullPath() {
|
|
523
546
|
const sections = [];
|
|
524
547
|
const ids = [];
|
|
@@ -555,7 +578,7 @@ class AXPValueWidgetComponent extends AXPLayoutBaseWidgetComponent {
|
|
|
555
578
|
}
|
|
556
579
|
handleValueChanged(e) {
|
|
557
580
|
if (e.isUserInteraction) {
|
|
558
|
-
this.
|
|
581
|
+
this.setUserValue(e.value);
|
|
559
582
|
}
|
|
560
583
|
}
|
|
561
584
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPValueWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
@@ -1651,6 +1674,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1651
1674
|
|
|
1652
1675
|
class AXPWidgetContainerComponent {
|
|
1653
1676
|
set context(value) {
|
|
1677
|
+
// Parent re-binds the same context after widget-driven updates; avoid reset() clearing dirty paths.
|
|
1678
|
+
if (isEqual(this.contextService.data(), value)) {
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1654
1681
|
this.contextService.set(value);
|
|
1655
1682
|
}
|
|
1656
1683
|
set functions(v) {
|
|
@@ -1660,6 +1687,11 @@ class AXPWidgetContainerComponent {
|
|
|
1660
1687
|
this.contextService = inject(AXPContextStore);
|
|
1661
1688
|
this.builderService = inject(AXPWidgetCoreService);
|
|
1662
1689
|
this.onContextChanged = new EventEmitter();
|
|
1690
|
+
/** True when user-edited context paths or composite widgets report dirty state. */
|
|
1691
|
+
this.isFormDirty = computed(() => {
|
|
1692
|
+
this.builderService.dirtyWidgetsRevisionSignal();
|
|
1693
|
+
return this.contextService.isUserDirty() || this.builderService.hasDirtyWidgets();
|
|
1694
|
+
}, ...(ngDevMode ? [{ debugName: "isFormDirty" }] : /* istanbul ignore next */ []));
|
|
1663
1695
|
this.status = computed(() => {
|
|
1664
1696
|
return this.builderService.status();
|
|
1665
1697
|
}, ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
@@ -1668,7 +1700,11 @@ class AXPWidgetContainerComponent {
|
|
|
1668
1700
|
}, ...(ngDevMode ? [{ debugName: "isBusy" }] : /* istanbul ignore next */ []));
|
|
1669
1701
|
effect(() => {
|
|
1670
1702
|
if (this.contextService.isChanged()) {
|
|
1671
|
-
this.
|
|
1703
|
+
const changeEvent = this.contextService.changeEvent();
|
|
1704
|
+
this.onContextChanged.emit({
|
|
1705
|
+
...changeEvent,
|
|
1706
|
+
isFormDirty: this.isFormDirty(),
|
|
1707
|
+
});
|
|
1672
1708
|
}
|
|
1673
1709
|
});
|
|
1674
1710
|
}
|
|
@@ -1678,6 +1714,18 @@ class AXPWidgetContainerComponent {
|
|
|
1678
1714
|
find(name) {
|
|
1679
1715
|
return this.builderService.waitForWidget(name);
|
|
1680
1716
|
}
|
|
1717
|
+
/** Replaces context and clears dirty tracking (discard, save reload, external reset). */
|
|
1718
|
+
replaceContext(value) {
|
|
1719
|
+
const next = cloneDeep(value);
|
|
1720
|
+
this.contextService.clearUserDirtyPaths();
|
|
1721
|
+
// After save the parent often re-binds deeply-equal data; still reset the clean baseline.
|
|
1722
|
+
if (isEqual(this.contextService.data(), next)) {
|
|
1723
|
+
this.contextService.commitBaseline();
|
|
1724
|
+
this.builderService.notifyWidgetDirtyChanged();
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
this.contextService.set(next);
|
|
1728
|
+
}
|
|
1681
1729
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWidgetContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1682
1730
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AXPWidgetContainerComponent, isStandalone: false, selector: "axp-widgets-container", inputs: { context: "context", functions: "functions" }, outputs: { onContextChanged: "onContextChanged" }, host: { styleAttribute: "display: contents;" }, providers: [AXPWidgetCoreService, AXPContextStore], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1683
1731
|
}
|
|
@@ -2511,7 +2559,7 @@ class AXPWidgetRendererDirective {
|
|
|
2511
2559
|
return this.contextService.data();
|
|
2512
2560
|
},
|
|
2513
2561
|
isDirty: () => {
|
|
2514
|
-
return this.contextService.
|
|
2562
|
+
return this.contextService.isUserDirty() || this.builderService.hasDirtyWidgets();
|
|
2515
2563
|
},
|
|
2516
2564
|
/**
|
|
2517
2565
|
* Host/widget-under-edit `options` from the shared context store (same values as
|