@praxisui/dynamic-fields 9.0.0-beta.46 → 9.0.0-beta.48

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-07-08T00:30:08.464Z",
3
+ "generatedAt": "2026-07-08T13:50:56.661Z",
4
4
  "packageName": "@praxisui/dynamic-fields",
5
- "packageVersion": "9.0.0-beta.46",
5
+ "packageVersion": "9.0.0-beta.48",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 76,
@@ -3350,6 +3350,27 @@ function computeEffectiveState(metadata, overrides = {}) {
3350
3350
  return { readonly, disabled, presentation, visible };
3351
3351
  }
3352
3352
 
3353
+ function isSelectDebugEnabled() {
3354
+ try {
3355
+ if (globalThis.__PRAXIS_DEBUG_FIELDS__) {
3356
+ return true;
3357
+ }
3358
+ if (typeof localStorage !== 'undefined') {
3359
+ return localStorage.getItem('praxis.debug.fields') === 'true';
3360
+ }
3361
+ }
3362
+ catch { }
3363
+ return false;
3364
+ }
3365
+ function debugSelect(message, data) {
3366
+ if (!isSelectDebugEnabled()) {
3367
+ return;
3368
+ }
3369
+ try {
3370
+ console.debug(message, data);
3371
+ }
3372
+ catch { }
3373
+ }
3353
3374
  /**
3354
3375
  * Base directive providing common select behaviour. Extends
3355
3376
  * `SimpleBaseInputComponent` and manages option handling, multiple
@@ -3518,6 +3539,16 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
3518
3539
  this.scheduleRemoteOptionsLoad(remoteLoadSignature, () => this.loadOptions());
3519
3540
  }
3520
3541
  }
3542
+ else {
3543
+ this.clearRemoteOptionSourceState(metadata.filterCriteria ?? {});
3544
+ }
3545
+ }
3546
+ clearRemoteOptionSourceState(filterCriteria = {}) {
3547
+ this.resourcePath.set(null);
3548
+ this.filterCriteria.set(filterCriteria);
3549
+ this.loading.set(false);
3550
+ this.error.set(null);
3551
+ this.hasLoadedOnce = false;
3521
3552
  }
3522
3553
  scheduleRemoteOptionsLoad(signature, load) {
3523
3554
  if (signature === this.remoteOptionsLoadSignature &&
@@ -4263,13 +4294,10 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
4263
4294
  }));
4264
4295
  const missing = controls.filter((c) => !c.control).map((c) => c.name);
4265
4296
  if (missing.length) {
4266
- try {
4267
- console.warn('[Select] dependency controls not found', {
4268
- field: meta?.name,
4269
- missing,
4270
- });
4271
- }
4272
- catch { }
4297
+ debugSelect('[Select] dependency controls not found', {
4298
+ field: meta?.name,
4299
+ missing,
4300
+ });
4273
4301
  // Continue with those available
4274
4302
  }
4275
4303
  const streams = controls
@@ -4345,19 +4373,13 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
4345
4373
  break;
4346
4374
  }
4347
4375
  // Dev log
4348
- try {
4349
- const isDev = typeof globalThis.ngDevMode !== 'undefined' ? !!globalThis.ngDevMode : false;
4350
- if (isDev || globalThis.__PRAXIS_DEBUG_FIELDS__) {
4351
- console.debug('[Select] dependencies changed', {
4352
- field: meta?.name,
4353
- deps,
4354
- fragment,
4355
- mergeStrategy,
4356
- reloaded: loadOnChange === 'immediate' || (loadOnChange === 'respectLoadOn' && this.hasLoadedOnce),
4357
- });
4358
- }
4359
- }
4360
- catch { }
4376
+ debugSelect('[Select] dependencies changed', {
4377
+ field: meta?.name,
4378
+ deps,
4379
+ fragment,
4380
+ mergeStrategy,
4381
+ reloaded: loadOnChange === 'immediate' || (loadOnChange === 'respectLoadOn' && this.hasLoadedOnce),
4382
+ });
4361
4383
  });
4362
4384
  }
4363
4385
  extractDependencyValue(raw, path) {
@@ -12451,6 +12473,9 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12451
12473
  this.lastConfiguredPath = path;
12452
12474
  }
12453
12475
  }
12476
+ else {
12477
+ this.clearRemoteConfiguration(metadata.filterCriteria ?? {});
12478
+ }
12454
12479
  }
12455
12480
  errorStateMatcher() {
12456
12481
  return getErrorStateMatcherForField(this.metadata());
@@ -12464,6 +12489,9 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12464
12489
  this.preloadSelected();
12465
12490
  this.termControl.valueChanges
12466
12491
  .pipe(debounceTime(300), distinctUntilChanged(), switchMap(() => {
12492
+ if (!this.hasRemoteOptionsContract()) {
12493
+ return of(void 0);
12494
+ }
12467
12495
  this.pageIndex.set(0);
12468
12496
  this.cursorAfter = null;
12469
12497
  this.cursorPageIndex = 0;
@@ -12474,7 +12502,9 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12474
12502
  .subscribe();
12475
12503
  // Perform initial load on init if configured so, otherwise load on first open
12476
12504
  queueMicrotask(() => {
12477
- if (this.initialLoadStrategy === 'init' && this.options().length === 0) {
12505
+ if (this.hasRemoteOptionsContract() &&
12506
+ this.initialLoadStrategy === 'init' &&
12507
+ this.options().length === 0) {
12478
12508
  this.pageIndex.set(0);
12479
12509
  this.cursorAfter = null;
12480
12510
  this.cursorPageIndex = 0;
@@ -12491,7 +12521,8 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12491
12521
  }
12492
12522
  onOpened(opened) {
12493
12523
  if (opened) {
12494
- const shouldLoadOnOpen = this.initialLoadStrategy !== 'none' &&
12524
+ const shouldLoadOnOpen = this.hasRemoteOptionsContract() &&
12525
+ this.initialLoadStrategy !== 'none' &&
12495
12526
  this.options().length === 0 &&
12496
12527
  !this.loading();
12497
12528
  if (shouldLoadOnOpen) {
@@ -12522,6 +12553,8 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12522
12553
  return (typeof val === 'string' || typeof val === 'number') ? [val] : [];
12523
12554
  }
12524
12555
  preloadSelected(ids = this.getSelectedIds()) {
12556
+ if (!this.hasRemoteOptionsContract())
12557
+ return;
12525
12558
  if (!this.crudService)
12526
12559
  return;
12527
12560
  if (!ids.length)
@@ -12658,7 +12691,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12658
12691
  });
12659
12692
  }
12660
12693
  runQuery(reset) {
12661
- if (!this.crudService || !this.resourcePath()) {
12694
+ if (!this.crudService || !this.hasRemoteOptionsContract()) {
12662
12695
  return of(void 0);
12663
12696
  }
12664
12697
  const term = this.termControl.value || '';
@@ -12774,6 +12807,8 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12774
12807
  this.refocusSearchInput();
12775
12808
  }
12776
12809
  retry() {
12810
+ if (!this.hasRemoteOptionsContract())
12811
+ return;
12777
12812
  this.runQuery(true).subscribe();
12778
12813
  }
12779
12814
  handleKey(event) {
@@ -12804,7 +12839,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12804
12839
  // Phase 1: explicit reload API and dependency handling
12805
12840
  // ---------------------------------------------------------------------------
12806
12841
  reload(reset) {
12807
- if (!this.crudService || !this.resourcePath())
12842
+ if (!this.crudService || !this.hasRemoteOptionsContract())
12808
12843
  return;
12809
12844
  if (reset) {
12810
12845
  this.pageIndex.set(0);
@@ -12830,7 +12865,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12830
12865
  catch { }
12831
12866
  this.remoteSelectionHydrationSub = null;
12832
12867
  }
12833
- if (!this.resourcePath()) {
12868
+ if (!this.hasRemoteOptionsContract()) {
12834
12869
  return;
12835
12870
  }
12836
12871
  const control = this.control();
@@ -12843,7 +12878,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12843
12878
  onDependenciesChanged() {
12844
12879
  const meta = this.metadata();
12845
12880
  const mode = meta?.dependencyLoadOnChange ?? 'respectLoadOn';
12846
- if (!this.resourcePath())
12881
+ if (!this.hasRemoteOptionsContract())
12847
12882
  return;
12848
12883
  if (mode === 'manual')
12849
12884
  return;
@@ -12857,7 +12892,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12857
12892
  }
12858
12893
  }
12859
12894
  ensureCurrentValueLoadedByIds() {
12860
- if (!this.resourcePath() || this.loading()) {
12895
+ if (!this.hasRemoteOptionsContract() || this.loading()) {
12861
12896
  return;
12862
12897
  }
12863
12898
  const selected = this.getSelectedIds();
@@ -12899,6 +12934,22 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12899
12934
  }
12900
12935
  return value;
12901
12936
  }
12937
+ hasRemoteOptionsContract() {
12938
+ return !!String(this.resourcePath() || '').trim();
12939
+ }
12940
+ clearRemoteConfiguration(filterCriteria) {
12941
+ this.resourcePath.set('');
12942
+ this.filterCriteria.set(filterCriteria);
12943
+ this.lastConfiguredPath = undefined;
12944
+ this.remoteTotalElements.set(null);
12945
+ this.loading.set(false);
12946
+ this.error.set(null);
12947
+ this.endReached.set(false);
12948
+ this.cursorAfter = null;
12949
+ this.cursorPageIndex = 0;
12950
+ this.store.clearPages();
12951
+ this.hasPerformedInitialLoad = false;
12952
+ }
12902
12953
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MaterialAsyncSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
12903
12954
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MaterialAsyncSelectComponent, isStandalone: true, selector: "pdx-material-async-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "isInteractionDisabled()", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"async-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
12904
12955
  GenericCrudService,
@@ -14211,13 +14262,18 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
14211
14262
  return super.inlineTooltipText();
14212
14263
  }
14213
14264
  resolveLookupText(value) {
14214
- const matchedOption = this.options().find((option) => this.equalsOptionValue(option.value, value));
14265
+ const matchedOption = this.findKnownLookupOption(value);
14266
+ if (matchedOption &&
14267
+ (value === null || typeof value !== 'object') &&
14268
+ (matchedOption.value === null || typeof matchedOption.value !== 'object')) {
14269
+ return this.fallbackLookupText(matchedOption.label, value);
14270
+ }
14215
14271
  const lookup = this.resolveLookupData(matchedOption ? matchedOption.value : value, matchedOption?.label);
14216
14272
  const primary = this.buildLookupPrimaryText(lookup.id, lookup.label);
14217
14273
  return primary || this.fallbackLookupText(matchedOption?.label, value);
14218
14274
  }
14219
14275
  lookupViewFromValue(source, fallbackLabel) {
14220
- const matchedOption = this.options().find((option) => this.equalsOptionValue(option.value, source));
14276
+ const matchedOption = this.findKnownLookupOption(source);
14221
14277
  const value = matchedOption ? matchedOption.value : source;
14222
14278
  const lookup = this.resolveLookupData(value, matchedOption?.label ?? fallbackLabel);
14223
14279
  return {
@@ -14237,6 +14293,10 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
14237
14293
  richFields: lookup.richFields,
14238
14294
  };
14239
14295
  }
14296
+ findKnownLookupOption(value) {
14297
+ return (this.options().find((option) => this.equalsOptionValue(option.value, value)) ||
14298
+ this.staticOptions.find((option) => this.equalsOptionValue(option.value, value)));
14299
+ }
14240
14300
  resolveLookupData(source, fallbackLabel) {
14241
14301
  const idKeys = this.lookupIdKeys();
14242
14302
  const labelKeys = this.lookupLabelKeys();
@@ -16751,6 +16811,10 @@ class EntityLookupDialogComponent {
16751
16811
  return;
16752
16812
  }
16753
16813
  this.activeResultIndex = index;
16814
+ const option = this.resultOptions()[index];
16815
+ if (option) {
16816
+ this.setPreviewFromOption(option);
16817
+ }
16754
16818
  target.focus();
16755
16819
  }
16756
16820
  normalizeOptionValue(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-fields",
3
- "version": "9.0.0-beta.46",
3
+ "version": "9.0.0-beta.48",
4
4
  "description": "Angular Material-based dynamic form fields for Praxis UI with lazy loading and metadata-driven rendering.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -11,8 +11,8 @@
11
11
  "@angular/platform-browser": "^21.0.0",
12
12
  "@angular/router": "^21.0.0",
13
13
  "rxjs": "^7.8.0",
14
- "@praxisui/core": "^9.0.0-beta.46",
15
- "@praxisui/cron-builder": "^9.0.0-beta.46"
14
+ "@praxisui/core": "^9.0.0-beta.48",
15
+ "@praxisui/cron-builder": "^9.0.0-beta.48"
16
16
  },
17
17
  "dependencies": {
18
18
  "libphonenumber-js": "^1.12.41",
@@ -1136,6 +1136,7 @@ declare abstract class SimpleBaseSelectComponent<T = any> extends SimpleBaseInpu
1136
1136
  * Applies typed metadata to the select component.
1137
1137
  */
