form error handling

This commit is contained in:
Mary Hipp 2024-02-21 14:33:45 -05:00 committed by psychedelicious
parent 86e2b39f0d
commit 782d15af13

View File

@ -1,7 +1,17 @@
import { skipToken } from '@reduxjs/toolkit/query'; import { skipToken } from '@reduxjs/toolkit/query';
import { useAppDispatch, useAppSelector } from '../../../../app/store/storeHooks'; import { useAppDispatch, useAppSelector } from '../../../../app/store/storeHooks';
import { useGetModelQuery, useUpdateModelsMutation } from '../../../../services/api/endpoints/models'; import { useGetModelQuery, useUpdateModelsMutation } from '../../../../services/api/endpoints/models';
import { Flex, Text, Heading, Button, Input, FormControl, FormLabel, Textarea } from '@invoke-ai/ui-library'; import {
Flex,
Text,
Heading,
Button,
Input,
FormControl,
FormLabel,
Textarea,
FormErrorMessage,
} from '@invoke-ai/ui-library';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { import {
AnyModelConfig, AnyModelConfig,
@ -75,6 +85,7 @@ export const ModelEdit = () => {
control, control,
formState: { errors }, formState: { errors },
reset, reset,
watch,
} = useForm<AnyModelConfig>({ } = useForm<AnyModelConfig>({
defaultValues: { defaultValues: {
...modelData, ...modelData,
@ -82,6 +93,9 @@ export const ModelEdit = () => {
mode: 'onChange', mode: 'onChange',
}); });
const watchedModelType = watch('type');
const watchedModelFormat = watch('format');
const onSubmit = useCallback<SubmitHandler<AnyModelConfig>>( const onSubmit = useCallback<SubmitHandler<AnyModelConfig>>(
(values) => { (values) => {
if (!modelData?.key) { if (!modelData?.key) {
@ -136,22 +150,33 @@ export const ModelEdit = () => {
return ( return (
<Flex flexDir="column" h="full"> <Flex flexDir="column" h="full">
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<Flex w="full" justifyContent="space-between" gap={4} alignItems="center"> <FormControl flexDir="column" alignItems="flex-start" gap={1} isInvalid={Boolean(errors.name)}>
<Input <Flex w="full" justifyContent="space-between" gap={4} alignItems="center">
{...register('name', { <FormLabel hidden={true}>Model Name</FormLabel>
validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters', <Input
})} {...register('name', {
size="lg" validate: (value) => value.trim().length > 3 || 'Must be at least 3 characters',
/> })}
<Flex gap={2}> size="lg"
<Button size="sm" onClick={handleClickCancel}> />
Cancel
</Button> <Flex gap={2}>
<Button size="sm" colorScheme="invokeYellow" onClick={handleSubmit(onSubmit)}> <Button size="sm" onClick={handleClickCancel}>
Save Cancel
</Button> </Button>
<Button
size="sm"
colorScheme="invokeYellow"
onClick={handleSubmit(onSubmit)}
isLoading={isSubmitting}
isDisabled={Boolean(errors)}
>
Save
</Button>
</Flex>
</Flex> </Flex>
</Flex> {errors.name?.message && <FormErrorMessage>{errors.name?.message}</FormErrorMessage>}
</FormControl>
<Flex flexDir="column" gap={3} mt="4"> <Flex flexDir="column" gap={3} mt="4">
<Flex> <Flex>
@ -178,25 +203,26 @@ export const ModelEdit = () => {
<FormLabel>Format</FormLabel> <FormLabel>Format</FormLabel>
<ModelFormatSelect<AnyModelConfig> control={control} name="format" /> <ModelFormatSelect<AnyModelConfig> control={control} name="format" />
</FormControl> </FormControl>
<FormControl flexDir="column" alignItems="flex-start" gap={1}> <FormControl flexDir="column" alignItems="flex-start" gap={1} isInvalid={Boolean(errors.path)}>
<FormLabel>Path</FormLabel> <FormLabel>Path</FormLabel>
<Input <Input
{...register('path', { {...register('path', {
validate: (value) => value.trim().length > 0 || 'Must provide a path', validate: (value) => value.trim().length > 0 || 'Must provide a path',
})} })}
/> />
{errors.path?.message && <FormErrorMessage>{errors.path?.message}</FormErrorMessage>}
</FormControl> </FormControl>
</Flex> </Flex>
{modelData.type === 'main' && ( {watchedModelType === 'main' && (
<> <>
<Flex gap={4}> <Flex gap={4}>
{modelData.format === 'diffusers' && ( {watchedModelFormat === 'diffusers' && (
<FormControl flexDir="column" alignItems="flex-start" gap={1}> <FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Repo Variant</FormLabel> <FormLabel>Repo Variant</FormLabel>
<RepoVariantSelect<AnyModelConfig> control={control} name="repo_variant" /> <RepoVariantSelect<AnyModelConfig> control={control} name="repo_variant" />
</FormControl> </FormControl>
)} )}
{modelData.format === 'checkpoint' && ( {watchedModelFormat === 'checkpoint' && (
<FormControl flexDir="column" alignItems="flex-start" gap={1}> <FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Config Path</FormLabel> <FormLabel>Config Path</FormLabel>
<Input {...register('config')} /> <Input {...register('config')} />
@ -230,7 +256,7 @@ export const ModelEdit = () => {
</Flex> </Flex>
</> </>
)} )}
{modelData.type === 'ip_adapter' && ( {watchedModelType === 'ip_adapter' && (
<Flex gap={4}> <Flex gap={4}>
<FormControl flexDir="column" alignItems="flex-start" gap={1}> <FormControl flexDir="column" alignItems="flex-start" gap={1}>
<FormLabel>Image Encoder Model ID</FormLabel> <FormLabel>Image Encoder Model ID</FormLabel>