feat: Update DiffusersEdit Component to use Mantine Form

This commit is contained in:
blessedcoolant 2023-06-30 08:19:36 +12:00 committed by psychedelicious
parent 009c20bfea
commit 33db4e27a0
3 changed files with 86 additions and 210 deletions

View File

@ -351,6 +351,7 @@
"scanForModels": "Scan For Models", "scanForModels": "Scan For Models",
"addManually": "Add Manually", "addManually": "Add Manually",
"manual": "Manual", "manual": "Manual",
"baseModel": "Base Model",
"name": "Name", "name": "Name",
"nameValidationMsg": "Enter a name for your model", "nameValidationMsg": "Enter a name for your model",
"description": "Description", "description": "Description",
@ -363,6 +364,7 @@
"repoIDValidationMsg": "Online repository of your model", "repoIDValidationMsg": "Online repository of your model",
"vaeLocation": "VAE Location", "vaeLocation": "VAE Location",
"vaeLocationValidationMsg": "Path to where your VAE is located.", "vaeLocationValidationMsg": "Path to where your VAE is located.",
"variant": "Variant",
"vaeRepoID": "VAE Repo ID", "vaeRepoID": "VAE Repo ID",
"vaeRepoIDValidationMsg": "Online repository of your VAE", "vaeRepoIDValidationMsg": "Online repository of your VAE",
"width": "Width", "width": "Width",

View File

