mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Interactive forms (#5608)
* Fix requery bug in related form field * Fixes for RelatedModelField - Better handling of null values * StockItem form fix - Clear 'supplier_part' field when 'part' field value changes * Add adjustFilters callback function - Allows query filters for a relatedfield to be changed on the fly
This commit is contained in:
parent
2f0dbf9776
commit
7e6db65cac
@ -18,6 +18,8 @@ import { ApiFormProps } from '../ApiForm';
|
||||
import { ChoiceField } from './ChoiceField';
|
||||
import { RelatedModelField } from './RelatedModelField';
|
||||
|
||||
export type ApiFormData = UseFormReturnType<Record<string, unknown>>;
|
||||
|
||||
/**
|
||||
* Callback function type when a form field value changes
|
||||
*/
|
||||
@ -25,7 +27,7 @@ export type ApiFormChangeCallback = {
|
||||
name: string;
|
||||
value: any;
|
||||
field: ApiFormFieldType;
|
||||
form: UseFormReturnType<Record<string, unknown>>;
|
||||
form: ApiFormData;
|
||||
};
|
||||
|
||||
/* Definition of the ApiForm field component.
|
||||
@ -51,6 +53,7 @@ export type ApiFormChangeCallback = {
|
||||
* @param preFieldContent : Content to render before the field
|
||||
* @param postFieldContent : Content to render after the field
|
||||
* @param onValueChange : Callback function to call when the field value changes
|
||||
* @param adjustFilters : Callback function to adjust the filters for a related field before a query is made
|
||||
*/
|
||||
export type ApiFormFieldType = {
|
||||
label?: string;
|
||||
@ -71,6 +74,7 @@ export type ApiFormFieldType = {
|
||||
preFieldContent?: JSX.Element | (() => JSX.Element);
|
||||
postFieldContent?: JSX.Element | (() => JSX.Element);
|
||||
onValueChange?: (change: ApiFormChangeCallback) => void;
|
||||
adjustFilters?: (filters: any, form: ApiFormData) => any;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -55,9 +55,14 @@ export function RelatedModelField({
|
||||
useEffect(() => {
|
||||
// If a value is provided, load the related object
|
||||
if (form.values) {
|
||||
let formPk = form.values[fieldName];
|
||||
let formPk = form.values[fieldName] ?? null;
|
||||
|
||||
if (formPk && formPk != pk) {
|
||||
// If the value is unchanged, do nothing
|
||||
if (formPk == pk) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (formPk != null) {
|
||||
let url = (definition.api_url || '') + formPk + '/';
|
||||
|
||||
// TODO: Fix this!!
|
||||
@ -78,9 +83,11 @@ export function RelatedModelField({
|
||||
setPk(data.pk);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setPk(null);
|
||||
}
|
||||
}
|
||||
}, [form]);
|
||||
}, [form.values[fieldName]]);
|
||||
|
||||
const [offset, setOffset] = useState<number>(0);
|
||||
|
||||
@ -105,8 +112,14 @@ export function RelatedModelField({
|
||||
url = url.substring(4);
|
||||
}
|
||||
|
||||
let filters = definition.filters ?? {};
|
||||
|
||||
if (definition.adjustFilters) {
|
||||
filters = definition.adjustFilters(filters, form);
|
||||
}
|
||||
|
||||
let params = {
|
||||
...definition.filters,
|
||||
...filters,
|
||||
search: searchText,
|
||||
offset: offset,
|
||||
limit: limit
|
||||
@ -173,7 +186,7 @@ export function RelatedModelField({
|
||||
<Input.Wrapper {...definition} error={error}>
|
||||
<Select
|
||||
id={fieldId}
|
||||
value={data.find((item) => item.value == pk)}
|
||||
value={pk != null && data.find((item) => item.value == pk)}
|
||||
options={data}
|
||||
filterOption={null}
|
||||
onInputChange={(value: any) => {
|
||||
@ -183,6 +196,11 @@ export function RelatedModelField({
|
||||
}}
|
||||
onChange={onChange}
|
||||
onMenuScrollToBottom={() => setOffset(offset + limit)}
|
||||
onMenuOpen={() => {
|
||||
setValue('');
|
||||
setOffset(0);
|
||||
selectQuery.refetch();
|
||||
}}
|
||||
isLoading={
|
||||
selectQuery.isFetching ||
|
||||
selectQuery.isLoading ||
|
||||
|
@ -2,6 +2,7 @@ import { t } from '@lingui/macro';
|
||||
|
||||
import {
|
||||
ApiFormChangeCallback,
|
||||
ApiFormData,
|
||||
ApiFormFieldSet,
|
||||
ApiFormFieldType
|
||||
} from '../../components/forms/fields/ApiFormField';
|
||||
@ -14,8 +15,13 @@ export function stockFields({}: {}): ApiFormFieldSet {
|
||||
let fields: ApiFormFieldSet = {
|
||||
part: {
|
||||
onValueChange: (change: ApiFormChangeCallback) => {
|
||||
// TODO: implement this
|
||||
// TODO: implement remaining functionality from old stock.py
|
||||
console.log('part changed: ', change.value);
|
||||
|
||||
// Clear the 'supplier_part' field if the part is changed
|
||||
change.form.setValues({
|
||||
supplier_part: null
|
||||
});
|
||||
}
|
||||
},
|
||||
supplier_part: {
|
||||
@ -24,6 +30,14 @@ export function stockFields({}: {}): ApiFormFieldSet {
|
||||
filters: {
|
||||
part_detail: true,
|
||||
supplier_detail: true
|
||||
},
|
||||
adjustFilters: (filters: any, form: ApiFormData) => {
|
||||
let part = form.values.part;
|
||||
if (part) {
|
||||
filters.part = part;
|
||||
}
|
||||
|
||||
return filters;
|
||||
}
|
||||
},
|
||||
use_pack_size: {
|
||||
|
Loading…
Reference in New Issue
Block a user