mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[React] Improvements to API forms (#5742)
* Remove read_only field from API OPTIONS - 'read_only' is a reserved field for some Mantine components * Fixing further errors for related field model * Handle bad values for numericalValue * Fix for default values for API forms * Fix for choice field - Do not set form default value when constructing element * Tweak for PartDetail page
This commit is contained in:
parent
cb33705e44
commit
3349013646
@ -136,13 +136,19 @@ export function ApiForm({
|
||||
useEffect(() => {
|
||||
// Provide initial form data
|
||||
Object.entries(props.fields ?? {}).forEach(([fieldName, field]) => {
|
||||
if (field.value !== undefined) {
|
||||
// fieldDefinition is supplied by the API, and can serve as a backup
|
||||
let fieldDefinition = fieldDefinitions[fieldName] ?? {};
|
||||
|
||||
let v =
|
||||
field.value ??
|
||||
field.default ??
|
||||
fieldDefinition.value ??
|
||||
fieldDefinition.default ??
|
||||
undefined;
|
||||
|
||||
if (v !== undefined) {
|
||||
form.setValues({
|
||||
[fieldName]: field.value
|
||||
});
|
||||
} else if (field.default !== undefined) {
|
||||
form.setValues({
|
||||
[fieldName]: field.default
|
||||
[fieldName]: v
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -68,6 +68,7 @@ export type ApiFormFieldType = {
|
||||
choices?: any[];
|
||||
hidden?: boolean;
|
||||
disabled?: boolean;
|
||||
read_only?: boolean;
|
||||
placeholder?: string;
|
||||
description?: string;
|
||||
preFieldContent?: JSX.Element | (() => JSX.Element);
|
||||
@ -115,6 +116,10 @@ export function constructField({
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear out the 'read_only' attribute
|
||||
def.disabled = def.disabled ?? def.read_only ?? false;
|
||||
delete def['read_only'];
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
@ -190,16 +195,26 @@ export function ApiFormField({
|
||||
|
||||
// Coerce the value to a numerical value
|
||||
const numericalValue: number | undefined = useMemo(() => {
|
||||
let val = 0;
|
||||
|
||||
switch (definition.field_type) {
|
||||
case 'integer':
|
||||
return parseInt(value);
|
||||
val = parseInt(value) ?? 0;
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'float':
|
||||
case 'number':
|
||||
return parseFloat(value);
|
||||
val = parseFloat(value) ?? 0;
|
||||
break;
|
||||
default:
|
||||
return undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isNaN(val) || !isFinite(val)) {
|
||||
val = 0;
|
||||
}
|
||||
|
||||
return val;
|
||||
}, [value]);
|
||||
|
||||
// Construct the individual field
|
||||
|
@ -34,8 +34,6 @@ export function ChoiceField({
|
||||
definitions: definitions
|
||||
});
|
||||
|
||||
form.setValues({ [fieldName]: def.value ?? def.default });
|
||||
|
||||
return def;
|
||||
}, [fieldName, field, definitions]);
|
||||
|
||||
|
@ -37,16 +37,18 @@ export function RelatedModelField({
|
||||
|
||||
// Extract field definition from provided data
|
||||
// Where user has provided specific data, override the API definition
|
||||
const definition: ApiFormFieldType = useMemo(
|
||||
() =>
|
||||
constructField({
|
||||
form: form,
|
||||
field: field,
|
||||
fieldName: fieldName,
|
||||
definitions: definitions
|
||||
}),
|
||||
[form.values, field, definitions]
|
||||
);
|
||||
const definition: ApiFormFieldType = useMemo(() => {
|
||||
let def = constructField({
|
||||
form: form,
|
||||
field: field,
|
||||
fieldName: fieldName,
|
||||
definitions: definitions
|
||||
});
|
||||
|
||||
// Remove the 'read_only' attribute (causes issues with Mantine)
|
||||
delete def['read_only'];
|
||||
return def;
|
||||
}, [form.values, field, definitions]);
|
||||
|
||||
// Keep track of the primary key value for this field
|
||||
const [pk, setPk] = useState<number | null>(null);
|
||||
@ -170,8 +172,20 @@ export function RelatedModelField({
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct a "cut-down" version of the definition,
|
||||
* which does not include any attributes that the lower components do not recognize
|
||||
*/
|
||||
const fieldDefinition = useMemo(() => {
|
||||
return {
|
||||
...definition,
|
||||
onValueChange: undefined,
|
||||
adjustFilters: undefined,
|
||||
read_only: undefined
|
||||
};
|
||||
}, [definition]);
|
||||
|
||||
return (
|
||||
<Input.Wrapper {...definition} error={error}>
|
||||
<Input.Wrapper {...fieldDefinition} error={error}>
|
||||
<Select
|
||||
id={fieldId}
|
||||
value={pk != null && data.find((item) => item.value == pk)}
|
||||
|
@ -69,8 +69,12 @@ export function extractAvailableFields(
|
||||
name: fieldName,
|
||||
field_type: field.type,
|
||||
description: field.help_text,
|
||||
value: field.value ?? field.default
|
||||
value: field.value ?? field.default,
|
||||
disabled: field.read_only ?? false
|
||||
};
|
||||
|
||||
// Remove the 'read_only' field - plays havoc with react components
|
||||
delete fields['read_only'];
|
||||
}
|
||||
|
||||
return fields;
|
||||
|
@ -180,7 +180,7 @@ export default function PartDetail() {
|
||||
)
|
||||
}
|
||||
];
|
||||
}, [part]);
|
||||
}, [id, part]);
|
||||
|
||||
const breadcrumbs = useMemo(
|
||||
() => [
|
||||
|
Loading…
Reference in New Issue
Block a user