mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 15:15:42 +00:00 
			
		
		
		
	Create components for different form types
- Create - Edit - Delete
This commit is contained in:
		@@ -32,6 +32,7 @@ export type ApiFormFieldType = {
 | 
				
			|||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  label?: string;
 | 
					  label?: string;
 | 
				
			||||||
  value?: any;
 | 
					  value?: any;
 | 
				
			||||||
 | 
					  default?: any;
 | 
				
			||||||
  icon?: ReactNode;
 | 
					  icon?: ReactNode;
 | 
				
			||||||
  fieldType?: string;
 | 
					  fieldType?: string;
 | 
				
			||||||
  api_url?: string;
 | 
					  api_url?: string;
 | 
				
			||||||
@@ -249,8 +250,7 @@ function ApiFormField({
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * An ApiForm component is a modal form which is rendered dynamically,
 | 
					 * Properties for the ApiForm component
 | 
				
			||||||
 * based on an API endpoint.
 | 
					 | 
				
			||||||
 * @param url : The API endpoint to fetch the form from.
 | 
					 * @param url : The API endpoint to fetch the form from.
 | 
				
			||||||
 * @param fields : The fields to render in the form.
 | 
					 * @param fields : The fields to render in the form.
 | 
				
			||||||
 * @param opened : Whether the form is opened or not.
 | 
					 * @param opened : Whether the form is opened or not.
 | 
				
			||||||
@@ -258,21 +258,7 @@ function ApiFormField({
 | 
				
			|||||||
 * @param onFormSuccess : A callback function to call when the form is submitted successfully.
 | 
					 * @param onFormSuccess : A callback function to call when the form is submitted successfully.
 | 
				
			||||||
 * @param onFormError : A callback function to call when the form is submitted with errors.
 | 
					 * @param onFormError : A callback function to call when the form is submitted with errors.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function ApiForm({
 | 
					export interface ApiFormProps {
 | 
				
			||||||
  name,
 | 
					 | 
				
			||||||
  url,
 | 
					 | 
				
			||||||
  pk,
 | 
					 | 
				
			||||||
  title,
 | 
					 | 
				
			||||||
  fields,
 | 
					 | 
				
			||||||
  opened,
 | 
					 | 
				
			||||||
  onClose,
 | 
					 | 
				
			||||||
  onFormSuccess,
 | 
					 | 
				
			||||||
  onFormError,
 | 
					 | 
				
			||||||
  cancelText = t`Cancel`,
 | 
					 | 
				
			||||||
  submitText = t`Submit`,
 | 
					 | 
				
			||||||
  method = 'PUT',
 | 
					 | 
				
			||||||
  fetchInitialData = false
 | 
					 | 
				
			||||||
}: {
 | 
					 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  url: string;
 | 
					  url: string;
 | 
				
			||||||
  pk?: number;
 | 
					  pk?: number;
 | 
				
			||||||
@@ -280,13 +266,22 @@ export function ApiForm({
 | 
				
			|||||||
  fields: ApiFormFieldType[];
 | 
					  fields: ApiFormFieldType[];
 | 
				
			||||||
  cancelText?: string;
 | 
					  cancelText?: string;
 | 
				
			||||||
  submitText?: string;
 | 
					  submitText?: string;
 | 
				
			||||||
 | 
					  submitColor?: string;
 | 
				
			||||||
 | 
					  cancelColor?: string;
 | 
				
			||||||
  fetchInitialData?: boolean;
 | 
					  fetchInitialData?: boolean;
 | 
				
			||||||
  method?: string;
 | 
					  method?: string;
 | 
				
			||||||
  opened: boolean;
 | 
					  opened: boolean;
 | 
				
			||||||
  onClose?: () => void;
 | 
					  onClose?: () => void;
 | 
				
			||||||
  onFormSuccess?: () => void;
 | 
					  onFormSuccess?: () => void;
 | 
				
			||||||
  onFormError?: () => void;
 | 
					  onFormError?: () => void;
 | 
				
			||||||
}) {
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * An ApiForm component is a modal form which is rendered dynamically,
 | 
				
			||||||
 | 
					 * based on an API endpoint.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function ApiForm(props: ApiFormProps) {
 | 
				
			||||||
  // Form state
 | 
					  // Form state
 | 
				
			||||||
  const form = useForm({});
 | 
					  const form = useForm({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -300,8 +295,8 @@ export function ApiForm({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Query manager for retrieving form definition from the server
 | 
					  // Query manager for retrieving form definition from the server
 | 
				
			||||||
  const definitionQuery = useQuery({
 | 
					  const definitionQuery = useQuery({
 | 
				
			||||||
    enabled: opened && !!url,
 | 
					    enabled: props.opened && !!props.url,
 | 
				
			||||||
    queryKey: ['form-definition', name, url, pk],
 | 
					    queryKey: ['form-definition', name, props.url, props.pk],
 | 
				
			||||||
    queryFn: async () => {
 | 
					    queryFn: async () => {
 | 
				
			||||||
      // Clear form construction error field
 | 
					      // Clear form construction error field
 | 
				
			||||||
      setError('');
 | 
					      setError('');
 | 
				
			||||||
@@ -320,8 +315,12 @@ export function ApiForm({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Query manager for retrieiving initial data from the server
 | 
					  // Query manager for retrieiving initial data from the server
 | 
				
			||||||
  const initialDataQuery = useQuery({
 | 
					  const initialDataQuery = useQuery({
 | 
				
			||||||
    enabled: fetchInitialData && opened && !!url && fieldDefinitions.length > 0,
 | 
					    enabled:
 | 
				
			||||||
    queryKey: ['form-initial-data', name, url, pk],
 | 
					      props.fetchInitialData &&
 | 
				
			||||||
 | 
					      props.opened &&
 | 
				
			||||||
 | 
					      !!props.url &&
 | 
				
			||||||
 | 
					      fieldDefinitions.length > 0,
 | 
				
			||||||
 | 
					    queryKey: ['form-initial-data', name, props.url, props.pk],
 | 
				
			||||||
    queryFn: async () => {
 | 
					    queryFn: async () => {
 | 
				
			||||||
      return api
 | 
					      return api
 | 
				
			||||||
        .get(getUrl())
 | 
					        .get(getUrl())
 | 
				
			||||||
@@ -357,10 +356,14 @@ export function ApiForm({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Construct a fully-qualified URL based on the provided details
 | 
					  // Construct a fully-qualified URL based on the provided details
 | 
				
			||||||
  function getUrl(): string {
 | 
					  function getUrl(): string {
 | 
				
			||||||
    let u = url;
 | 
					    if (!props.url) {
 | 
				
			||||||
 | 
					      return '';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pk && pk > 0) {
 | 
					    let u = props.url;
 | 
				
			||||||
      u += `${pk}/`;
 | 
					
 | 
				
			||||||
 | 
					    if (props.pk && props.pk > 0) {
 | 
				
			||||||
 | 
					      u += `${props.pk}/`;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return u;
 | 
					    return u;
 | 
				
			||||||
@@ -374,10 +377,14 @@ export function ApiForm({
 | 
				
			|||||||
  function extractFieldDefinitions(
 | 
					  function extractFieldDefinitions(
 | 
				
			||||||
    response: AxiosResponse
 | 
					    response: AxiosResponse
 | 
				
			||||||
  ): ApiFormFieldType[] {
 | 
					  ): ApiFormFieldType[] {
 | 
				
			||||||
    let actions = response.data?.actions[method.toUpperCase()] || [];
 | 
					    if (!props.method) {
 | 
				
			||||||
 | 
					      return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let actions = response.data?.actions[props.method.toUpperCase()] || [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (actions.length == 0) {
 | 
					    if (actions.length == 0) {
 | 
				
			||||||
      setError(`Permission denied for ${method} at ${url}`);
 | 
					      setError(`Permission denied for ${props.method} at ${props.url}`);
 | 
				
			||||||
      return [];
 | 
					      return [];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -389,7 +396,7 @@ export function ApiForm({
 | 
				
			|||||||
        name: fieldName,
 | 
					        name: fieldName,
 | 
				
			||||||
        label: field.label,
 | 
					        label: field.label,
 | 
				
			||||||
        description: field.help_text,
 | 
					        description: field.help_text,
 | 
				
			||||||
        value: field.value,
 | 
					        value: field.value || field.default,
 | 
				
			||||||
        fieldType: field.type,
 | 
					        fieldType: field.type,
 | 
				
			||||||
        required: field.required,
 | 
					        required: field.required,
 | 
				
			||||||
        placeholder: field.placeholder,
 | 
					        placeholder: field.placeholder,
 | 
				
			||||||
@@ -405,11 +412,11 @@ export function ApiForm({
 | 
				
			|||||||
    <Modal
 | 
					    <Modal
 | 
				
			||||||
      size="xl"
 | 
					      size="xl"
 | 
				
			||||||
      radius="sm"
 | 
					      radius="sm"
 | 
				
			||||||
      opened={opened}
 | 
					      opened={props.opened}
 | 
				
			||||||
      onClose={() => {
 | 
					      onClose={() => {
 | 
				
			||||||
        onClose ? onClose() : null;
 | 
					        props.onClose ? props.onClose() : null;
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
      title={title}
 | 
					      title={props.title}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <Stack>
 | 
					      <Stack>
 | 
				
			||||||
        <Divider />
 | 
					        <Divider />
 | 
				
			||||||
@@ -430,7 +437,7 @@ export function ApiForm({
 | 
				
			|||||||
          {canRender && (
 | 
					          {canRender && (
 | 
				
			||||||
            <ScrollArea>
 | 
					            <ScrollArea>
 | 
				
			||||||
              <Stack spacing="md">
 | 
					              <Stack spacing="md">
 | 
				
			||||||
                {fields.map((field) => (
 | 
					                {props.fields.map((field) => (
 | 
				
			||||||
                  <ApiFormField
 | 
					                  <ApiFormField
 | 
				
			||||||
                    key={field.name}
 | 
					                    key={field.name}
 | 
				
			||||||
                    field={field}
 | 
					                    field={field}
 | 
				
			||||||
@@ -447,19 +454,24 @@ export function ApiForm({
 | 
				
			|||||||
        </Stack>
 | 
					        </Stack>
 | 
				
			||||||
        <Divider />
 | 
					        <Divider />
 | 
				
			||||||
        <Group position="right">
 | 
					        <Group position="right">
 | 
				
			||||||
          <Button onClick={onClose} variant="outline" radius="sm" color="red">
 | 
					          <Button
 | 
				
			||||||
            {cancelText}
 | 
					            onClick={props.onClose}
 | 
				
			||||||
 | 
					            variant="outline"
 | 
				
			||||||
 | 
					            radius="sm"
 | 
				
			||||||
 | 
					            color={props.cancelColor ?? 'blue'}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {props.cancelText ?? `Cancel`}
 | 
				
			||||||
          </Button>
 | 
					          </Button>
 | 
				
			||||||
          <Button
 | 
					          <Button
 | 
				
			||||||
            onClick={() => null}
 | 
					            onClick={() => null}
 | 
				
			||||||
            variant="outline"
 | 
					            variant="outline"
 | 
				
			||||||
            radius="sm"
 | 
					            radius="sm"
 | 
				
			||||||
            color="green"
 | 
					            color={props.submitColor ?? 'green'}
 | 
				
			||||||
            disabled={!canSubmit}
 | 
					            disabled={!canSubmit}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <Group position="right" spacing={5} noWrap={true}>
 | 
					            <Group position="right" spacing={5} noWrap={true}>
 | 
				
			||||||
              <Loader size="xs" />
 | 
					              <Loader size="xs" />
 | 
				
			||||||
              {submitText}
 | 
					              {props.submitText ?? `Submit`}
 | 
				
			||||||
            </Group>
 | 
					            </Group>
 | 
				
			||||||
          </Button>
 | 
					          </Button>
 | 
				
			||||||
        </Group>
 | 
					        </Group>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								src/frontend/src/components/forms/CreateApiForm.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/frontend/src/components/forms/CreateApiForm.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					import { useMemo } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ApiForm, ApiFormProps } from './ApiForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A modal form for creating a new database object via the API
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function CreateApiForm(props: ApiFormProps) {
 | 
				
			||||||
 | 
					  const createProps: ApiFormProps = useMemo(() => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      ...props,
 | 
				
			||||||
 | 
					      method: 'POST',
 | 
				
			||||||
 | 
					      fetchInitialData: false
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }, [props]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return <ApiForm {...createProps} />;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								src/frontend/src/components/forms/DeleteApiForm.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/frontend/src/components/forms/DeleteApiForm.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					import { t } from '@lingui/macro';
 | 
				
			||||||
 | 
					import { useMemo } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ApiForm, ApiFormProps } from './ApiForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A modal form for deleting a single database object via the API.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function DeleteApiForm(props: ApiFormProps) {
 | 
				
			||||||
 | 
					  const deleteProps: ApiFormProps = useMemo(() => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      ...props,
 | 
				
			||||||
 | 
					      method: 'DELETE',
 | 
				
			||||||
 | 
					      fetchInitialData: false,
 | 
				
			||||||
 | 
					      submitText: props.submitText ? props.submitText : t`Delete`,
 | 
				
			||||||
 | 
					      submitColor: 'red'
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }, [props]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return <ApiForm {...deleteProps} />;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/frontend/src/components/forms/EditApiForm.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/frontend/src/components/forms/EditApiForm.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import { useMemo } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ApiForm, ApiFormProps } from './ApiForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A modal form for editing a single database object via the API.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function EditApiForm(props: ApiFormProps) {
 | 
				
			||||||
 | 
					  const editProps: ApiFormProps = useMemo(() => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      ...props,
 | 
				
			||||||
 | 
					      method: 'PUT',
 | 
				
			||||||
 | 
					      fetchInitialData: true,
 | 
				
			||||||
 | 
					      submitText: props.submitText ? props.submitText : 'Save'
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }, [props]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return <ApiForm {...editProps} />;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -11,6 +11,9 @@ import {
 | 
				
			|||||||
import { useState } from 'react';
 | 
					import { useState } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ApiForm, ApiFormFieldType } from '../../components/forms/ApiForm';
 | 
					import { ApiForm, ApiFormFieldType } from '../../components/forms/ApiForm';
 | 
				
			||||||
 | 
					import { CreateApiForm } from '../../components/forms/CreateApiForm';
 | 
				
			||||||
 | 
					import { DeleteApiForm } from '../../components/forms/DeleteApiForm';
 | 
				
			||||||
 | 
					import { EditApiForm } from '../../components/forms/EditApiForm';
 | 
				
			||||||
import { PlaceholderPill } from '../../components/items/Placeholder';
 | 
					import { PlaceholderPill } from '../../components/items/Placeholder';
 | 
				
			||||||
import { StylishText } from '../../components/items/StylishText';
 | 
					import { StylishText } from '../../components/items/StylishText';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,6 +21,8 @@ export default function Home() {
 | 
				
			|||||||
  const [partFormOpened, setPartFormOpened] = useState(false);
 | 
					  const [partFormOpened, setPartFormOpened] = useState(false);
 | 
				
			||||||
  const [poFormOpened, setPoFormOpened] = useState(false);
 | 
					  const [poFormOpened, setPoFormOpened] = useState(false);
 | 
				
			||||||
  const [companyFormOpened, setCompanyFormOpened] = useState(false);
 | 
					  const [companyFormOpened, setCompanyFormOpened] = useState(false);
 | 
				
			||||||
 | 
					  const [stockFormOpened, setStockFormOpened] = useState(false);
 | 
				
			||||||
 | 
					  const [salesOrderFormOpened, setSalesOrderFormOpened] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const partFields: ApiFormFieldType[] = [
 | 
					  const partFields: ApiFormFieldType[] = [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -59,6 +64,18 @@ export default function Home() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const salesOrderFields: ApiFormFieldType[] = [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'reference'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'customer'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: 'description'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const companyFields: ApiFormFieldType[] = [
 | 
					  const companyFields: ApiFormFieldType[] = [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      name: 'name'
 | 
					      name: 'name'
 | 
				
			||||||
@@ -91,39 +108,51 @@ export default function Home() {
 | 
				
			|||||||
        </StylishText>
 | 
					        </StylishText>
 | 
				
			||||||
        <PlaceholderPill />
 | 
					        <PlaceholderPill />
 | 
				
			||||||
      </Group>
 | 
					      </Group>
 | 
				
			||||||
      <ApiForm
 | 
					      <EditApiForm
 | 
				
			||||||
        name="part-edit"
 | 
					        name="part-edit"
 | 
				
			||||||
        url="/part/"
 | 
					        url="/part/"
 | 
				
			||||||
        pk={1}
 | 
					        pk={1}
 | 
				
			||||||
        fields={partFields}
 | 
					        fields={partFields}
 | 
				
			||||||
        method="PUT"
 | 
					 | 
				
			||||||
        title="Edit Part"
 | 
					        title="Edit Part"
 | 
				
			||||||
        opened={partFormOpened}
 | 
					        opened={partFormOpened}
 | 
				
			||||||
        onClose={() => setPartFormOpened(false)}
 | 
					        onClose={() => setPartFormOpened(false)}
 | 
				
			||||||
        fetchInitialData={true}
 | 
					 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      <ApiForm
 | 
					      <EditApiForm
 | 
				
			||||||
        name="po-edit"
 | 
					        name="po-edit"
 | 
				
			||||||
        url="/order/po/"
 | 
					        url="/order/po/"
 | 
				
			||||||
        pk={1}
 | 
					        pk={1}
 | 
				
			||||||
        fields={poFields}
 | 
					        fields={poFields}
 | 
				
			||||||
        method="PUT"
 | 
					 | 
				
			||||||
        title="Edit Purchase Order"
 | 
					        title="Edit Purchase Order"
 | 
				
			||||||
        opened={poFormOpened}
 | 
					        opened={poFormOpened}
 | 
				
			||||||
        onClose={() => setPoFormOpened(false)}
 | 
					        onClose={() => setPoFormOpened(false)}
 | 
				
			||||||
        fetchInitialData={true}
 | 
					 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      <ApiForm
 | 
					      <EditApiForm
 | 
				
			||||||
        name="company-edit"
 | 
					        name="company-edit"
 | 
				
			||||||
        url="/company/"
 | 
					        url="/company/"
 | 
				
			||||||
        pk={1}
 | 
					        pk={1}
 | 
				
			||||||
        fields={companyFields}
 | 
					        fields={companyFields}
 | 
				
			||||||
        method="PUT"
 | 
					 | 
				
			||||||
        title="Edit Company"
 | 
					        title="Edit Company"
 | 
				
			||||||
        opened={companyFormOpened}
 | 
					        opened={companyFormOpened}
 | 
				
			||||||
        onClose={() => setCompanyFormOpened(false)}
 | 
					        onClose={() => setCompanyFormOpened(false)}
 | 
				
			||||||
        fetchInitialData={true}
 | 
					 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
 | 
					      <DeleteApiForm
 | 
				
			||||||
 | 
					        name="stock-delete"
 | 
				
			||||||
 | 
					        url="/stock/"
 | 
				
			||||||
 | 
					        title="Delete Stock Item"
 | 
				
			||||||
 | 
					        pk={1}
 | 
				
			||||||
 | 
					        fields={[]}
 | 
				
			||||||
 | 
					        opened={stockFormOpened}
 | 
				
			||||||
 | 
					        onClose={() => setStockFormOpened(false)}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      <CreateApiForm
 | 
				
			||||||
 | 
					        name="sales-order-create"
 | 
				
			||||||
 | 
					        url="/order/so/"
 | 
				
			||||||
 | 
					        title="Create Sales Order"
 | 
				
			||||||
 | 
					        fields={salesOrderFields}
 | 
				
			||||||
 | 
					        opened={salesOrderFormOpened}
 | 
				
			||||||
 | 
					        onClose={() => setSalesOrderFormOpened(false)}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <Stack align="flex-start" spacing="xs">
 | 
					      <Stack align="flex-start" spacing="xs">
 | 
				
			||||||
        <Button
 | 
					        <Button
 | 
				
			||||||
          onClick={() => setPartFormOpened(true)}
 | 
					          onClick={() => setPartFormOpened(true)}
 | 
				
			||||||
@@ -146,6 +175,20 @@ export default function Home() {
 | 
				
			|||||||
        >
 | 
					        >
 | 
				
			||||||
          Edit Company Form
 | 
					          Edit Company Form
 | 
				
			||||||
        </Button>
 | 
					        </Button>
 | 
				
			||||||
 | 
					        <Button
 | 
				
			||||||
 | 
					          variant="outline"
 | 
				
			||||||
 | 
					          color="green"
 | 
				
			||||||
 | 
					          onClick={() => setSalesOrderFormOpened(true)}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          Create Sales Order Form
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					        <Button
 | 
				
			||||||
 | 
					          variant="outline"
 | 
				
			||||||
 | 
					          color="red"
 | 
				
			||||||
 | 
					          onClick={() => setStockFormOpened(true)}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          Delete Stock Item Form
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
      </Stack>
 | 
					      </Stack>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user