mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-03 22:55:43 +00:00 
			
		
		
		
	Use form state to update values
This commit is contained in:
		@@ -9,7 +9,7 @@ import {
 | 
				
			|||||||
  TextInput
 | 
					  TextInput
 | 
				
			||||||
} from '@mantine/core';
 | 
					} from '@mantine/core';
 | 
				
			||||||
import { Button, Center, Group, Loader, Stack, Text } from '@mantine/core';
 | 
					import { Button, Center, Group, Loader, Stack, Text } from '@mantine/core';
 | 
				
			||||||
import { useForm } from '@mantine/form';
 | 
					import { UseFormReturnType, useForm } from '@mantine/form';
 | 
				
			||||||
import { IconAlertCircle } from '@tabler/icons-react';
 | 
					import { IconAlertCircle } from '@tabler/icons-react';
 | 
				
			||||||
import { useQuery } from '@tanstack/react-query';
 | 
					import { useQuery } from '@tanstack/react-query';
 | 
				
			||||||
import { AxiosResponse } from 'axios';
 | 
					import { AxiosResponse } from 'axios';
 | 
				
			||||||
@@ -42,10 +42,12 @@ export type ApiFormFieldType = {
 | 
				
			|||||||
 * Render an individual form field
 | 
					 * Render an individual form field
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function ApiFormField({
 | 
					function ApiFormField({
 | 
				
			||||||
 | 
					  form,
 | 
				
			||||||
  field,
 | 
					  field,
 | 
				
			||||||
  definitions,
 | 
					  definitions,
 | 
				
			||||||
  onValueChange
 | 
					  onValueChange
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
 | 
					  form: UseFormReturnType<Record<string, unknown>>;
 | 
				
			||||||
  field: ApiFormFieldType;
 | 
					  field: ApiFormFieldType;
 | 
				
			||||||
  definitions: ApiFormFieldType[];
 | 
					  definitions: ApiFormFieldType[];
 | 
				
			||||||
  onValueChange: (fieldName: string, value: any) => void;
 | 
					  onValueChange: (fieldName: string, value: any) => void;
 | 
				
			||||||
@@ -63,6 +65,17 @@ function ApiFormField({
 | 
				
			|||||||
    // Format the errors
 | 
					    // Format the errors
 | 
				
			||||||
    if (def.errors?.length == 1) {
 | 
					    if (def.errors?.length == 1) {
 | 
				
			||||||
      def.error = def.errors[0];
 | 
					      def.error = def.errors[0];
 | 
				
			||||||
 | 
					    } else if (def.errors?.length ?? 0 > 1) {
 | 
				
			||||||
 | 
					      // TODO: Build a custom error stack?
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      def.error = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Retrieve the latest value from the form
 | 
				
			||||||
 | 
					    let value = form.values[def.name];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (value != undefined) {
 | 
				
			||||||
 | 
					      def.value = value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return def;
 | 
					    return def;
 | 
				
			||||||
@@ -70,7 +83,8 @@ function ApiFormField({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Callback helper when form value changes
 | 
					  // Callback helper when form value changes
 | 
				
			||||||
  function onChange(value: any) {
 | 
					  function onChange(value: any) {
 | 
				
			||||||
    onValueChange(definition.name, value);
 | 
					    // onValueChange(definition.name, value);
 | 
				
			||||||
 | 
					    form.setValues({ [definition.name]: value });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch (definition.fieldType) {
 | 
					  switch (definition.fieldType) {
 | 
				
			||||||
@@ -133,7 +147,8 @@ export function ApiForm({
 | 
				
			|||||||
  onFormError,
 | 
					  onFormError,
 | 
				
			||||||
  cancelText = t`Cancel`,
 | 
					  cancelText = t`Cancel`,
 | 
				
			||||||
  submitText = t`Submit`,
 | 
					  submitText = t`Submit`,
 | 
				
			||||||
  method = 'PUT'
 | 
					  method = 'PUT',
 | 
				
			||||||
 | 
					  fetchInitialData = false
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  url: string;
 | 
					  url: string;
 | 
				
			||||||
@@ -142,6 +157,7 @@ export function ApiForm({
 | 
				
			|||||||
  fields: ApiFormFieldType[];
 | 
					  fields: ApiFormFieldType[];
 | 
				
			||||||
  cancelText?: string;
 | 
					  cancelText?: string;
 | 
				
			||||||
  submitText?: string;
 | 
					  submitText?: string;
 | 
				
			||||||
 | 
					  fetchInitialData?: boolean;
 | 
				
			||||||
  method?: string;
 | 
					  method?: string;
 | 
				
			||||||
  opened: boolean;
 | 
					  opened: boolean;
 | 
				
			||||||
  onClose?: () => void;
 | 
					  onClose?: () => void;
 | 
				
			||||||
@@ -159,6 +175,7 @@ export function ApiForm({
 | 
				
			|||||||
  // Error observed during form construction
 | 
					  // Error observed during form construction
 | 
				
			||||||
  const [error, setError] = useState<string>('');
 | 
					  const [error, setError] = useState<string>('');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Query manager for retrieving form definition from the server
 | 
				
			||||||
  const definitionQuery = useQuery({
 | 
					  const definitionQuery = useQuery({
 | 
				
			||||||
    enabled: opened && !!url,
 | 
					    enabled: opened && !!url,
 | 
				
			||||||
    queryKey: ['form-definition', name, url, pk, fields],
 | 
					    queryKey: ['form-definition', name, url, pk, fields],
 | 
				
			||||||
@@ -172,13 +189,30 @@ export function ApiForm({
 | 
				
			|||||||
          return response;
 | 
					          return response;
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .catch((error) => {
 | 
					        .catch((error) => {
 | 
				
			||||||
          console.error('Error fetching field definitions:', error);
 | 
					 | 
				
			||||||
          setError(error.message);
 | 
					          setError(error.message);
 | 
				
			||||||
          setFieldDefinitions([]);
 | 
					          setFieldDefinitions([]);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Query manager for retrieiving initial data from the server
 | 
				
			||||||
 | 
					  const initialDataQuery = useQuery({
 | 
				
			||||||
 | 
					    enabled: fetchInitialData && opened && !!url && fieldDefinitions.length > 0,
 | 
				
			||||||
 | 
					    queryKey: ['form-initial-data', name, url, pk, fields, fieldDefinitions],
 | 
				
			||||||
 | 
					    queryFn: async () => {
 | 
				
			||||||
 | 
					      return api
 | 
				
			||||||
 | 
					        .get(getUrl())
 | 
				
			||||||
 | 
					        .then((response) => {
 | 
				
			||||||
 | 
					          form.setValues(response.data);
 | 
				
			||||||
 | 
					          return response;
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          console.error('Error fetching initial data:', error);
 | 
				
			||||||
 | 
					          setError(error.message);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // State variable to determine if the form can render the data
 | 
					  // State variable to determine if the form can render the data
 | 
				
			||||||
  const [canRender, setCanRender] = useState<boolean>(false);
 | 
					  const [canRender, setCanRender] = useState<boolean>(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -274,8 +308,11 @@ export function ApiForm({
 | 
				
			|||||||
                <ApiFormField
 | 
					                <ApiFormField
 | 
				
			||||||
                  key={field.name}
 | 
					                  key={field.name}
 | 
				
			||||||
                  field={field}
 | 
					                  field={field}
 | 
				
			||||||
 | 
					                  form={form}
 | 
				
			||||||
                  definitions={fieldDefinitions}
 | 
					                  definitions={fieldDefinitions}
 | 
				
			||||||
                  onValueChange={(fieldName, value) => {}}
 | 
					                  onValueChange={(fieldName, value) => {
 | 
				
			||||||
 | 
					                    form.setValues({ [fieldName]: value });
 | 
				
			||||||
 | 
					                  }}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
              ))}
 | 
					              ))}
 | 
				
			||||||
            </Stack>
 | 
					            </Stack>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,7 @@ export default function Home() {
 | 
				
			|||||||
        title="Edit Part"
 | 
					        title="Edit Part"
 | 
				
			||||||
        opened={formOpened}
 | 
					        opened={formOpened}
 | 
				
			||||||
        onClose={() => setFormOpened(false)}
 | 
					        onClose={() => setFormOpened(false)}
 | 
				
			||||||
 | 
					        fetchInitialData={true}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      <Button
 | 
					      <Button
 | 
				
			||||||
        onClick={() => setFormOpened(true)}
 | 
					        onClick={() => setFormOpened(true)}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user