@nubitio/crud 0.4.0 → 0.5.0
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/dist/index.cjs +21 -13
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +21 -13
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -597,10 +597,12 @@ function serializeDateField(formData, field) {
|
|
|
597
597
|
}
|
|
598
598
|
function serializeNumericField(formData, field) {
|
|
599
599
|
if (field.isIdentity) return;
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
formData[field.name]
|
|
603
|
-
|
|
600
|
+
const val = formData[field.name];
|
|
601
|
+
if (val === null || val === void 0 || val === "") {
|
|
602
|
+
delete formData[field.name];
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
formData[field.name] = field.sendAsString ? Number(val).toFixed(field.precision || 2) : Number(val);
|
|
604
606
|
}
|
|
605
607
|
/**
|
|
606
608
|
* Serializes detail grid rows (entity refs, numeric coercion, identity cleanup).
|
|
@@ -615,10 +617,12 @@ function serializeDetailRows(rows, detailFields, detailIdField, isEditMode, adap
|
|
|
615
617
|
else detail[field.name] = serialized;
|
|
616
618
|
});
|
|
617
619
|
if (field.type === "number" || field.type === "currency") details.forEach((detail) => {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
detail[field.name]
|
|
621
|
-
|
|
620
|
+
const val = detail[field.name];
|
|
621
|
+
if (val === null || val === void 0 || val === "") {
|
|
622
|
+
delete detail[field.name];
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
detail[field.name] = field.sendAsString ? Number(val).toFixed(field.precision || 2) : Number(val);
|
|
622
626
|
});
|
|
623
627
|
});
|
|
624
628
|
details.forEach((detail) => {
|
|
@@ -6908,20 +6912,22 @@ function ResourceSchemaProvider({ children, resolver }) {
|
|
|
6908
6912
|
children
|
|
6909
6913
|
});
|
|
6910
6914
|
}
|
|
6911
|
-
function resolveWithRuntimeErrors(resolver, supportedOperations = []) {
|
|
6915
|
+
function resolveWithRuntimeErrors(resolver, supportedOperations = [], formLayout) {
|
|
6912
6916
|
try {
|
|
6913
6917
|
return {
|
|
6914
6918
|
fields: resolver(),
|
|
6915
6919
|
isLoading: false,
|
|
6916
6920
|
error: void 0,
|
|
6917
|
-
supportedOperations
|
|
6921
|
+
supportedOperations,
|
|
6922
|
+
formLayout
|
|
6918
6923
|
};
|
|
6919
6924
|
} catch (runtimeError) {
|
|
6920
6925
|
return {
|
|
6921
6926
|
fields: [],
|
|
6922
6927
|
isLoading: false,
|
|
6923
6928
|
error: runtimeError instanceof Error ? runtimeError : new Error(String(runtimeError)),
|
|
6924
|
-
supportedOperations
|
|
6929
|
+
supportedOperations,
|
|
6930
|
+
formLayout
|
|
6925
6931
|
};
|
|
6926
6932
|
}
|
|
6927
6933
|
}
|
|
@@ -6947,7 +6953,7 @@ function useResolvedResourceFields({ apiUrl, manualFields, overrides, fieldContr
|
|
|
6947
6953
|
baselineFields: baseline.fields,
|
|
6948
6954
|
contract: fieldContract,
|
|
6949
6955
|
legacyOverrides: fieldContract ? void 0 : overrides
|
|
6950
|
-
}), baseline.supportedOperations);
|
|
6956
|
+
}), baseline.supportedOperations, baseline.formLayout);
|
|
6951
6957
|
}, [
|
|
6952
6958
|
baseline,
|
|
6953
6959
|
fieldContract,
|
|
@@ -7027,7 +7033,7 @@ function SmartCrudPage({ resource, fieldOverrides, formRef, onSelectionChanged,
|
|
|
7027
7033
|
const effectiveGridRef = gridRef ?? internalGridRef;
|
|
7028
7034
|
const resolvedBaseResource = (0, react.useMemo)(() => resolveCrudResource(resource), [resource]);
|
|
7029
7035
|
const hasManualFields = !resource.fieldContract && Array.isArray(resource.fields) && resource.fields.length > 0;
|
|
7030
|
-
const { fields, isLoading, error, supportedOperations } = useResolvedResourceFields({
|
|
7036
|
+
const { fields, isLoading, error, supportedOperations, formLayout: inferredFormLayout } = useResolvedResourceFields({
|
|
7031
7037
|
apiUrl: resolvedBaseResource.apiUrl,
|
|
7032
7038
|
manualFields: hasManualFields ? buildFields(resource.fields) : void 0,
|
|
7033
7039
|
overrides: hasManualFields ? void 0 : fieldOverrides,
|
|
@@ -7062,11 +7068,13 @@ function SmartCrudPage({ resource, fieldOverrides, formRef, onSelectionChanged,
|
|
|
7062
7068
|
apiUrl: normalizedApiUrl,
|
|
7063
7069
|
fields: hasManualFields ? buildFields(resource.fields) : gridFields,
|
|
7064
7070
|
formFields: processedFields,
|
|
7071
|
+
formLayout: resolvedBaseResource.formLayout ?? inferredFormLayout,
|
|
7065
7072
|
_supportedOperations: supportedOperations
|
|
7066
7073
|
}), [
|
|
7067
7074
|
fields,
|
|
7068
7075
|
gridFields,
|
|
7069
7076
|
hasManualFields,
|
|
7077
|
+
inferredFormLayout,
|
|
7070
7078
|
normalizedApiUrl,
|
|
7071
7079
|
processedFields,
|
|
7072
7080
|
resolvedBaseResource,
|
package/dist/index.d.cts
CHANGED
|
@@ -1871,6 +1871,11 @@ interface ResourceSchemaResolution {
|
|
|
1871
1871
|
isLoading: boolean;
|
|
1872
1872
|
error: Error | undefined;
|
|
1873
1873
|
supportedOperations: string[];
|
|
1874
|
+
/**
|
|
1875
|
+
* Backend-declared form layout (sections/tabs) from the API doc, when the
|
|
1876
|
+
* resource publishes one. Explicit `ResourceConfig.formLayout` wins.
|
|
1877
|
+
*/
|
|
1878
|
+
formLayout?: FormLayout;
|
|
1874
1879
|
}
|
|
1875
1880
|
interface ResourceSchemaResolver {
|
|
1876
1881
|
useResourceSchema(request: ResourceSchemaRequest): ResourceSchemaResolution;
|
package/dist/index.d.mts
CHANGED
|
@@ -1871,6 +1871,11 @@ interface ResourceSchemaResolution {
|
|
|
1871
1871
|
isLoading: boolean;
|
|
1872
1872
|
error: Error | undefined;
|
|
1873
1873
|
supportedOperations: string[];
|
|
1874
|
+
/**
|
|
1875
|
+
* Backend-declared form layout (sections/tabs) from the API doc, when the
|
|
1876
|
+
* resource publishes one. Explicit `ResourceConfig.formLayout` wins.
|
|
1877
|
+
*/
|
|
1878
|
+
formLayout?: FormLayout;
|
|
1874
1879
|
}
|
|
1875
1880
|
interface ResourceSchemaResolver {
|
|
1876
1881
|
useResourceSchema(request: ResourceSchemaRequest): ResourceSchemaResolution;
|
package/dist/index.mjs
CHANGED
|
@@ -573,10 +573,12 @@ function serializeDateField(formData, field) {
|
|
|
573
573
|
}
|
|
574
574
|
function serializeNumericField(formData, field) {
|
|
575
575
|
if (field.isIdentity) return;
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
formData[field.name]
|
|
579
|
-
|
|
576
|
+
const val = formData[field.name];
|
|
577
|
+
if (val === null || val === void 0 || val === "") {
|
|
578
|
+
delete formData[field.name];
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
formData[field.name] = field.sendAsString ? Number(val).toFixed(field.precision || 2) : Number(val);
|
|
580
582
|
}
|
|
581
583
|
/**
|
|
582
584
|
* Serializes detail grid rows (entity refs, numeric coercion, identity cleanup).
|
|
@@ -591,10 +593,12 @@ function serializeDetailRows(rows, detailFields, detailIdField, isEditMode, adap
|
|
|
591
593
|
else detail[field.name] = serialized;
|
|
592
594
|
});
|
|
593
595
|
if (field.type === "number" || field.type === "currency") details.forEach((detail) => {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
detail[field.name]
|
|
597
|
-
|
|
596
|
+
const val = detail[field.name];
|
|
597
|
+
if (val === null || val === void 0 || val === "") {
|
|
598
|
+
delete detail[field.name];
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
detail[field.name] = field.sendAsString ? Number(val).toFixed(field.precision || 2) : Number(val);
|
|
598
602
|
});
|
|
599
603
|
});
|
|
600
604
|
details.forEach((detail) => {
|
|
@@ -6884,20 +6888,22 @@ function ResourceSchemaProvider({ children, resolver }) {
|
|
|
6884
6888
|
children
|
|
6885
6889
|
});
|
|
6886
6890
|
}
|
|
6887
|
-
function resolveWithRuntimeErrors(resolver, supportedOperations = []) {
|
|
6891
|
+
function resolveWithRuntimeErrors(resolver, supportedOperations = [], formLayout) {
|
|
6888
6892
|
try {
|
|
6889
6893
|
return {
|
|
6890
6894
|
fields: resolver(),
|
|
6891
6895
|
isLoading: false,
|
|
6892
6896
|
error: void 0,
|
|
6893
|
-
supportedOperations
|
|
6897
|
+
supportedOperations,
|
|
6898
|
+
formLayout
|
|
6894
6899
|
};
|
|
6895
6900
|
} catch (runtimeError) {
|
|
6896
6901
|
return {
|
|
6897
6902
|
fields: [],
|
|
6898
6903
|
isLoading: false,
|
|
6899
6904
|
error: runtimeError instanceof Error ? runtimeError : new Error(String(runtimeError)),
|
|
6900
|
-
supportedOperations
|
|
6905
|
+
supportedOperations,
|
|
6906
|
+
formLayout
|
|
6901
6907
|
};
|
|
6902
6908
|
}
|
|
6903
6909
|
}
|
|
@@ -6923,7 +6929,7 @@ function useResolvedResourceFields({ apiUrl, manualFields, overrides, fieldContr
|
|
|
6923
6929
|
baselineFields: baseline.fields,
|
|
6924
6930
|
contract: fieldContract,
|
|
6925
6931
|
legacyOverrides: fieldContract ? void 0 : overrides
|
|
6926
|
-
}), baseline.supportedOperations);
|
|
6932
|
+
}), baseline.supportedOperations, baseline.formLayout);
|
|
6927
6933
|
}, [
|
|
6928
6934
|
baseline,
|
|
6929
6935
|
fieldContract,
|
|
@@ -7003,7 +7009,7 @@ function SmartCrudPage({ resource, fieldOverrides, formRef, onSelectionChanged,
|
|
|
7003
7009
|
const effectiveGridRef = gridRef ?? internalGridRef;
|
|
7004
7010
|
const resolvedBaseResource = useMemo(() => resolveCrudResource(resource), [resource]);
|
|
7005
7011
|
const hasManualFields = !resource.fieldContract && Array.isArray(resource.fields) && resource.fields.length > 0;
|
|
7006
|
-
const { fields, isLoading, error, supportedOperations } = useResolvedResourceFields({
|
|
7012
|
+
const { fields, isLoading, error, supportedOperations, formLayout: inferredFormLayout } = useResolvedResourceFields({
|
|
7007
7013
|
apiUrl: resolvedBaseResource.apiUrl,
|
|
7008
7014
|
manualFields: hasManualFields ? buildFields(resource.fields) : void 0,
|
|
7009
7015
|
overrides: hasManualFields ? void 0 : fieldOverrides,
|
|
@@ -7038,11 +7044,13 @@ function SmartCrudPage({ resource, fieldOverrides, formRef, onSelectionChanged,
|
|
|
7038
7044
|
apiUrl: normalizedApiUrl,
|
|
7039
7045
|
fields: hasManualFields ? buildFields(resource.fields) : gridFields,
|
|
7040
7046
|
formFields: processedFields,
|
|
7047
|
+
formLayout: resolvedBaseResource.formLayout ?? inferredFormLayout,
|
|
7041
7048
|
_supportedOperations: supportedOperations
|
|
7042
7049
|
}), [
|
|
7043
7050
|
fields,
|
|
7044
7051
|
gridFields,
|
|
7045
7052
|
hasManualFields,
|
|
7053
|
+
inferredFormLayout,
|
|
7046
7054
|
normalizedApiUrl,
|
|
7047
7055
|
processedFields,
|
|
7048
7056
|
resolvedBaseResource,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nubitio/crud",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Declarative CRUD engine with field DSL, forms, datagrids, RBAC, conditional logic and pluggable adapters (Hydra/REST).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"react-dom": "^19.0.0",
|
|
57
57
|
"react-i18next": "^14.0.0",
|
|
58
58
|
"react-router-dom": "^6.0.0",
|
|
59
|
-
"@nubitio/
|
|
60
|
-
"@nubitio/
|
|
59
|
+
"@nubitio/ui": "^0.5.0",
|
|
60
|
+
"@nubitio/core": "^0.5.0"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"react-dropzone": "^15.0.0"
|