@acorex/platform 21.0.0-next.70 → 21.0.0-next.72
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-auth.mjs +10 -2
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-Bi1RYif5.mjs → acorex-platform-common-common-settings.provider-Ytey9uhY.mjs} +15 -1
- package/fesm2022/acorex-platform-common-common-settings.provider-Ytey9uhY.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +3798 -1674
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +1362 -97
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +446 -44
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +149 -109
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +199 -126
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-entity-attachments-page.component-D8iQnT-R.mjs → acorex-platform-layout-entity-attachments-page.component-B0EkdqvH.mjs} +6 -1
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-B0EkdqvH.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-entity.mjs +823 -594
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +845 -218
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +122 -33
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-BcpRkpJp.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-BcpRkpJp.mjs.map → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DjpZU6gz.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-DQtK4lxl.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-DQtK4lxl.mjs.map → acorex-platform-layout-widgets-tabular-data-view-popup.component-gX-3Kx9I.mjs.map} +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +312 -676
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-error-401.component-B1nsdpTY.mjs +48 -0
- package/fesm2022/acorex-platform-themes-default-error-401.component-B1nsdpTY.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-error-404.component-D4UvRe8u.mjs +42 -0
- package/fesm2022/acorex-platform-themes-default-error-404.component-D4UvRe8u.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +89 -46
- 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-auth.d.ts +2 -0
- package/types/acorex-platform-common.d.ts +899 -256
- package/types/acorex-platform-core.d.ts +394 -60
- package/types/acorex-platform-layout-builder.d.ts +78 -13
- package/types/acorex-platform-layout-components.d.ts +30 -24
- package/types/acorex-platform-layout-entity.d.ts +93 -44
- package/types/acorex-platform-layout-views.d.ts +162 -42
- package/types/acorex-platform-layout-widget-core.d.ts +60 -33
- package/types/acorex-platform-layout-widgets.d.ts +48 -20
- package/types/acorex-platform-themes-default.d.ts +38 -8
- package/types/acorex-platform-themes-shared.d.ts +6 -0
- package/types/acorex-platform-workflow.d.ts +1 -1
- package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-D8iQnT-R.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs +0 -31
- package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs +0 -25
- package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { signal, computed, Injectable, InjectionToken, inject, ElementRef, effect, untracked, EventEmitter, Injector, ChangeDetectorRef, ViewChild, Input, Output, ChangeDetectionStrategy, Component, input, output, ViewContainerRef, Directive, NgModule } from '@angular/core';
|
|
3
3
|
import { convertArrayToDataSource, AXDataSource, AX_STYLE_COLOR_TYPES, AX_STYLE_LOOK_TYPES } from '@acorex/cdk/common';
|
|
4
|
-
import { AXPContextStore, AXPDataSourceDefinitionProviderService, extractValue, AXPExpressionEvaluatorService, getSmart } from '@acorex/platform/core';
|
|
4
|
+
import { AXPContextStore, isSelectionValueEqual, isFormValueEqual, AXPDataSourceDefinitionProviderService, extractValue, AXPExpressionEvaluatorService, getSmart } from '@acorex/platform/core';
|
|
5
5
|
export { normalizeDefinitionCategories } from '@acorex/platform/core';
|
|
6
6
|
import { set, merge, cloneDeep, isNil, get, isEqual, isUndefined, isObjectLike, sum, isEmpty, isString } from 'lodash-es';
|
|
7
7
|
import { Subject, BehaviorSubject, filter } from 'rxjs';
|
|
@@ -65,6 +65,8 @@ 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
|
+
this.dirtyWidgetsRevision = signal(0, ...(ngDevMode ? [{ debugName: "dirtyWidgetsRevision" }] : /* istanbul ignore next */ []));
|
|
69
|
+
this.dirtyWidgetsRevisionSignal = this.dirtyWidgetsRevision.asReadonly();
|
|
68
70
|
}
|
|
69
71
|
get variables() {
|
|
70
72
|
return this.variables$();
|
|
@@ -78,22 +80,19 @@ class AXPWidgetCoreService {
|
|
|
78
80
|
}
|
|
79
81
|
detectStatus() {
|
|
80
82
|
const statuses = Array.from(this.widgets.values()).map((c) => c.status());
|
|
81
|
-
// Rendering statuses
|
|
82
83
|
if (statuses.some((status) => status === AXPWidgetStatus.Rendering)) {
|
|
83
84
|
return AXPPageStatus.Rendering;
|
|
84
85
|
}
|
|
85
86
|
if (statuses.every((status) => status === AXPWidgetStatus.Rendered)) {
|
|
86
87
|
return AXPPageStatus.Rendered;
|
|
87
88
|
}
|
|
88
|
-
// Processing statuses
|
|
89
89
|
if (statuses.some((status) => status === AXPWidgetStatus.Processing)) {
|
|
90
90
|
return AXPPageStatus.Processing;
|
|
91
91
|
}
|
|
92
|
-
// Error handling
|
|
93
92
|
if (statuses.some((status) => status === AXPWidgetStatus.Error)) {
|
|
94
93
|
return AXPPageStatus.Error;
|
|
95
94
|
}
|
|
96
|
-
return AXPPageStatus.Rendered;
|
|
95
|
+
return AXPPageStatus.Rendered;
|
|
97
96
|
}
|
|
98
97
|
refresh() {
|
|
99
98
|
setTimeout(() => {
|
|
@@ -128,11 +127,6 @@ class AXPWidgetCoreService {
|
|
|
128
127
|
getWidget(id) {
|
|
129
128
|
return this.widgets.get(id);
|
|
130
129
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Waits until a widget with the given id is registered, then resolves with it.
|
|
133
|
-
* If the widget is already registered, resolves immediately.
|
|
134
|
-
* Optionally accepts a timeout (in ms) after which it resolves with undefined.
|
|
135
|
-
*/
|
|
136
130
|
async waitForWidget(id, timeoutMs) {
|
|
137
131
|
const existing = this.widgets.get(id);
|
|
138
132
|
if (existing) {
|
|
@@ -162,12 +156,12 @@ class AXPWidgetCoreService {
|
|
|
162
156
|
}
|
|
163
157
|
});
|
|
164
158
|
}
|
|
165
|
-
/**
|
|
166
|
-
* Returns a list of registered widget ids (names).
|
|
167
|
-
*/
|
|
168
159
|
listRegisteredWidgetNames() {
|
|
169
160
|
return Array.from(this.widgets.keys());
|
|
170
161
|
}
|
|
162
|
+
notifyWidgetDirtyChanged() {
|
|
163
|
+
this.dirtyWidgetsRevision.update((value) => value + 1);
|
|
164
|
+
}
|
|
171
165
|
ngOnDestroy() { }
|
|
172
166
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWidgetCoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
173
167
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWidgetCoreService }); }
|
|
@@ -501,23 +495,34 @@ class AXPValueWidgetComponent extends AXPLayoutBaseWidgetComponent {
|
|
|
501
495
|
if (this.node.valueTransforms?.setter) {
|
|
502
496
|
value = this.node.valueTransforms?.setter(value);
|
|
503
497
|
}
|
|
498
|
+
const path = this.fullPath();
|
|
499
|
+
if (!path) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
504
502
|
const oldValue = this.getValue();
|
|
505
503
|
value = isUndefined(value) ? null : value;
|
|
506
504
|
if (isNil(value) && isNil(oldValue)) {
|
|
507
505
|
return;
|
|
508
506
|
}
|
|
507
|
+
const savedAtPath = this.contextService.getSavedValue(path);
|
|
508
|
+
if (this.contextService.isSavedCommitted() &&
|
|
509
|
+
isSelectionValueEqual(value, savedAtPath) &&
|
|
510
|
+
!isEqual(oldValue, savedAtPath)) {
|
|
511
|
+
this.contextService.update(path, cloneDeep(savedAtPath));
|
|
512
|
+
this.onValueChanged.next({ sender: this });
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
509
515
|
// Reordered arrays must persist even when items are deep-equal (e.g. empty row objects).
|
|
510
516
|
const isArrayReorder = Array.isArray(oldValue) &&
|
|
511
517
|
Array.isArray(value) &&
|
|
512
518
|
oldValue.length === value.length &&
|
|
513
519
|
oldValue.some((v, i) => v !== value[i]);
|
|
514
|
-
|
|
520
|
+
const isArrayLengthChange = Array.isArray(value) && (!Array.isArray(oldValue) || value.length !== oldValue.length);
|
|
521
|
+
if (!isArrayReorder && !isArrayLengthChange && isFormValueEqual(oldValue, value)) {
|
|
515
522
|
return;
|
|
516
523
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
this.onValueChanged.next({ sender: this });
|
|
520
|
-
}
|
|
524
|
+
this.contextService.update(path, value);
|
|
525
|
+
this.onValueChanged.next({ sender: this });
|
|
521
526
|
}
|
|
522
527
|
detectFullPath() {
|
|
523
528
|
const sections = [];
|
|
@@ -1649,9 +1654,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1649
1654
|
args: ['header']
|
|
1650
1655
|
}] } });
|
|
1651
1656
|
|
|
1657
|
+
/** Idle period after widgets register / hydrate before committing the saved baseline. */
|
|
1658
|
+
const FORM_SAVED_BASELINE_IDLE_MS = 500;
|
|
1652
1659
|
class AXPWidgetContainerComponent {
|
|
1653
1660
|
set context(value) {
|
|
1654
|
-
this.
|
|
1661
|
+
this.syncExternalContext(value);
|
|
1655
1662
|
}
|
|
1656
1663
|
set functions(v) {
|
|
1657
1664
|
this.builderService.setFunctions(v);
|
|
@@ -1660,16 +1667,38 @@ class AXPWidgetContainerComponent {
|
|
|
1660
1667
|
this.contextService = inject(AXPContextStore);
|
|
1661
1668
|
this.builderService = inject(AXPWidgetCoreService);
|
|
1662
1669
|
this.onContextChanged = new EventEmitter();
|
|
1663
|
-
this.
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1670
|
+
this.isSavedCommitted = computed(() => this.contextService.isSavedCommitted(), ...(ngDevMode ? [{ debugName: "isSavedCommitted" }] : /* istanbul ignore next */ []));
|
|
1671
|
+
this.isFormDirty = computed(() => {
|
|
1672
|
+
if (!this.contextService.isSavedCommitted()) {
|
|
1673
|
+
return false;
|
|
1674
|
+
}
|
|
1675
|
+
this.contextService.data();
|
|
1676
|
+
return this.contextService.isDirty();
|
|
1677
|
+
}, ...(ngDevMode ? [{ debugName: "isFormDirty" }] : /* istanbul ignore next */ []));
|
|
1678
|
+
this.status = computed(() => this.builderService.status(), ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
1679
|
+
this.isBusy = computed(() => this.builderService.isBusy(), ...(ngDevMode ? [{ debugName: "isBusy" }] : /* istanbul ignore next */ []));
|
|
1669
1680
|
effect(() => {
|
|
1670
|
-
|
|
1671
|
-
|
|
1681
|
+
const isDirty = this.isFormDirty();
|
|
1682
|
+
const data = this.contextService.data();
|
|
1683
|
+
const changeEvent = this.contextService.changeEvent();
|
|
1684
|
+
if (!this.contextService.isChanged() && this.lastEmittedFormDirty === isDirty) {
|
|
1685
|
+
return;
|
|
1672
1686
|
}
|
|
1687
|
+
this.lastEmittedFormDirty = isDirty;
|
|
1688
|
+
this.onContextChanged.emit({
|
|
1689
|
+
...changeEvent,
|
|
1690
|
+
data: cloneDeep(data),
|
|
1691
|
+
isFormDirty: isDirty,
|
|
1692
|
+
});
|
|
1693
|
+
});
|
|
1694
|
+
effect(() => {
|
|
1695
|
+
if (this.contextService.isSavedCommitted()) {
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
if (this.builderService.registeredWidgetsCount() === 0) {
|
|
1699
|
+
return;
|
|
1700
|
+
}
|
|
1701
|
+
untracked(() => void this.settleSavedBaseline());
|
|
1673
1702
|
});
|
|
1674
1703
|
}
|
|
1675
1704
|
refresh() {
|
|
@@ -1678,6 +1707,62 @@ class AXPWidgetContainerComponent {
|
|
|
1678
1707
|
find(name) {
|
|
1679
1708
|
return this.builderService.waitForWidget(name);
|
|
1680
1709
|
}
|
|
1710
|
+
syncExternalContext(value) {
|
|
1711
|
+
const next = cloneDeep(value ?? {});
|
|
1712
|
+
const current = this.contextService.data();
|
|
1713
|
+
if (isEqual(current, next)) {
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
if (this.contextService.isSavedCommitted() && this.isFormDirty()) {
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
if (this.contextService.isSavedCommitted()) {
|
|
1720
|
+
this.contextService.set(next);
|
|
1721
|
+
void this.settleSavedBaseline();
|
|
1722
|
+
return;
|
|
1723
|
+
}
|
|
1724
|
+
if (this.contextService.isChanged()) {
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
this.contextService.set(next);
|
|
1728
|
+
void this.settleSavedBaseline();
|
|
1729
|
+
}
|
|
1730
|
+
/** Commits the current data as saved after widget hydration settles. */
|
|
1731
|
+
settleSavedBaseline() {
|
|
1732
|
+
this.clearSavedBaselineTimer();
|
|
1733
|
+
return new Promise((resolve) => {
|
|
1734
|
+
const commit = () => {
|
|
1735
|
+
if (this.builderService.registeredWidgetsCount() === 0) {
|
|
1736
|
+
this.savedBaselineTimer = setTimeout(commit, FORM_SAVED_BASELINE_IDLE_MS);
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
this.contextService.commitSaved();
|
|
1740
|
+
this.lastEmittedFormDirty = undefined;
|
|
1741
|
+
this.savedBaselineTimer = undefined;
|
|
1742
|
+
resolve();
|
|
1743
|
+
};
|
|
1744
|
+
this.savedBaselineTimer = setTimeout(commit, FORM_SAVED_BASELINE_IDLE_MS);
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
async replaceContext(value) {
|
|
1748
|
+
this.clearSavedBaselineTimer();
|
|
1749
|
+
this.contextService.set(cloneDeep(value));
|
|
1750
|
+
// Commit immediately so save/replace is clean even when `set()` no-ops (data already matches).
|
|
1751
|
+
this.contextService.commitSaved();
|
|
1752
|
+
this.lastEmittedFormDirty = undefined;
|
|
1753
|
+
await this.settleSavedBaseline();
|
|
1754
|
+
}
|
|
1755
|
+
revertAndSettle() {
|
|
1756
|
+
this.clearSavedBaselineTimer();
|
|
1757
|
+
this.contextService.revertToSaved();
|
|
1758
|
+
this.lastEmittedFormDirty = undefined;
|
|
1759
|
+
}
|
|
1760
|
+
clearSavedBaselineTimer() {
|
|
1761
|
+
if (this.savedBaselineTimer) {
|
|
1762
|
+
clearTimeout(this.savedBaselineTimer);
|
|
1763
|
+
this.savedBaselineTimer = undefined;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1681
1766
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWidgetContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1682
1767
|
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
1768
|
}
|
|
@@ -1753,6 +1838,7 @@ class AXPWidgetRendererDirective {
|
|
|
1753
1838
|
this.isVisible = signal(true, ...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
|
|
1754
1839
|
this.expressionEvaluators = new Map();
|
|
1755
1840
|
this.renderTimeoutId = null;
|
|
1841
|
+
this.renderGeneration = 0;
|
|
1756
1842
|
this.hasInitialRender = false;
|
|
1757
1843
|
this.onContextChanged = new Subject();
|
|
1758
1844
|
this.onLoadEvent = new Subject();
|
|
@@ -2111,18 +2197,18 @@ class AXPWidgetRendererDirective {
|
|
|
2111
2197
|
}
|
|
2112
2198
|
}
|
|
2113
2199
|
rerenderComponent() {
|
|
2114
|
-
// Clear any pending render operation to prevent double rendering
|
|
2115
2200
|
if (this.renderTimeoutId) {
|
|
2116
2201
|
clearTimeout(this.renderTimeoutId);
|
|
2117
2202
|
this.renderTimeoutId = null;
|
|
2118
2203
|
}
|
|
2119
|
-
|
|
2120
|
-
this.isLoading.set(false);
|
|
2121
|
-
// Schedule the component loading
|
|
2204
|
+
const generation = ++this.renderGeneration;
|
|
2122
2205
|
this.renderTimeoutId = setTimeout(async () => {
|
|
2123
|
-
await this.loadComponent();
|
|
2124
2206
|
this.renderTimeoutId = null;
|
|
2125
|
-
|
|
2207
|
+
if (generation !== this.renderGeneration) {
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2210
|
+
await this.loadComponent();
|
|
2211
|
+
}, 0);
|
|
2126
2212
|
}
|
|
2127
2213
|
ngOnDestroy() {
|
|
2128
2214
|
if (this.renderTimeoutId) {
|
|
@@ -2511,6 +2597,9 @@ class AXPWidgetRendererDirective {
|
|
|
2511
2597
|
return this.contextService.data();
|
|
2512
2598
|
},
|
|
2513
2599
|
isDirty: () => {
|
|
2600
|
+
if (!this.contextService.isSavedCommitted()) {
|
|
2601
|
+
return false;
|
|
2602
|
+
}
|
|
2514
2603
|
return this.contextService.isDirty();
|
|
2515
2604
|
},
|
|
2516
2605
|
/**
|