1138
1138
  setSelectMetadata(metadata: SimpleSelectMetadata<T>): void;
1139
+ protected clearRemoteOptionSourceState(filterCriteria?: Record<string, any>): void;
1139
1140
  private scheduleRemoteOptionsLoad;
1140
1141
  protected setMetadata(metadata: ComponentMetadata): void;
1141
1142
  protected registerMatSelect(select: MatSelect): void;
@@ -2756,6 +2757,8 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2756
2757
  protected resolveRemoteOptionDisabled(option: AsyncOption): boolean;
2757
2758
  protected areOptionValuesEqual(left: unknown, right: unknown): boolean;
2758
2759
  private normalizeRemoteOptionValue;
2760
+ protected hasRemoteOptionsContract(): boolean;
2761
+ private clearRemoteConfiguration;
2759
2762
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MaterialAsyncSelectComponent, never>;
2760
2763
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<MaterialAsyncSelectComponent, "pdx-material-async-select", never, { "readonlyMode": { "alias": "readonlyMode"; "required": false; }; "disabledMode": { "alias": "disabledMode"; "required": false; }; "visible": { "alias": "visible"; "required": false; }; "presentationMode": { "alias": "presentationMode"; "required": false; }; }, {}, never, never, true, never>;
2761
2764
  }
@@ -3052,6 +3055,7 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
3052
3055
  inlineTooltipText(): string;
3053
3056
  private resolveLookupText;
3054
3057
  private lookupViewFromValue;
3058
+ private findKnownLookupOption;
3055
3059
  private resolveLookupData;
3056
3060
  private buildLookupPrimaryText;
3057
3061
  private fallbackLookupText;