diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx index e667c17d3e..4e1f3d8240 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx @@ -2,6 +2,7 @@ import { ButtonGroup, Flex } from '@chakra-ui/react'; import IAIButton from 'common/components/IAIButton'; import { useState } from 'react'; import AutoAddModels from './AutoAddModels'; +import ManualAddModels from './ManualAddModels'; export default function AddModels() { const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>( @@ -40,7 +41,7 @@ export default function AddModels() { }} > {addModelMode === 'simple' && } - {addModelMode === 'advanced' && null} + {addModelMode === 'advanced' && } ); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddCheckpoint.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddCheckpoint.tsx new file mode 100644 index 0000000000..efee656d81 --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddCheckpoint.tsx @@ -0,0 +1,20 @@ +import { useForm } from '@mantine/form'; +import { CheckpointModelConfig } from 'services/api/types'; + +export default function ManualAddCheckpoint() { + const manualAddCheckpointForm = useForm({ + initialValues: { + model_name: '', + base_model: 'sd-1', + model_type: 'main', + path: '', + description: '', + model_format: 'checkpoint', + error: undefined, + vae: '', + variant: 'normal', + config: '', + }, + }); + return
ManualAddCheckpoint
; +} diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddDiffusers.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddDiffusers.tsx new file mode 100644 index 0000000000..1e51006dcd --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddDiffusers.tsx @@ -0,0 +1,102 @@ +import { Flex } from '@chakra-ui/react'; +import { useForm } from '@mantine/form'; +import { makeToast } from 'app/components/Toaster'; +import { useAppDispatch } from 'app/store/storeHooks'; +import IAIButton from 'common/components/IAIButton'; +import IAIMantineTextInput from 'common/components/IAIMantineInput'; +import { addToast } from 'features/system/store/systemSlice'; +import { useTranslation } from 'react-i18next'; +import { useAddMainModelsMutation } from 'services/api/endpoints/models'; +import { DiffusersModelConfig } from 'services/api/types'; +import BaseModelSelect from '../shared/BaseModelSelect'; +import ModelVariantSelect from '../shared/ModelVariantSelect'; + +export default function ManualAddDiffusers() { + const { t } = useTranslation(); + const dispatch = useAppDispatch(); + + const [addMainModel] = useAddMainModelsMutation(); + + const manualAddDiffusersForm = useForm({ + initialValues: { + model_name: '', + base_model: 'sd-1', + model_type: 'main', + path: '', + description: '', + model_format: 'diffusers', + error: undefined, + vae: '', + variant: 'normal', + }, + }); + const manualAddDiffusersFormHandler = (values: DiffusersModelConfig) => { + console.log(values); + addMainModel({ + body: values, + }) + .unwrap() + .then((_) => { + dispatch( + addToast( + makeToast({ + title: `Model Added: ${values.model_name}`, + status: 'success', + }) + ) + ); + manualAddDiffusersForm.reset(); + }) + .catch((error) => { + if (error) { + dispatch( + addToast( + makeToast({ + title: 'Model Add Failed', + status: 'error', + }) + ) + ); + } + }); + }; + + return ( +
+ manualAddDiffusersFormHandler(v) + )} + style={{ width: '100%' }} + > + + + + + + + + + {t('modelManager.addModel')} + + +
+ ); +} diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddModels.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddModels.tsx new file mode 100644 index 0000000000..2783e4e6b3 --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddModels.tsx @@ -0,0 +1,46 @@ +import { Flex } from '@chakra-ui/react'; +import { SelectItem } from '@mantine/core'; +import IAIMantineSelect from 'common/components/IAIMantineSelect'; +import { useState } from 'react'; +import ManualAddCheckpoint from './ManualAddCheckpoint'; +import ManualAddDiffusers from './ManualAddDiffusers'; + +const manualAddModeData: SelectItem[] = [ + { label: 'Diffusers', value: 'diffusers' }, + { label: 'Checkpoint / Safetensors', value: 'checkpoint' }, +]; + +type ManualAddMode = 'diffusers' | 'checkpoint'; + +export default function ManualAddModels() { + const [manualAddMode, setManualAddMode] = + useState('diffusers'); + + return ( + + { + if (!v) return; + setManualAddMode(v as ManualAddMode); + }} + /> + + + {manualAddMode === 'diffusers' && } + {manualAddMode === 'checkpoint' && } + + + ); +} diff --git a/invokeai/frontend/web/src/services/api/endpoints/models.ts b/invokeai/frontend/web/src/services/api/endpoints/models.ts index 2a5e5547b3..e0177ca8d1 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/models.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/models.ts @@ -86,6 +86,13 @@ type ImportMainModelArg = { type ImportMainModelResponse = paths['/api/v1/models/import']['post']['responses']['201']['content']['application/json']; +type AddMainModelArg = { + body: MainModelConfig; +}; + +type AddMainModelResponse = + paths['/api/v1/models/add']['post']['responses']['201']['content']['application/json']; + type SearchFolderResponse = paths['/api/v1/models/search']['get']['responses']['200']['content']['application/json']; @@ -189,6 +196,16 @@ export const modelsApi = api.injectEndpoints({ }, invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }], }), + addMainModels: build.mutation({ + query: ({ body }) => { + return { + url: `models/add`, + method: 'POST', + body: body, + }; + }, + invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }], + }), deleteMainModels: build.mutation< DeleteMainModelResponse, DeleteMainModelArg @@ -378,6 +395,7 @@ export const { useUpdateMainModelsMutation, useDeleteMainModelsMutation, useImportMainModelsMutation, + useAddMainModelsMutation, useConvertMainModelsMutation, useMergeMainModelsMutation, useGetModelsInFolderQuery,