@ -24,6 +24,7 @@ export default function ModelManagerPanel() {
<DiffusersModelEdit <DiffusersModelEdit
modelToEdit={openModel} modelToEdit={openModel}
retrievedModel={mainModels['entities'][openModel]} retrievedModel={mainModels['entities'][openModel]}
key={openModel}
/> />
); );
} else { } else {

View File

@ -1,245 +1,118 @@
import IAIButton from 'common/components/IAIButton';
import IAIInput from 'common/components/IAIInput';
import { useEffect, useState } from 'react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { Flex, FormControl, FormLabel, Text, VStack } from '@chakra-ui/react'; import { Divider, Flex, Text } from '@chakra-ui/react';
// import { addNewModel } from 'app/socketio/actions'; // import { addNewModel } from 'app/socketio/actions';
import { Field, Formik } from 'formik';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useForm } from '@mantine/form';
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import type { InvokeDiffusersModelConfigProps } from 'app/types/invokeai'; import IAIButton from 'common/components/IAIButton';
import IAIForm from 'common/components/IAIForm'; import IAIInput from 'common/components/IAIInput';
import IAIFormErrorMessage from 'common/components/IAIForms/IAIFormErrorMessage'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import IAIFormHelperText from 'common/components/IAIForms/IAIFormHelperText'; import { MODEL_TYPE_MAP } from 'features/system/components/ModelSelect';
import { S } from 'services/api/types';
type DiffusersModel =
| S<'StableDiffusion1ModelDiffusersConfig'>
| S<'StableDiffusion2ModelDiffusersConfig'>;
type DiffusersModelEditProps = { type DiffusersModelEditProps = {
modelToEdit: string; modelToEdit: string;
retrievedModel: any; retrievedModel: DiffusersModel;
}; };
const baseModelSelectData = [
{ value: 'sd-1', label: MODEL_TYPE_MAP['sd-1'] },
{ value: 'sd-2', label: MODEL_TYPE_MAP['sd-2'] },
];
const variantSelectData = [
{ value: 'normal', label: 'Normal' },
{ value: 'inpaint', label: 'Inpaint' },
{ value: 'depth', label: 'Depth' },
];
export default function DiffusersModelEdit(props: DiffusersModelEditProps) { export default function DiffusersModelEdit(props: DiffusersModelEditProps) {
const isProcessing = useAppSelector( const isProcessing = useAppSelector(
(state: RootState) => state.system.isProcessing (state: RootState) => state.system.isProcessing
); );
const { retrievedModel, modelToEdit } = props; const { retrievedModel, modelToEdit } = props;
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
const [editModelFormValues, setEditModelFormValues] = const diffusersEditForm = useForm({
useState<InvokeDiffusersModelConfigProps>({ initialValues: {
name: '', name: retrievedModel.name,
description: '', base_model: retrievedModel.base_model,
repo_id: '', type: 'main',
path: '', path: retrievedModel.path,
vae: { repo_id: '', path: '' }, description: retrievedModel.description,
default: false,
model_format: 'diffusers', model_format: 'diffusers',
}); vae: retrievedModel.vae,
variant: retrievedModel.variant,
},
});
useEffect(() => { const editModelFormSubmitHandler = (values) => {
setEditModelFormValues({ console.log(values);
name: modelToEdit,
description: retrievedModel?.description,
path:
retrievedModel?.path && retrievedModel?.path !== 'None'
? retrievedModel?.path
: '',
repo_id:
retrievedModel?.repo_id && retrievedModel?.repo_id !== 'None'
? retrievedModel?.repo_id
: '',
vae: {
repo_id: retrievedModel?.vae?.repo_id
? retrievedModel?.vae?.repo_id
: '',
path: retrievedModel?.vae?.path ? retrievedModel?.vae?.path : '',
},
default: retrievedModel?.default,
model_format: 'diffusers',
});
}, [retrievedModel, modelToEdit]);
const editModelFormSubmitHandler = (
values: InvokeDiffusersModelConfigProps
) => {
const diffusersModelToEdit = values;
if (values.path === '') delete diffusersModelToEdit.path;
if (values.repo_id === '') delete diffusersModelToEdit.repo_id;
if (values.vae.path === '') delete diffusersModelToEdit.vae.path;
if (values.vae.repo_id === '') delete diffusersModelToEdit.vae.repo_id;
dispatch(addNewModel(values));
}; };
return modelToEdit ? ( return modelToEdit ? (
<Flex flexDirection="column" rowGap={4} width="100%"> <Flex flexDirection="column" rowGap={4} width="100%">
<Flex alignItems="center"> <Flex flexDirection="column">
<Text fontSize="lg" fontWeight="bold"> <Text fontSize="lg" fontWeight="bold">
{retrievedModel.name} {retrievedModel.name}
</Text> </Text>
<Text fontSize="sm" color="base.400">
{MODEL_TYPE_MAP[retrievedModel.base_model]} Model
</Text>
</Flex> </Flex>
<Flex flexDirection="column" overflowY="scroll" paddingInlineEnd={8}> <Divider />
<Formik
enableReinitialize={true} <form
initialValues={editModelFormValues} onSubmit={diffusersEditForm.onSubmit((values) =>
onSubmit={editModelFormSubmitHandler} editModelFormSubmitHandler(values)
)}
>
<Flex
flexDirection="column"
overflowY="scroll"
gap={4}
paddingInlineEnd={8}
> >
{({ handleSubmit, errors, touched }) => ( <IAIInput
<IAIForm onSubmit={handleSubmit}> label={t('modelManager.name')}
<VStack rowGap={2} alignItems="start"> {...diffusersEditForm.getInputProps('name')}
{/* Description */} />
<FormControl <IAIInput
isInvalid={!!errors.description && touched.description} label={t('modelManager.description')}
isRequired {...diffusersEditForm.getInputProps('description')}
> />
<FormLabel htmlFor="description" fontSize="sm"> <IAIMantineSelect
{t('modelManager.description')} label={t('modelManager.baseModel')}
</FormLabel> data={baseModelSelectData}
<VStack alignItems="start"> {...diffusersEditForm.getInputProps('base_model')}
<Field />
as={IAIInput} <IAIMantineSelect
id="description" label={t('modelManager.variant')}
name="description" data={variantSelectData}
type="text" {...diffusersEditForm.getInputProps('variant')}
width="full" />
/> <IAIInput
{!!errors.description && touched.description ? ( label={t('modelManager.modelLocation')}
<IAIFormErrorMessage> {...diffusersEditForm.getInputProps('path')}
{errors.description} />
</IAIFormErrorMessage> <IAIInput
) : ( label={t('modelManager.vaeLocation')}
<IAIFormHelperText> {...diffusersEditForm.getInputProps('vae')}
{t('modelManager.descriptionValidationMsg')} />
</IAIFormHelperText> <IAIButton disabled={isProcessing} type="submit">
)} {t('modelManager.updateModel')}
</VStack> </IAIButton>
</FormControl> </Flex>
</form>
{/* Path */}
<FormControl
isInvalid={!!errors.path && touched.path}
isRequired
>
<FormLabel htmlFor="path" fontSize="sm">
{t('modelManager.modelLocation')}
</FormLabel>
<VStack alignItems="start">
<Field
as={IAIInput}
id="path"
name="path"
type="text"
width="full"
/>
{!!errors.path && touched.path ? (
<IAIFormErrorMessage>{errors.path}</IAIFormErrorMessage>
) : (
<IAIFormHelperText>
{t('modelManager.modelLocationValidationMsg')}
</IAIFormHelperText>
)}
</VStack>
</FormControl>
{/* Repo ID */}
<FormControl isInvalid={!!errors.repo_id && touched.repo_id}>
<FormLabel htmlFor="repo_id" fontSize="sm">
{t('modelManager.repo_id')}
</FormLabel>
<VStack alignItems="start">
<Field
as={IAIInput}
id="repo_id"
name="repo_id"
type="text"
width="full"
/>
{!!errors.repo_id && touched.repo_id ? (
<IAIFormErrorMessage>
{errors.repo_id}
</IAIFormErrorMessage>
) : (
<IAIFormHelperText>
{t('modelManager.repoIDValidationMsg')}
</IAIFormHelperText>
)}
</VStack>
</FormControl>
{/* VAE Path */}
<FormControl
isInvalid={!!errors.vae?.path && touched.vae?.path}
>
<FormLabel htmlFor="vae.path" fontSize="sm">
{t('modelManager.vaeLocation')}
</FormLabel>
<VStack alignItems="start">
<Field
as={IAIInput}
id="vae.path"
name="vae.path"
type="text"
width="full"
/>
{!!errors.vae?.path && touched.vae?.path ? (
<IAIFormErrorMessage>
{errors.vae?.path}
</IAIFormErrorMessage>
) : (
<IAIFormHelperText>
{t('modelManager.vaeLocationValidationMsg')}
</IAIFormHelperText>
)}
</VStack>
</FormControl>
{/* VAE Repo ID */}
<FormControl
isInvalid={!!errors.vae?.repo_id && touched.vae?.repo_id}
>
<FormLabel htmlFor="vae.repo_id" fontSize="sm">
{t('modelManager.vaeRepoID')}
</FormLabel>
<VStack alignItems="start">
<Field
as={IAIInput}
id="vae.repo_id"
name="vae.repo_id"
type="text"
width="full"
/>
{!!errors.vae?.repo_id && touched.vae?.repo_id ? (
<IAIFormErrorMessage>
{errors.vae?.repo_id}
</IAIFormErrorMessage>
) : (
<IAIFormHelperText>
{t('modelManager.vaeRepoIDValidationMsg')}
</IAIFormHelperText>
)}
</VStack>
</FormControl>
<IAIButton
type="submit"
className="modal-close-btn"
isLoading={isProcessing}
>
{t('modelManager.updateModel')}
</IAIButton>
</VStack>
</IAIForm>
)}
</Formik>
</Flex>
</Flex> </Flex>
) : ( ) : (
<Flex <Flex