@praxisui/dynamic-fields 9.0.0-beta.45 → 9.0.0-beta.47

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-07T23:17:36.844Z",
3
+ "generatedAt": "2026-07-08T03:07:40.937Z",
4
4
  "packageName": "@praxisui/dynamic-fields",
5
- "packageVersion": "9.0.0-beta.45",
5
+ "packageVersion": "9.0.0-beta.47",
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
@@ -4263,13 +4284,10 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
4263
4284
  }));
4264
4285
  const missing = controls.filter((c) => !c.control).map((c) => c.name);
4265
4286
  if (missing.length) {
4266
- try {
4267
- console.warn('[Select] dependency controls not found', {
4268
- field: meta?.name,
4269
- missing,
4270
- });
4271
- }
4272
- catch { }
4287
+ debugSelect('[Select] dependency controls not found', {
4288
+ field: meta?.name,
4289
+ missing,
4290
+ });
4273
4291
  // Continue with those available
4274
4292
  }
4275
4293
  const streams = controls
@@ -4345,19 +4363,13 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
4345
4363
  break;
4346
4364
  }
4347
4365
  // 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 { }
4366
+ debugSelect('[Select] dependencies changed', {
4367
+ field: meta?.name,
4368
+ deps,
4369
+ fragment,
4370
+ mergeStrategy,
4371
+ reloaded: loadOnChange === 'immediate' || (loadOnChange === 'respectLoadOn' && this.hasLoadedOnce),
4372
+ });
4361
4373
  });
4362
4374
  }
4363
4375
  extractDependencyValue(raw, path) {
@@ -12451,6 +12463,9 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12451
12463
  this.lastConfiguredPath = path;
12452
12464
  }
12453
12465
  }
12466
+ else {
12467
+ this.clearRemoteConfiguration(metadata.filterCriteria ?? {});
12468
+ }
12454
12469
  }
