import { createSelector } from '@reduxjs/toolkit'; import IAIButton from 'common/components/IAIButton'; import IAIInput from 'common/components/IAIInput'; import IAINumberInput from 'common/components/IAINumberInput'; import { useEffect, useState } from 'react'; import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { systemSelector } from 'features/system/store/systemSelectors'; import { Flex, FormControl, FormLabel, HStack, Text, VStack, } from '@chakra-ui/react'; import { addNewModel } from 'app/socketio/actions'; import { Field, Formik } from 'formik'; import { useTranslation } from 'react-i18next'; import type { InvokeModelConfigProps } from 'app/invokeai'; import type { RootState } from 'app/store'; import type { FieldInputProps, FormikProps } from 'formik'; import { isEqual, pickBy } from 'lodash'; import ModelConvert from './ModelConvert'; import IAIFormHelperText from 'common/components/IAIForms/IAIFormHelperText'; import IAIFormErrorMessage from 'common/components/IAIForms/IAIFormErrorMessage'; import IAIForm from 'common/components/IAIForm'; const selector = createSelector( [systemSelector], (system) => { const { openModel, model_list } = system; return { model_list, openModel, }; }, { memoizeOptions: { resultEqualityCheck: isEqual, }, } ); const MIN_MODEL_SIZE = 64; const MAX_MODEL_SIZE = 2048; export default function CheckpointModelEdit() { const { openModel, model_list } = useAppSelector(selector); const isProcessing = useAppSelector( (state: RootState) => state.system.isProcessing ); const dispatch = useAppDispatch(); const { t } = useTranslation(); const [editModelFormValues, setEditModelFormValues] = useState({ name: '', description: '', config: 'configs/stable-diffusion/v1-inference.yaml', weights: '', vae: '', width: 512, height: 512, default: false, format: 'ckpt', }); useEffect(() => { if (openModel) { const retrievedModel = pickBy(model_list, (_val, key) => { return isEqual(key, openModel); }); setEditModelFormValues({ name: openModel, description: retrievedModel[openModel]?.description, config: retrievedModel[openModel]?.config, weights: retrievedModel[openModel]?.weights, vae: retrievedModel[openModel]?.vae, width: retrievedModel[openModel]?.width, height: retrievedModel[openModel]?.height, default: retrievedModel[openModel]?.default, format: 'ckpt', }); } }, [model_list, openModel]); const editModelFormSubmitHandler = (values: InvokeModelConfigProps) => { dispatch( addNewModel({ ...values, width: Number(values.width), height: Number(values.height), }) ); }; return openModel ? ( {openModel} {({ handleSubmit, errors, touched }) => ( {/* Description */} {t('modelManager.description')} {!!errors.description && touched.description ? ( {errors.description} ) : ( {t('modelManager.descriptionValidationMsg')} )} {/* Config */} {t('modelManager.config')} {!!errors.config && touched.config ? ( {errors.config} ) : ( {t('modelManager.configValidationMsg')} )} {/* Weights */} {t('modelManager.modelLocation')} {!!errors.weights && touched.weights ? ( {errors.weights} ) : ( {t('modelManager.modelLocationValidationMsg')} )} {/* VAE */} {t('modelManager.vaeLocation')} {!!errors.vae && touched.vae ? ( {errors.vae} ) : ( {t('modelManager.vaeLocationValidationMsg')} )} {/* Width */} {t('modelManager.width')} {({ field, form, }: { field: FieldInputProps; form: FormikProps; }) => ( form.setFieldValue(field.name, Number(value)) } /> )} {!!errors.width && touched.width ? ( {errors.width} ) : ( {t('modelManager.widthValidationMsg')} )} {/* Height */} {t('modelManager.height')} {({ field, form, }: { field: FieldInputProps; form: FormikProps; }) => ( form.setFieldValue(field.name, Number(value)) } /> )} {!!errors.height && touched.height ? ( {errors.height} ) : ( {t('modelManager.heightValidationMsg')} )} {t('modelManager.updateModel')} )} ) : ( Pick A Model To Edit ); }