@praxisui/dynamic-fields 9.0.0-beta.81 → 9.0.0-beta.83
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-
|
|
3
|
+
"generatedAt": "2026-07-20T14:11:58.169Z",
|
|
4
4
|
"packageName": "@praxisui/dynamic-fields",
|
|
5
|
-
"packageVersion": "9.0.0-beta.
|
|
5
|
+
"packageVersion": "9.0.0-beta.83",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 76,
|
|
@@ -4170,6 +4170,8 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
|
|
|
4170
4170
|
if (!this.crudService || !this.resourcePath()) {
|
|
4171
4171
|
return;
|
|
4172
4172
|
}
|
|
4173
|
+
this.synchronizeDependencyCriteriaFromControls();
|
|
4174
|
+
criteria = this.filterCriteria();
|
|
4173
4175
|
const filter = { ...criteria };
|
|
4174
4176
|
if (searchTerm && !this.optionSource()) {
|
|
4175
4177
|
filter[this.optionLabelKey()] = searchTerm;
|
|
@@ -4367,53 +4369,14 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
|
|
|
4367
4369
|
if (!streams.length)
|
|
4368
4370
|
return;
|
|
4369
4371
|
const debounceMs = Number(meta.dependencyDebounceMs ?? this.global.getDynamicFields()?.cascade?.debounceMs ?? 150);
|
|
4370
|
-
const valuePathCfg = this.resolveDependencyValuePathConfig(meta);
|
|
4371
|
-
const mapCfg = this.resolveDependencyFilterMap(meta);
|
|
4372
4372
|
const mergeStrategy = meta.dependencyMergeStrategy ?? 'merge';
|
|
4373
4373
|
const loadOnChange = meta.dependencyLoadOnChange ?? this.global.getDynamicFields()?.cascade?.loadOnChange ?? 'respectLoadOn';
|
|
4374
4374
|
// Subscribe to combined changes
|
|
4375
4375
|
this.dependencySub = combineLatest(streams)
|
|
4376
4376
|
.pipe(debounceTime(debounceMs))
|
|
4377
4377
|
.subscribe((values) => {
|
|
4378
|
-
|
|
4379
|
-
const fragment =
|
|
4380
|
-
controls
|
|
4381
|
-
.filter((c) => !!c.control)
|
|
4382
|
-
.forEach((c, idx) => {
|
|
4383
|
-
const raw = values[idx];
|
|
4384
|
-
// Determine valuePath for this dep
|
|
4385
|
-
let valuePath;
|
|
4386
|
-
if (valuePathCfg && typeof valuePathCfg === 'object') {
|
|
4387
|
-
valuePath = valuePathCfg[c.name];
|
|
4388
|
-
}
|
|
4389
|
-
else if (typeof valuePathCfg === 'string') {
|
|
4390
|
-
valuePath = valuePathCfg;
|
|
4391
|
-
}
|
|
4392
|
-
else {
|
|
4393
|
-
// default: use this component's optionValueKey or 'id'
|
|
4394
|
-
valuePath = this.optionValueKey?.() || 'id';
|
|
4395
|
-
}
|
|
4396
|
-
const extracted = this.extractDependencyValue(raw, valuePath);
|
|
4397
|
-
// Determine key mapping
|
|
4398
|
-
const mapEntry = mapCfg?.[c.name] ?? c.name;
|
|
4399
|
-
const targetKey = typeof mapEntry === 'string' ? mapEntry : mapEntry?.key ?? c.name;
|
|
4400
|
-
if (extracted == null || (Array.isArray(extracted) && extracted.length === 0)) {
|
|
4401
|
-
// remove mapped key when null/empty
|
|
4402
|
-
this.applyDependencyCriteria({ __remove__: targetKey }, mergeStrategy);
|
|
4403
|
-
return;
|
|
4404
|
-
}
|
|
4405
|
-
// Support dot-path keys (e.g., 'rota.id')
|
|
4406
|
-
const fragRoot = {};
|
|
4407
|
-
this.setByPath(fragRoot, targetKey, extracted);
|
|
4408
|
-
// Shallow merge fragment root-level keys
|
|
4409
|
-
Object.keys(fragRoot).forEach((k) => {
|
|
4410
|
-
fragment[k] = this.mergeObjectsDeep(fragment[k], fragRoot[k]);
|
|
4411
|
-
});
|
|
4412
|
-
});
|
|
4413
|
-
// Apply built fragment
|
|
4414
|
-
if (Object.keys(fragment).length > 0) {
|
|
4415
|
-
this.applyDependencyCriteria(fragment, mergeStrategy);
|
|
4416
|
-
}
|
|
4378
|
+
const availableControls = controls.filter((entry) => !!entry.control);
|
|
4379
|
+
const fragment = this.applyDependencyValues(meta, availableControls, values);
|
|
4417
4380
|
// Reset value when configured
|
|
4418
4381
|
if (meta.resetOnDependentChange) {
|
|
4419
4382
|
this.setValue(null, { emitEvent: false });
|
|
@@ -4501,9 +4464,62 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
|
|
|
4501
4464
|
return meta.optionSource?.valuePropertyPath;
|
|
4502
4465
|
}
|
|
4503
4466
|
optionSourceByIdsOptions() {
|
|
4467
|
+
this.synchronizeDependencyCriteriaFromControls();
|
|
4504
4468
|
const filter = this.filterCriteria();
|
|
4505
4469
|
return filter && Object.keys(filter).length ? { filter } : undefined;
|
|
4506
4470
|
}
|
|
4471
|
+
/** Keeps every request aligned with the dependency values currently bound to the form. */
|
|
4472
|
+
synchronizeDependencyCriteriaFromControls() {
|
|
4473
|
+
const meta = this.metadata();
|
|
4474
|
+
if (!meta || !this.resourcePath())
|
|
4475
|
+
return;
|
|
4476
|
+
const enabled = meta.enableDependencyCascade ??
|
|
4477
|
+
(this.global.getDynamicFields()?.cascade?.enable ?? true);
|
|
4478
|
+
const dependencies = this.resolveDependencyFields(meta);
|
|
4479
|
+
if (!dependencies?.length || enabled === false)
|
|
4480
|
+
return;
|
|
4481
|
+
const form = this.control()?.parent ?? null;
|
|
4482
|
+
if (!form)
|
|
4483
|
+
return;
|
|
4484
|
+
const controls = dependencies
|
|
4485
|
+
.map((name) => ({ name, control: form.get(name) ?? null }))
|
|
4486
|
+
.filter((entry) => !!entry.control);
|
|
4487
|
+
if (!controls.length)
|
|
4488
|
+
return;
|
|
4489
|
+
this.applyDependencyValues(meta, controls, controls.map((entry) => entry.control.value));
|
|
4490
|
+
}
|
|
4491
|
+
applyDependencyValues(meta, controls, values) {
|
|
4492
|
+
const fragment = {};
|
|
4493
|
+
const valuePathConfig = this.resolveDependencyValuePathConfig(meta);
|
|
4494
|
+
const filterMap = this.resolveDependencyFilterMap(meta);
|
|
4495
|
+
const mergeStrategy = meta.dependencyMergeStrategy ?? 'merge';
|
|
4496
|
+
controls.forEach((entry, index) => {
|
|
4497
|
+
const raw = values[index];
|
|
4498
|
+
const valuePath = valuePathConfig && typeof valuePathConfig === 'object'
|
|
4499
|
+
? valuePathConfig[entry.name]
|
|
4500
|
+
: typeof valuePathConfig === 'string'
|
|
4501
|
+
? valuePathConfig
|
|
4502
|
+
: this.optionValueKey?.() || 'id';
|
|
4503
|
+
const extracted = this.extractDependencyValue(raw, valuePath);
|
|
4504
|
+
const mapEntry = filterMap?.[entry.name] ?? entry.name;
|
|
4505
|
+
const targetKey = typeof mapEntry === 'string'
|
|
4506
|
+
? mapEntry
|
|
4507
|
+
: mapEntry?.key ?? entry.name;
|
|
4508
|
+
if (extracted == null || (Array.isArray(extracted) && extracted.length === 0)) {
|
|
4509
|
+
this.applyDependencyCriteria({ __remove__: targetKey }, mergeStrategy);
|
|
4510
|
+
return;
|
|
4511
|
+
}
|
|
4512
|
+
const mapped = {};
|
|
4513
|
+
this.setByPath(mapped, targetKey, extracted);
|
|
4514
|
+
Object.keys(mapped).forEach((key) => {
|
|
4515
|
+
fragment[key] = this.mergeObjectsDeep(fragment[key], mapped[key]);
|
|
4516
|
+
});
|
|
4517
|
+
});
|
|
4518
|
+
if (Object.keys(fragment).length) {
|
|
4519
|
+
this.applyDependencyCriteria(fragment, mergeStrategy);
|
|
4520
|
+
}
|
|
4521
|
+
return fragment;
|
|
4522
|
+
}
|
|
4507
4523
|
// Helpers: object path ops and merges
|
|
4508
4524
|
getByPath(obj, dotPath) {
|
|
4509
4525
|
if (!obj || !dotPath)
|
|
@@ -13097,6 +13113,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
|
|
|
13097
13113
|
if (!this.crudService || !this.hasRemoteOptionsContract()) {
|
|
13098
13114
|
return of(void 0);
|
|
13099
13115
|
}
|
|
13116
|
+
this.synchronizeDependencyCriteriaFromControls();
|
|
13100
13117
|
const term = this.termControl.value || '';
|
|
13101
13118
|
const hasSearchTerm = !!term.trim();
|
|
13102
13119
|
const optionSource = this.optionSource();
|
|
@@ -26985,6 +27002,8 @@ class MaterialSearchableSelectComponent extends SimpleBaseSelectComponent {
|
|
|
26985
27002
|
if (!this.crudService || !this.resourcePath()) {
|
|
26986
27003
|
return;
|
|
26987
27004
|
}
|
|
27005
|
+
this.synchronizeDependencyCriteriaFromControls();
|
|
27006
|
+
criteria = this.filterCriteria();
|
|
26988
27007
|
const optionSource = this.optionSource();
|
|
26989
27008
|
const filter = { ...criteria };
|
|
26990
27009
|
if (searchTerm && !optionSource) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/dynamic-fields",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.83",
|
|
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.
|
|
15
|
-
"@praxisui/cron-builder": "^9.0.0-beta.
|
|
14
|
+
"@praxisui/core": "^9.0.0-beta.83",
|
|
15
|
+
"@praxisui/cron-builder": "^9.0.0-beta.83"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"libphonenumber-js": "^1.12.41",
|
|
@@ -1296,6 +1296,9 @@ declare abstract class SimpleBaseSelectComponent<T = any> extends SimpleBaseInpu
|
|
|
1296
1296
|
protected optionSourceByIdsOptions(): {
|
|
1297
1297
|
filter?: Record<string, unknown>;
|
|
1298
1298
|
} | undefined;
|
|
1299
|
+
/** Keeps every request aligned with the dependency values currently bound to the form. */
|
|
1300
|
+
protected synchronizeDependencyCriteriaFromControls(): void;
|
|
1301
|
+
private applyDependencyValues;
|
|
1299
1302
|
private getByPath;
|
|
1300
1303
|
private setByPath;
|
|
1301
1304
|
private unsetByPath;
|