@acorex/platform 20.9.5 → 20.9.8
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 +71 -1
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +244 -4
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +96 -19
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +19 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +51 -8
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +65 -19
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +82 -43
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +168 -80
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-common.d.ts +18 -2
- package/types/acorex-platform-core.d.ts +68 -2
- package/types/acorex-platform-layout-components.d.ts +12 -0
- package/types/acorex-platform-layout-entity-contracts.d.ts +14 -2
- package/types/acorex-platform-layout-entity.d.ts +2 -1
- package/types/acorex-platform-layout-views.d.ts +6 -13
- package/types/acorex-platform-layout-widget-core.d.ts +11 -4
- package/types/acorex-platform-layout-widgets.d.ts +20 -0
|
@@ -3,7 +3,7 @@ import { signal, computed, effect, untracked, Injectable, inject, ElementRef, De
|
|
|
3
3
|
import { isSelectionValueEqual, isFormValueEqual, extractValue, getSmart, summarizeFormContextDirtyDiff, AXPWidgetsCatalog } from '@acorex/platform/contracts';
|
|
4
4
|
import { AXPPageStatus, AXPWidgetStatus, AXP_WIDGET_TOKEN, AXP_WIDGET_COLUMN_TOKEN, createStringProperty, createBooleanProperty, createSelectProperty, createNumberProperty, cloneProperty } from '@acorex/platform/layout/widget-core-contracts';
|
|
5
5
|
import { convertArrayToDataSource, AXDataSource, AX_STYLE_COLOR_TYPES, AX_STYLE_LOOK_TYPES } from '@acorex/cdk/common';
|
|
6
|
-
import { AXPContextStore, AXPDebugService, FORM_DIRTY_TRACE_NS,
|
|
6
|
+
import { AXPContextStore, AXPDebugService, FORM_DIRTY_TRACE_NS, AXPDataSourceQueryService, AXPExpressionEvaluatorService, OVERLAY_WIDGET_SETTLE_TRACE_NS } from '@acorex/platform/core';
|
|
7
7
|
import { set, get, cloneDeep, isEqual, isNil, isUndefined, isObjectLike, merge, sum, isEmpty, isString } from 'lodash-es';
|
|
8
8
|
import { Subject, BehaviorSubject, filter } from 'rxjs';
|
|
9
9
|
import * as i1$1 from '@acorex/components/skeleton';
|
|
@@ -504,14 +504,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
504
504
|
class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
505
505
|
constructor() {
|
|
506
506
|
super(...arguments);
|
|
507
|
-
this.
|
|
507
|
+
this.registryDataSourceQuery = inject(AXPDataSourceQueryService);
|
|
508
508
|
this.textField = computed(() => this.options()['textField'] ?? 'title', ...(ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []));
|
|
509
509
|
this.valueField = computed(() => this.options()['valueField'] ?? 'id', ...(ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []));
|
|
510
510
|
this.textTemplate = computed(() => isNil(this.options()['textTemplate'])
|
|
511
511
|
? undefined
|
|
512
512
|
: this.options()['textTemplate'].replace(/{/g, '{{').replace(/}/g, '}}'), ...(ngDevMode ? [{ debugName: "textTemplate" }] : /* istanbul ignore next */ []));
|
|
513
513
|
this.dataSource = signal(convertArrayToDataSource([]), ...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
|
|
514
|
+
/** Registry datasource name from options, when options.dataSource is a string or `{ id }` object. */
|
|
515
|
+
this.registryDataSourceName = computed(() => {
|
|
516
|
+
const rawValue = this.options()['dataSource'];
|
|
517
|
+
if (typeof rawValue === 'string') {
|
|
518
|
+
return rawValue;
|
|
519
|
+
}
|
|
520
|
+
if (rawValue && typeof rawValue === 'object' && 'id' in rawValue) {
|
|
521
|
+
return String(rawValue['id']);
|
|
522
|
+
}
|
|
523
|
+
return null;
|
|
524
|
+
}, ...(ngDevMode ? [{ debugName: "registryDataSourceName" }] : /* istanbul ignore next */ []));
|
|
514
525
|
this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
|
|
526
|
+
/** Reactive flag: registry datasource finished resolving (success or failure). */
|
|
527
|
+
this.registryDataSourceReady = signal(false, ...(ngDevMode ? [{ debugName: "registryDataSourceReady" }] : /* istanbul ignore next */ []));
|
|
528
|
+
/** Reactive bump to reload registry-backed datasources (e.g. after locale change). */
|
|
529
|
+
this.registryRefreshEpoch = signal(0, ...(ngDevMode ? [{ debugName: "registryRefreshEpoch" }] : /* istanbul ignore next */ []));
|
|
515
530
|
//#region ---- DataSource Loading Effect ----
|
|
516
531
|
/**
|
|
517
532
|
* Track the last loaded string dataSource reference to prevent infinite loops
|
|
@@ -520,9 +535,14 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
520
535
|
this.lastStringDataSourceRef = null;
|
|
521
536
|
this.rf = effect(async () => {
|
|
522
537
|
const rawValue = this.options()['dataSource'];
|
|
538
|
+
const registryId = this.registryDataSourceName();
|
|
539
|
+
this.registryRefreshEpoch();
|
|
523
540
|
// For string datasources: prevent infinite loop by checking reference
|
|
524
541
|
if (typeof rawValue === 'string') {
|
|
525
542
|
if (rawValue === this.lastStringDataSourceRef) {
|
|
543
|
+
if (registryId) {
|
|
544
|
+
this.registryDataSourceReady.set(true);
|
|
545
|
+
}
|
|
526
546
|
return;
|
|
527
547
|
}
|
|
528
548
|
this.lastStringDataSourceRef = rawValue;
|
|
@@ -531,6 +551,9 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
531
551
|
// Reset string reference when dataSource changes to non-string
|
|
532
552
|
this.lastStringDataSourceRef = null;
|
|
533
553
|
}
|
|
554
|
+
if (registryId) {
|
|
555
|
+
this.registryDataSourceReady.set(false);
|
|
556
|
+
}
|
|
534
557
|
this.beginHydration();
|
|
535
558
|
try {
|
|
536
559
|
// Process dataSource creation in untracked context
|
|
@@ -540,6 +563,7 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
540
563
|
if (!isEqual(rawValue.config, this.dataSource().config)) {
|
|
541
564
|
this.dataSource.set(rawValue);
|
|
542
565
|
}
|
|
566
|
+
this.registryDataSourceReady.set(true);
|
|
543
567
|
}
|
|
544
568
|
// static array datasource - always recreate when options change
|
|
545
569
|
else if (Array.isArray(rawValue)) {
|
|
@@ -562,35 +586,24 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
562
586
|
},
|
|
563
587
|
});
|
|
564
588
|
this.dataSource.set(ds);
|
|
589
|
+
this.registryDataSourceReady.set(true);
|
|
565
590
|
}
|
|
566
591
|
// resolve data source by name (string or object with id)
|
|
567
|
-
else if (
|
|
568
|
-
const
|
|
569
|
-
const
|
|
570
|
-
if (
|
|
571
|
-
this.dataSource.set(
|
|
572
|
-
key: this.valueField(),
|
|
573
|
-
pageSize: 500,
|
|
574
|
-
}));
|
|
592
|
+
else if (registryId) {
|
|
593
|
+
const queryOptions = this.buildRegistryQueryOptions();
|
|
594
|
+
const result = await this.registryDataSourceQuery.resolve(registryId, queryOptions);
|
|
595
|
+
if (result.dataSource) {
|
|
596
|
+
this.dataSource.set(result.dataSource);
|
|
575
597
|
}
|
|
576
598
|
else {
|
|
577
|
-
|
|
578
|
-
if (ds && ds instanceof Promise) {
|
|
579
|
-
const d = await ds;
|
|
580
|
-
this.dataSource.set(d);
|
|
581
|
-
}
|
|
582
|
-
else if (ds) {
|
|
583
|
-
this.dataSource.set(ds);
|
|
584
|
-
}
|
|
585
|
-
// empty datasource
|
|
586
|
-
else {
|
|
587
|
-
this.dataSource.set(convertArrayToDataSource([]));
|
|
588
|
-
}
|
|
599
|
+
this.dataSource.set(convertArrayToDataSource([]));
|
|
589
600
|
}
|
|
601
|
+
this.registryDataSourceReady.set(true);
|
|
590
602
|
}
|
|
591
603
|
// empty datasource
|
|
592
604
|
else {
|
|
593
605
|
this.dataSource.set(convertArrayToDataSource([]));
|
|
606
|
+
this.registryDataSourceReady.set(true);
|
|
594
607
|
}
|
|
595
608
|
});
|
|
596
609
|
}
|
|
@@ -598,26 +611,51 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
598
611
|
this.endHydration();
|
|
599
612
|
}
|
|
600
613
|
}, ...(ngDevMode ? [{ debugName: "rf" }] : /* istanbul ignore next */ []));
|
|
601
|
-
this.effect2 = effect(
|
|
602
|
-
this.
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
614
|
+
this.effect2 = effect(() => {
|
|
615
|
+
const registryName = this.registryDataSourceName();
|
|
616
|
+
const value = this.resolveSelectedItemsValue();
|
|
617
|
+
const registryReady = this.registryDataSourceReady();
|
|
618
|
+
this.dataSource();
|
|
619
|
+
if (registryName && !registryReady) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const resolveSelectedItems = async () => {
|
|
623
|
+
this.beginHydration();
|
|
624
|
+
try {
|
|
625
|
+
const items = [];
|
|
626
|
+
if (Array.isArray(value)) {
|
|
627
|
+
items.push(...(await Promise.all(value.map((item) => this.extractItem(item)))));
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
items.push(await this.extractItem(value));
|
|
631
|
+
}
|
|
632
|
+
this.selectedItems.set(items.filter((c) => c != null));
|
|
609
633
|
}
|
|
610
|
-
|
|
611
|
-
|
|
634
|
+
finally {
|
|
635
|
+
this.endHydration();
|
|
612
636
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
finally {
|
|
616
|
-
this.endHydration();
|
|
617
|
-
}
|
|
637
|
+
};
|
|
638
|
+
void resolveSelectedItems();
|
|
618
639
|
}, ...(ngDevMode ? [{ debugName: "effect2" }] : /* istanbul ignore next */ []));
|
|
619
640
|
}
|
|
641
|
+
buildRegistryQueryOptions() {
|
|
642
|
+
return {
|
|
643
|
+
valueField: this.valueField(),
|
|
644
|
+
useSamples: this.mode === 'designer',
|
|
645
|
+
};
|
|
646
|
+
}
|
|
620
647
|
//#endregion
|
|
648
|
+
/** Invalidates cached registry datasource and forces a reload on the next effect run. */
|
|
649
|
+
refreshRegistryDataSource() {
|
|
650
|
+
const registryId = this.registryDataSourceName();
|
|
651
|
+
if (!registryId) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
this.registryDataSourceQuery.invalidate(registryId);
|
|
655
|
+
this.lastStringDataSourceRef = null;
|
|
656
|
+
this.registryDataSourceReady.set(false);
|
|
657
|
+
this.registryRefreshEpoch.update((epoch) => epoch + 1);
|
|
658
|
+
}
|
|
621
659
|
async extractItem(item) {
|
|
622
660
|
if (isNil(item)) {
|
|
623
661
|
return null;
|
|
@@ -626,6 +664,13 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
626
664
|
return item;
|
|
627
665
|
}
|
|
628
666
|
const key = extractValue(item, this.valueField());
|
|
667
|
+
const registryName = this.registryDataSourceName();
|
|
668
|
+
if (registryName) {
|
|
669
|
+
const found = await this.registryDataSourceQuery.queryByKey(registryName, key, this.buildRegistryQueryOptions());
|
|
670
|
+
if (found) {
|
|
671
|
+
return found;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
629
674
|
const ds = this.dataSource();
|
|
630
675
|
if (ds.config?.byKey) {
|
|
631
676
|
const found = await ds.config?.byKey(key);
|
|
@@ -645,16 +690,10 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
|
|
|
645
690
|
* widgets that wrap their value (e.g. filter mode) can override this to expose
|
|
646
691
|
* the unwrapped scalar/array so item resolution receives a real key.
|
|
647
692
|
*/
|
|
648
|
-
//TODO: WHY IS THIS HAPPENING
|
|
649
693
|
resolveSelectedItemsValue() {
|
|
650
694
|
return this.getValue();
|
|
651
695
|
}
|
|
652
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDataListWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
653
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDataListWidgetComponent }); }
|
|
654
696
|
}
|
|
655
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDataListWidgetComponent, decorators: [{
|
|
656
|
-
type: Injectable
|
|
657
|
-
}] });
|
|
658
697
|
class AXPColumnWidgetComponent {
|
|
659
698
|
constructor() {
|
|
660
699
|
this.token = inject(AXP_WIDGET_COLUMN_TOKEN);
|