@acorex/platform 20.6.0-next.1 → 20.6.0-next.3

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/core/index.d.ts CHANGED
@@ -989,8 +989,8 @@ type AXPWidgetTriggers = AXPWidgetTrigger[];
989
989
 
990
990
  type AXPFileStatus = 'attached' | 'uploading' | 'uploaded' | 'deleted' | 'remote';
991
991
  interface AXPFileSource {
992
- kind: 'blob' | 'url' | 'preview' | 'none' | 'fileId' | 'documentId';
993
- value?: Blob | string;
992
+ kind: 'blob' | 'url' | 'preview' | 'none' | 'fileId' | 'reference';
993
+ value?: Blob | string | AXPEntityReference;
994
994
  }
995
995
  interface AXPFileListItem {
996
996
  id?: string;
@@ -686,65 +686,83 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
686
686
  return result;
687
687
  }, ...(ngDevMode ? [{ debugName: "isReady" }] : []));
688
688
  this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
689
+ //#region ---- DataSource Loading Effect ----
690
+ /**
691
+ * Track the last loaded string dataSource reference to prevent infinite loops
692
+ * Only used for string-based datasources (not arrays or AXDataSource instances)
693
+ */
694
+ this.lastStringDataSourceRef = null;
689
695
  this.rf = effect(async () => {
690
696
  const rawValue = this.options()['dataSource'];
691
- // static datasource class
692
- untracked(async () => {
693
- if (!isEqual(this.options()['dataSource'].config, this.dataSource().config)) {
694
- if (rawValue instanceof AXDataSource) {
697
+ // For string datasources: prevent infinite loop by checking reference
698
+ if (typeof rawValue === 'string') {
699
+ if (rawValue === this.lastStringDataSourceRef) {
700
+ return;
701
+ }
702
+ this.lastStringDataSourceRef = rawValue;
703
+ }
704
+ else {
705
+ // Reset string reference when dataSource changes to non-string
706
+ this.lastStringDataSourceRef = null;
707
+ }
708
+ // Process dataSource creation in untracked context
709
+ await untracked(async () => {
710
+ if (rawValue instanceof AXDataSource) {
711
+ // For AXDataSource instances, check if config changed
712
+ if (!isEqual(rawValue.config, this.dataSource().config)) {
695
713
  this.dataSource.set(rawValue);
696
714
  }
697
- // static array datasource
698
- else if (Array.isArray(rawValue)) {
699
- const ds = new AXDataSource({
715
+ }
716
+ // static array datasource - always recreate when options change
717
+ else if (Array.isArray(rawValue)) {
718
+ const ds = new AXDataSource({
719
+ key: this.valueField(),
720
+ pageSize: 10,
721
+ load: async (e) => {
722
+ const raw = this.options()['dataSource'];
723
+ const skip = e.skip ?? 0;
724
+ const take = e.take ?? raw.length;
725
+ return {
726
+ items: raw.slice(skip, skip + take),
727
+ total: raw.length,
728
+ };
729
+ },
730
+ byKey: (key) => {
731
+ const raw = this.options()['dataSource'];
732
+ const item = raw.filter((c) => c[this.valueField()] == key);
733
+ return Promise.resolve(item[0]);
734
+ },
735
+ });
736
+ this.dataSource.set(ds);
737
+ }
738
+ // resolve data source by name (string or object with id)
739
+ else if (rawValue && (typeof rawValue == 'string' || typeof rawValue == 'object')) {
740
+ const id = typeof rawValue == 'object' ? rawValue['id'] : rawValue;
741
+ const c = await this.dataService.get(id);
742
+ if (this.mode == 'designer' && c?.samples?.length) {
743
+ this.dataSource.set(convertArrayToDataSource(c.samples, {
700
744
  key: this.valueField(),
701
- pageSize: 10,
702
- load: async (e) => {
703
- const raw = this.options()['dataSource'];
704
- const skip = e.skip ?? 0;
705
- const take = e.take ?? raw.length;
706
- return {
707
- items: raw.slice(skip, skip + take),
708
- total: raw.length,
709
- };
710
- },
711
- byKey: (key) => {
712
- const raw = this.options()['dataSource'];
713
- const item = raw.filter((c) => c[this.valueField()] == key);
714
- return Promise.resolve(item[0]);
715
- },
716
- });
717
- this.dataSource.set(ds);
745
+ pageSize: 500,
746
+ }));
718
747
  }
719
- // resolve data source by name
720
- else if (rawValue && (typeof rawValue == 'string' || typeof rawValue == 'object')) {
721
- const id = typeof rawValue == 'object' ? rawValue['id'] : rawValue;
722
- const c = await this.dataService.get(id);
723
- if (this.mode == 'designer' && c?.samples?.length) {
724
- this.dataSource.set(convertArrayToDataSource(c.samples, {
725
- key: this.valueField(),
726
- pageSize: 500,
727
- }));
748
+ else {
749
+ const ds = c?.source();
750
+ if (ds && ds instanceof Promise) {
751
+ const d = await ds;
752
+ this.dataSource.set(d);
728
753
  }
754
+ else if (ds) {
755
+ this.dataSource.set(ds);
756
+ }
757
+ // empty datasource
729
758
  else {
730
- const ds = c?.source();
731
- if (ds && ds instanceof Promise) {
732
- const d = await ds;
733
- this.dataSource.set(d);
734
- }
735
- else if (ds) {
736
- this.dataSource.set(ds);
737
- }
738
- // empty datasource
739
- else {
740
- this.dataSource.set(convertArrayToDataSource([]));
741
- }
759
+ this.dataSource.set(convertArrayToDataSource([]));
742
760
  }
743
761
  }
744
- // empty datasource
745
- else {
746
- this.dataSource.set(convertArrayToDataSource([]));
747
- }
762
+ }
763
+ // empty datasource
764
+ else {
765
+ this.dataSource.set(convertArrayToDataSource([]));
748
766
  }
749
767
  });
750
768
  }, ...(ngDevMode ? [{ debugName: "rf" }] : []));
@@ -760,6 +778,7 @@ class AXPDataListWidgetComponent extends AXPValueWidgetComponent {
760
778
  this.selectedItems.set(items.filter((c) => c != null));
761
779
  }, ...(ngDevMode ? [{ debugName: "effect2" }] : []));
762
780
  }
781
+ //#endregion
763
782
  async extractItem(item) {
764
783
  if (isNil(item)) {
765
784
  return null;