12455
12470
  errorStateMatcher() {
12456
12471
  return getErrorStateMatcherForField(this.metadata());
@@ -12464,6 +12479,9 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12464
12479
  this.preloadSelected();
12465
12480
  this.termControl.valueChanges
12466
12481
  .pipe(debounceTime(300), distinctUntilChanged(), switchMap(() => {
12482
+ if (!this.hasRemoteOptionsContract()) {
12483
+ return of(void 0);
12484
+ }
12467
12485
  this.pageIndex.set(0);
12468
12486
  this.cursorAfter = null;
12469
12487
  this.cursorPageIndex = 0;
@@ -12474,7 +12492,9 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12474
12492
  .subscribe();
12475
12493
  // Perform initial load on init if configured so, otherwise load on first open
12476
12494
  queueMicrotask(() => {
12477
- if (this.initialLoadStrategy === 'init' && this.options().length === 0) {
12495
+ if (this.hasRemoteOptionsContract() &&
12496
+ this.initialLoadStrategy === 'init' &&
12497
+ this.options().length === 0) {
12478
12498
  this.pageIndex.set(0);
12479
12499
  this.cursorAfter = null;
12480
12500
  this.cursorPageIndex = 0;
@@ -12491,7 +12511,8 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12491
12511
  }
12492
12512
  onOpened(opened) {
12493
12513
  if (opened) {
12494
- const shouldLoadOnOpen = this.initialLoadStrategy !== 'none' &&
12514
+ const shouldLoadOnOpen = this.hasRemoteOptionsContract() &&
12515
+ this.initialLoadStrategy !== 'none' &&
12495
12516
  this.options().length === 0 &&
12496
12517
  !this.loading();
12497
12518
  if (shouldLoadOnOpen) {
@@ -12522,6 +12543,8 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12522
12543
  return (typeof val === 'string' || typeof val === 'number') ? [val] : [];
12523
12544
  }
12524
12545
  preloadSelected(ids = this.getSelectedIds()) {
12546
+ if (!this.hasRemoteOptionsContract())
12547
+ return;
12525
12548
  if (!this.crudService)
12526
12549
  return;
12527
12550
  if (!ids.length)
@@ -12658,7 +12681,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12658
12681
  });
12659
12682
  }
12660
12683
  runQuery(reset) {
12661
- if (!this.crudService || !this.resourcePath()) {
12684
+ if (!this.crudService || !this.hasRemoteOptionsContract()) {
12662
12685
  return of(void 0);
12663
12686
  }
12664
12687
  const term = this.termControl.value || '';
@@ -12774,6 +12797,8 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12774
12797
  this.refocusSearchInput();
12775
12798
  }
12776
12799
  retry() {
12800
+ if (!this.hasRemoteOptionsContract())
12801
+ return;
12777
12802
  this.runQuery(true).subscribe();
12778
12803
  }
12779
12804
  handleKey(event) {
@@ -12804,7 +12829,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12804
12829
  // Phase 1: explicit reload API and dependency handling
12805
12830
  // ---------------------------------------------------------------------------
12806
12831
  reload(reset) {
12807
- if (!this.crudService || !this.resourcePath())
12832
+ if (!this.crudService || !this.hasRemoteOptionsContract())
12808
12833
  return;
12809
12834
  if (reset) {
12810
12835
  this.pageIndex.set(0);
@@ -12830,7 +12855,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12830
12855
  catch { }
12831
12856
  this.remoteSelectionHydrationSub = null;
12832
12857
  }
12833
- if (!this.resourcePath()) {
12858
+ if (!this.hasRemoteOptionsContract()) {
12834
12859
  return;
12835
12860
  }
12836
12861
  const control = this.control();
@@ -12843,7 +12868,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12843
12868
  onDependenciesChanged() {
12844
12869
  const meta = this.metadata();
12845
12870
  const mode = meta?.dependencyLoadOnChange ?? 'respectLoadOn';
12846
- if (!this.resourcePath())
12871
+ if (!this.hasRemoteOptionsContract())
12847
12872
  return;
12848
12873
  if (mode === 'manual')
12849
12874
  return;
@@ -12857,7 +12882,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12857
12882
  }
12858
12883
  }
12859
12884
  ensureCurrentValueLoadedByIds() {
12860
- if (!this.resourcePath() || this.loading()) {
12885
+ if (!this.hasRemoteOptionsContract() || this.loading()) {
12861
12886
  return;
12862
12887
  }
12863
12888
  const selected = this.getSelectedIds();
@@ -12899,6 +12924,22 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
12899
12924
  }
12900
12925
  return value;
12901
12926
  }
12927
+ hasRemoteOptionsContract() {
12928
+ return !!String(this.resourcePath() || '').trim();
12929
+ }
12930
+ clearRemoteConfiguration(filterCriteria) {
12931
+ this.resourcePath.set('');
12932
+ this.filterCriteria.set(filterCriteria);
12933
+ this.lastConfiguredPath = undefined;
12934
+ this.remoteTotalElements.set(null);
12935
+ this.loading.set(false);
12936
+ this.error.set(null);
12937
+ this.endReached.set(false);
12938
+ this.cursorAfter = null;
12939
+ this.cursorPageIndex = 0;
12940
+ this.store.clearPages();
12941
+ this.hasPerformedInitialLoad = false;
12942
+ }
12902
12943
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MaterialAsyncSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
12903
12944
  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
12945
  GenericCrudService,
@@ -14211,13 +14252,18 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
14211
14252
  return super.inlineTooltipText();
14212
14253
  }
14213
14254
  resolveLookupText(value) {
14214
- const matchedOption = this.options().find((option) => this.equalsOptionValue(option.value, value));
14255
+ const matchedOption = this.findKnownLookupOption(value);
14256
+ if (matchedOption &&
14257
+ (value === null || typeof value !== 'object') &&
14258
+ (matchedOption.value === null || typeof matchedOption.value !== 'object')) {
14259
+ return this.fallbackLookupText(matchedOption.label, value);
14260
+ }
14215
14261
  const lookup = this.resolveLookupData(matchedOption ? matchedOption.value : value, matchedOption?.label);
14216
14262
  const primary = this.buildLookupPrimaryText(lookup.id, lookup.label);
14217
14263
  return primary || this.fallbackLookupText(matchedOption?.label, value);
14218
14264
  }
14219
14265
  lookupViewFromValue(source, fallbackLabel) {
14220
- const matchedOption = this.options().find((option) => this.equalsOptionValue(option.value, source));
14266
+ const matchedOption = this.findKnownLookupOption(source);
14221
14267
  const value = matchedOption ? matchedOption.value : source;
14222
14268
  const lookup = this.resolveLookupData(value, matchedOption?.label ?? fallbackLabel);
14223
14269
  return {
@@ -14237,6 +14283,10 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
14237
14283
  richFields: lookup.richFields,
14238
14284
  };
14239
14285
  }
14286
+ findKnownLookupOption(value) {
14287
+ return (this.options().find((option) => this.equalsOptionValue(option.value, value)) ||
14288
+ this.staticOptions.find((option) => this.equalsOptionValue(option.value, value)));
14289
+ }
14240
14290
  resolveLookupData(source, fallbackLabel) {
14241
14291
  const idKeys = this.lookupIdKeys();
14242
14292
  const labelKeys = this.lookupLabelKeys();
@@ -16751,6 +16801,10 @@ class EntityLookupDialogComponent {
16751
16801
  return;
16752
16802
  }
16753
16803
  this.activeResultIndex = index;
16804
+ const option = this.resultOptions()[index];
16805
+ if (option) {
16806
+ this.setPreviewFromOption(option);
16807
+ }
16754
16808
  target.focus();
16755
16809
  }
16756
16810
  normalizeOptionValue(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-fields",
3
- "version": "9.0.0-beta.45",
3
+ "version": "9.0.0-beta.47",
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.45",
15
- "@praxisui/cron-builder": "^9.0.0-beta.45"
14
+ "@praxisui/core": "^9.0.0-beta.47",
15
+ "@praxisui/cron-builder": "^9.0.0-beta.47"
16
16
  },
17
17
  "dependencies": {
18
18
  "libphonenumber-js": "^1.12.41",
@@ -2756,6 +2756,8 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2756
2756
  protected resolveRemoteOptionDisabled(option: AsyncOption): boolean;
2757
2757
  protected areOptionValuesEqual(left: unknown, right: unknown): boolean;
2758
2758
  private normalizeRemoteOptionValue;
2759
+ protected hasRemoteOptionsContract(): boolean;
2760
+ private clearRemoteConfiguration;
2759
2761
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MaterialAsyncSelectComponent, never>;
2760
2762
  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
2763
  }
@@ -3052,6 +3054,7 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
3052
3054
  inlineTooltipText(): string;
3053
3055
  private resolveLookupText;
3054
3056
  private lookupViewFromValue;
3057
+ private findKnownLookupOption;
3055
3058
  private resolveLookupData;
3056
3059
  private buildLookupPrimaryText;
3057
3060
  private fallbackLookupText;