@praxisui/crud 10.0.0-rc.22 → 10.0.0-rc.24
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-10-
|
|
3
|
+
"generatedAt": "2026-10-15T13:55:17.858Z",
|
|
4
4
|
"packageName": "@praxisui/crud",
|
|
5
|
-
"packageVersion": "10.0.0-rc.
|
|
5
|
+
"packageVersion": "10.0.0-rc.24",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 2,
|
|
@@ -3811,7 +3811,10 @@ function validateCrudKpiBand(metadata, diagnostics) {
|
|
|
3811
3811
|
diagnostics.push(errorDiagnostic('crud.metadata.kpiBand.cards.value.required', `KPI card #${index + 1} requires a displayed value`, `metadata.kpiBand.cards.${index}.value`));
|
|
3812
3812
|
}
|
|
3813
3813
|
if (card?.filter !== undefined &&
|
|
3814
|
-
(!card.filter ||
|
|
3814
|
+
(!card.filter ||
|
|
3815
|
+
typeof card.filter !== 'object' ||
|
|
3816
|
+
Array.isArray(card.filter) ||
|
|
3817
|
+
Object.keys(card.filter).some((key) => !trimString(key)))) {
|
|
3815
3818
|
diagnostics.push(errorDiagnostic('crud.metadata.kpiBand.cards.filter.invalid', `KPI card #${index + 1} filter must be a valid criteria object`, `metadata.kpiBand.cards.${index}.filter`));
|
|
3816
3819
|
}
|
|
3817
3820
|
});
|
|
@@ -3832,8 +3835,11 @@ function validateCrudFilterBar(metadata, diagnostics) {
|
|
|
3832
3835
|
const filterVal = qf?.filter;
|
|
3833
3836
|
const isInvalidFilter = filterVal === undefined ||
|
|
3834
3837
|
filterVal === null ||
|
|
3838
|
+
(typeof filterVal === 'string' && !filterVal.trim()) ||
|
|
3835
3839
|
(typeof filterVal !== 'string' &&
|
|
3836
|
-
(typeof filterVal !== 'object' ||
|
|
3840
|
+
(typeof filterVal !== 'object' ||
|
|
3841
|
+
Array.isArray(filterVal) ||
|
|
3842
|
+
Object.keys(filterVal).some((key) => !trimString(key))));
|
|
3837
3843
|
if (isInvalidFilter) {
|
|
3838
3844
|
diagnostics.push(errorDiagnostic('crud.metadata.filterBar.quickFilters.filter.invalid', `Quick filter #${index + 1} requires a valid filter condition`, `metadata.filterBar.quickFilters.${index}.filter`));
|
|
3839
3845
|
}
|
|
@@ -5164,6 +5170,7 @@ class CrudMetadataEditorComponent {
|
|
|
5164
5170
|
// Observe the supplied snapshot with its external resource, before local edits.
|
|
5165
5171
|
this.providedSnapshotOwner();
|
|
5166
5172
|
this.synchronizeSchemaScope();
|
|
5173
|
+
this.initialValueDrafts.set({});
|
|
5167
5174
|
this.kpiFilterJsonDrafts.set({});
|
|
5168
5175
|
this.quickFilterExpressionDrafts.set({});
|
|
5169
5176
|
this.syncState();
|
|
@@ -5292,9 +5299,9 @@ class CrudMetadataEditorComponent {
|
|
|
5292
5299
|
else {
|
|
5293
5300
|
parts.push(this.tx('crud.authoring.action.paramsNone', 'No param mappings yet'));
|
|
5294
5301
|
}
|
|
5295
|
-
const
|
|
5302
|
+
const hasInvalidDraft = this.initialValueDrafts()[actionName] !== undefined;
|
|
5296
5303
|
const hasInitialValue = !!this.actionValue(actionName).form?.initialValue;
|
|
5297
|
-
if (
|
|
5304
|
+
if (hasInvalidDraft) {
|
|
5298
5305
|
parts.push(this.tx('crud.authoring.action.initialValueInvalid', 'Initial value JSON is not valid yet'));
|
|
5299
5306
|
}
|
|
5300
5307
|
else if (hasInitialValue) {
|
|
@@ -5313,9 +5320,9 @@ class CrudMetadataEditorComponent {
|
|
|
5313
5320
|
return this.tx('crud.authoring.action.paramsNoteReady', 'Mappings ready');
|
|
5314
5321
|
}
|
|
5315
5322
|
actionInitialValueNote(actionName) {
|
|
5316
|
-
const
|
|
5323
|
+
const hasInvalidDraft = this.initialValueDrafts()[actionName] !== undefined;
|
|
5317
5324
|
const hasInitialValue = !!this.actionValue(actionName).form?.initialValue;
|
|
5318
|
-
if (
|
|
5325
|
+
if (hasInvalidDraft) {
|
|
5319
5326
|
return this.tx('crud.authoring.action.initialValueInvalid', 'Initial value JSON is not valid yet');
|
|
5320
5327
|
}
|
|
5321
5328
|
if (hasInitialValue) {
|
|
@@ -5492,6 +5499,9 @@ class CrudMetadataEditorComponent {
|
|
|
5492
5499
|
if (diagnosticPaths.some((issue) => issue.level === 'error')) {
|
|
5493
5500
|
return 'invalid';
|
|
5494
5501
|
}
|
|
5502
|
+
if (this.initialValueDrafts()[actionName] !== undefined) {
|
|
5503
|
+
return 'invalid';
|
|
5504
|
+
}
|
|
5495
5505
|
const action = this.actionValue(actionName);
|
|
5496
5506
|
const effectiveMode = (action.openMode || this.defaultsOpenMode());
|
|
5497
5507
|
const hasBinding = effectiveMode === 'route'
|
|
@@ -5797,6 +5807,13 @@ class CrudMetadataEditorComponent {
|
|
|
5797
5807
|
if (section === 'kpis' && Object.keys(this.kpiFilterJsonDrafts()).length > 0) {
|
|
5798
5808
|
return 'invalid';
|
|
5799
5809
|
}
|
|
5810
|
+
if (section === 'filters' && this.hasInvalidQuickFilterDraft()) {
|
|
5811
|
+
return 'invalid';
|
|
5812
|
+
}
|
|
5813
|
+
if (section === 'actions' &&
|
|
5814
|
+
this.actionKeys.some((actionName) => this.actionStatus(actionName) === 'invalid')) {
|
|
5815
|
+
return 'invalid';
|
|
5816
|
+
}
|
|
5800
5817
|
if (diagnostics.some((issue) => issue.level === 'warning')) {
|
|
5801
5818
|
return 'pending';
|
|
5802
5819
|
}
|
|
@@ -6393,7 +6410,7 @@ class CrudMetadataEditorComponent {
|
|
|
6393
6410
|
[index]: raw,
|
|
6394
6411
|
}));
|
|
6395
6412
|
const trimmed = String(raw || '').trim();
|
|
6396
|
-
if (trimmed.startsWith('{')) {
|
|
6413
|
+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
6397
6414
|
try {
|
|
6398
6415
|
const parsed = JSON.parse(trimmed);
|
|
6399
6416
|
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
@@ -6405,8 +6422,10 @@ class CrudMetadataEditorComponent {
|
|
|
6405
6422
|
}
|
|
6406
6423
|
}
|
|
6407
6424
|
catch {
|
|
6408
|
-
//
|
|
6425
|
+
// Keep malformed JSON draft in signal so sectionStatus('filters') surfaces 'invalid'
|
|
6409
6426
|
}
|
|
6427
|
+
this.syncState();
|
|
6428
|
+
return;
|
|
6410
6429
|
}
|
|
6411
6430
|
this.patchQuickFilter(index, (qf) => ({
|
|
6412
6431
|
...qf,
|
|
@@ -6558,12 +6577,9 @@ class CrudMetadataEditorComponent {
|
|
|
6558
6577
|
});
|
|
6559
6578
|
}
|
|
6560
6579
|
setActionInitialValue(actionName, raw) {
|
|
6561
|
-
this.initialValueDrafts.update((drafts) => ({
|
|
6562
|
-
...drafts,
|
|
6563
|
-
[actionName]: raw,
|
|
6564
|
-
}));
|
|
6565
6580
|
const trimmed = raw.trim();
|
|
6566
6581
|
if (!trimmed) {
|
|
6582
|
+
this.clearActionInitialValueDraft(actionName);
|
|
6567
6583
|
this.patchAction(actionName, (action) => ({
|
|
6568
6584
|
...action,
|
|
6569
6585
|
form: {
|
|
@@ -6575,20 +6591,26 @@ class CrudMetadataEditorComponent {
|
|
|
6575
6591
|
}
|
|
6576
6592
|
try {
|
|
6577
6593
|
const parsed = JSON.parse(trimmed);
|
|
6578
|
-
if (
|
|
6594
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
6595
|
+
this.clearActionInitialValueDraft(actionName);
|
|
6596
|
+
this.patchAction(actionName, (action) => ({
|
|
6597
|
+
...action,
|
|
6598
|
+
form: {
|
|
6599
|
+
...(action.form || {}),
|
|
6600
|
+
initialValue: parsed,
|
|
6601
|
+
},
|
|
6602
|
+
}));
|
|
6579
6603
|
return;
|
|
6580
6604
|
}
|
|
6581
|
-
this.patchAction(actionName, (action) => ({
|
|
6582
|
-
...action,
|
|
6583
|
-
form: {
|
|
6584
|
-
...(action.form || {}),
|
|
6585
|
-
initialValue: parsed,
|
|
6586
|
-
},
|
|
6587
|
-
}));
|
|
6588
6605
|
}
|
|
6589
6606
|
catch {
|
|
6590
|
-
|
|
6607
|
+
// Keep invalid draft in signal so actionStatus and sectionStatus('actions') surface 'invalid'
|
|
6591
6608
|
}
|
|
6609
|
+
this.initialValueDrafts.update((drafts) => ({
|
|
6610
|
+
...drafts,
|
|
6611
|
+
[actionName]: raw,
|
|
6612
|
+
}));
|
|
6613
|
+
this.syncState();
|
|
6592
6614
|
}
|
|
6593
6615
|
setActionBackField(actionName, field, value) {
|
|
6594
6616
|
this.patchAction(actionName, (action) => ({
|
|
@@ -6666,6 +6688,31 @@ class CrudMetadataEditorComponent {
|
|
|
6666
6688
|
return next;
|
|
6667
6689
|
});
|
|
6668
6690
|
}
|
|
6691
|
+
clearActionInitialValueDraft(actionName) {
|
|
6692
|
+
if (this.initialValueDrafts()[actionName] === undefined) {
|
|
6693
|
+
return;
|
|
6694
|
+
}
|
|
6695
|
+
this.initialValueDrafts.update((drafts) => {
|
|
6696
|
+
const next = { ...drafts };
|
|
6697
|
+
delete next[actionName];
|
|
6698
|
+
return next;
|
|
6699
|
+
});
|
|
6700
|
+
}
|
|
6701
|
+
hasInvalidQuickFilterDraft() {
|
|
6702
|
+
return Object.values(this.quickFilterExpressionDrafts()).some((raw) => {
|
|
6703
|
+
const trimmed = String(raw ?? '').trim();
|
|
6704
|
+
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
|
|
6705
|
+
return false;
|
|
6706
|
+
}
|
|
6707
|
+
try {
|
|
6708
|
+
const parsed = JSON.parse(trimmed);
|
|
6709
|
+
return !parsed || typeof parsed !== 'object' || Array.isArray(parsed);
|
|
6710
|
+
}
|
|
6711
|
+
catch {
|
|
6712
|
+
return true;
|
|
6713
|
+
}
|
|
6714
|
+
});
|
|
6715
|
+
}
|
|
6669
6716
|
updateFilterBar(updater) {
|
|
6670
6717
|
this.updateMetadata((metadata) => {
|
|
6671
6718
|
const base = this.effectiveFilterBar() || {};
|
|
@@ -6808,10 +6855,12 @@ class CrudMetadataEditorComponent {
|
|
|
6808
6855
|
syncState() {
|
|
6809
6856
|
const currentSignature = JSON.stringify(serializeCrudAuthoringDocument(this.currentDocument()));
|
|
6810
6857
|
const initialSignature = JSON.stringify(serializeCrudAuthoringDocument(this.initialDocument()));
|
|
6811
|
-
const
|
|
6812
|
-
|
|
6858
|
+
const hasInvalidDraft = Object.keys(this.kpiFilterJsonDrafts()).length > 0 ||
|
|
6859
|
+
this.hasInvalidQuickFilterDraft() ||
|
|
6860
|
+
Object.keys(this.initialValueDrafts()).length > 0;
|
|
6861
|
+
this.isDirty$.next(currentSignature !== initialSignature || hasInvalidDraft);
|
|
6813
6862
|
const hasErrorDiagnostics = this.diagnostics().some((issue) => issue.level === 'error');
|
|
6814
|
-
this.isValid$.next(!hasErrorDiagnostics && !
|
|
6863
|
+
this.isValid$.next(!hasErrorDiagnostics && !hasInvalidDraft);
|
|
6815
6864
|
}
|
|
6816
6865
|
tx(key, fallback) {
|
|
6817
6866
|
return translateCrudAuthoringText(this.i18n, key, fallback);
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/crud",
|
|
3
|
-
"version": "10.0.0-rc.
|
|
3
|
+
"version": "10.0.0-rc.24",
|
|
4
4
|
"description": "CRUD building blocks for Praxis UI: integrates dynamic forms and tables with unified configuration and services.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
8
|
-
"@praxisui/dynamic-form": "^10.0.0-rc.
|
|
9
|
-
"@praxisui/table": "^10.0.0-rc.
|
|
10
|
-
"@praxisui/core": "^10.0.0-rc.
|
|
11
|
-
"@praxisui/dynamic-fields": "^10.0.0-rc.
|
|
12
|
-
"@praxisui/settings-panel": "^10.0.0-rc.
|
|
8
|
+
"@praxisui/dynamic-form": "^10.0.0-rc.24",
|
|
9
|
+
"@praxisui/table": "^10.0.0-rc.24",
|
|
10
|
+
"@praxisui/core": "^10.0.0-rc.24",
|
|
11
|
+
"@praxisui/dynamic-fields": "^10.0.0-rc.24",
|
|
12
|
+
"@praxisui/settings-panel": "^10.0.0-rc.24",
|
|
13
13
|
"@angular/cdk": "^21.0.0",
|
|
14
14
|
"@angular/forms": "^21.0.0",
|
|
15
15
|
"@angular/material": "^21.0.0",
|
|
16
16
|
"@angular/router": "^21.0.0",
|
|
17
|
-
"@praxisui/ai": "^10.0.0-rc.
|
|
17
|
+
"@praxisui/ai": "^10.0.0-rc.24",
|
|
18
18
|
"rxjs": "~7.8.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
package/types/praxisui-crud.d.ts
CHANGED
|
@@ -996,6 +996,8 @@ declare class CrudMetadataEditorComponent implements SettingsValueProvider {
|
|
|
996
996
|
private updateKpiBand;
|
|
997
997
|
private patchKpiCard;
|
|
998
998
|
private clearKpiFilterJsonDraft;
|
|
999
|
+
private clearActionInitialValueDraft;
|
|
1000
|
+
private hasInvalidQuickFilterDraft;
|
|
999
1001
|
private updateFilterBar;
|
|
1000
1002
|
private patchQuickFilter;
|
|
1001
1003
|
private resourceSchemaIdentity;
|