mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat: Initial port of Model Manager to new tab
This commit is contained in:
parent
9e35643911
commit
2ad5a4ea46
@ -1,93 +0,0 @@
|
||||
import {
|
||||
Flex,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import { cloneElement } from 'react';
|
||||
|
||||
import { RootState } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { ReactElement } from 'react';
|
||||
|
||||
import { useListModelsQuery } from 'services/api/endpoints/models';
|
||||
import CheckpointModelEdit from './CheckpointModelEdit';
|
||||
import DiffusersModelEdit from './DiffusersModelEdit';
|
||||
import ModelList from './ModelList';
|
||||
|
||||
type ModelManagerModalProps = {
|
||||
children: ReactElement;
|
||||
};
|
||||
|
||||
export default function ModelManagerModal({
|
||||
children,
|
||||
}: ModelManagerModalProps) {
|
||||
const {
|
||||
isOpen: isModelManagerModalOpen,
|
||||
onOpen: onModelManagerModalOpen,
|
||||
onClose: onModelManagerModalClose,
|
||||
} = useDisclosure();
|
||||
|
||||
const { data: pipelineModels } = useListModelsQuery({
|
||||
model_type: 'pipeline',
|
||||
});
|
||||
|
||||
const openModel = useAppSelector(
|
||||
(state: RootState) => state.system.openModel
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const renderModelEditTabs = () => {
|
||||
if (!openModel || !pipelineModels) return;
|
||||
|
||||
if (pipelineModels['entities'][openModel]['model_format'] === 'diffusers') {
|
||||
return (
|
||||
<DiffusersModelEdit
|
||||
modelToEdit={openModel}
|
||||
retrievedModel={pipelineModels['entities'][openModel]}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<CheckpointModelEdit
|
||||
modelToEdit={openModel}
|
||||
retrievedModel={pipelineModels['entities'][openModel]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{cloneElement(children, {
|
||||
onClick: onModelManagerModalOpen,
|
||||
})}
|
||||
<Modal
|
||||
isOpen={isModelManagerModalOpen}
|
||||
onClose={onModelManagerModalClose}
|
||||
size="full"
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalCloseButton />
|
||||
<ModalHeader>{t('modelManager.modelManager')}</ModalHeader>
|
||||
<ModalBody>
|
||||
<Flex width="100%" columnGap={8}>
|
||||
<ModelList />
|
||||
{renderModelEditTabs()}
|
||||
</Flex>
|
||||
</ModalBody>
|
||||
<ModalFooter />
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
@ -5,21 +5,18 @@ import StatusIndicator from './StatusIndicator';
|
||||
import { Link } from '@chakra-ui/react';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaBug, FaCube, FaDiscord, FaGithub, FaKeyboard } from 'react-icons/fa';
|
||||
import { FaBug, FaDiscord, FaGithub, FaKeyboard } from 'react-icons/fa';
|
||||
import { MdSettings } from 'react-icons/md';
|
||||
import { useFeatureStatus } from '../hooks/useFeatureStatus';
|
||||
import ColorModeButton from './ColorModeButton';
|
||||
import HotkeysModal from './HotkeysModal/HotkeysModal';
|
||||
import InvokeAILogoComponent from './InvokeAILogoComponent';
|
||||
import LanguagePicker from './LanguagePicker';
|
||||
import ModelManagerModal from './ModelManager/ModelManagerModal';
|
||||
import SettingsModal from './SettingsModal/SettingsModal';
|
||||
import { useFeatureStatus } from '../hooks/useFeatureStatus';
|
||||
import ColorModeButton from './ColorModeButton';
|
||||
|
||||
const SiteHeader = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isModelManagerEnabled =
|
||||
useFeatureStatus('modelManager').isFeatureEnabled;
|
||||
const isLocalizationEnabled =
|
||||
useFeatureStatus('localization').isFeatureEnabled;
|
||||
const isBugLinkEnabled = useFeatureStatus('bugLink').isFeatureEnabled;
|
||||
@ -37,20 +34,6 @@ const SiteHeader = () => {
|
||||
<Spacer />
|
||||
<StatusIndicator />
|
||||
|
||||
{isModelManagerEnabled && (
|
||||
<ModelManagerModal>
|
||||
<IAIIconButton
|
||||
aria-label={t('modelManager.modelManager')}
|
||||
tooltip={t('modelManager.modelManager')}
|
||||
size="sm"
|
||||
variant="link"
|
||||
data-variant="link"
|
||||
fontSize={20}
|
||||
icon={<FaCube />}
|
||||
/>
|
||||
</ModelManagerModal>
|
||||
)}
|
||||
|
||||
<HotkeysModal>
|
||||
<IAIIconButton
|
||||
aria-label={t('common.hotkeysLabel')}
|
||||
|
@ -1,7 +1,81 @@
|
||||
import { memo } from 'react';
|
||||
import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react';
|
||||
import i18n from 'i18n';
|
||||
import { ReactNode, memo } from 'react';
|
||||
import AddModelsPanel from './subpanels/AddModelsPanel';
|
||||
import MergeModelsPanel from './subpanels/MergeModelsPanel';
|
||||
import ModelManagerPanel from './subpanels/ModelManagerPanel';
|
||||
|
||||
type ModelManagerTabName = 'modelmanager' | 'add_models' | 'merge_models';
|
||||
|
||||
type ModelManagerTabInfo = {
|
||||
id: ModelManagerTabName;
|
||||
label: string;
|
||||
content: ReactNode;
|
||||
};
|
||||
|
||||
const modelManagerTabs: ModelManagerTabInfo[] = [
|
||||
{
|
||||
id: 'modelmanager',
|
||||
label: i18n.t('modelManager.modelManager'),
|
||||
content: <ModelManagerPanel />,
|
||||
},
|
||||
{
|
||||
id: 'add_models',
|
||||
label: i18n.t('modelManager.addModel'),
|
||||
content: <AddModelsPanel />,
|
||||
},
|
||||
{
|
||||
id: 'merge_models',
|
||||
label: i18n.t('modelManager.mergeModels'),
|
||||
content: <MergeModelsPanel />,
|
||||
},
|
||||
];
|
||||
|
||||
const ModelManagerTab = () => {
|
||||
return 'Model Manager';
|
||||
const renderTabsList = () => {
|
||||
const modelManagerTabListsToRender: ReactNode[] = [];
|
||||
modelManagerTabs.forEach((modelManagerTab) => {
|
||||
modelManagerTabListsToRender.push(
|
||||
<Tab key={modelManagerTab.id}>{modelManagerTab.label}</Tab>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<TabList
|
||||
sx={{
|
||||
w: '100%',
|
||||
color: 'base.200',
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 2,
|
||||
borderColor: 'accent.700',
|
||||
}}
|
||||
>
|
||||
{modelManagerTabListsToRender}
|
||||
</TabList>
|
||||
);
|
||||
};
|
||||
|
||||
const renderTabPanels = () => {
|
||||
const modelManagerTabPanelsToRender: ReactNode[] = [];
|
||||
modelManagerTabs.forEach((modelManagerTab) => {
|
||||
modelManagerTabPanelsToRender.push(
|
||||
<TabPanel key={modelManagerTab.id}>{modelManagerTab.content}</TabPanel>
|
||||
);
|
||||
});
|
||||
|
||||
return <TabPanels sx={{ p: 2 }}>{modelManagerTabPanelsToRender}</TabPanels>;
|
||||
};
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
isLazy
|
||||
variant="invokeAI"
|
||||
sx={{ w: 'full', h: 'full', p: 2, gap: 4, flexDirection: 'column' }}
|
||||
>
|
||||
{renderTabsList()}
|
||||
{renderTabPanels()}
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ModelManagerTab);
|
||||
|
@ -0,0 +1,10 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import AddModel from 'features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModel';
|
||||
|
||||
export default function AddModelsPanel() {
|
||||
return (
|
||||
<Flex>
|
||||
<AddModel />
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -10,13 +10,11 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import IAIButton from 'common/components/IAIButton';
|
||||
import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
|
||||
import IAIInput from 'common/components/IAIInput';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
|
||||
import React from 'react';
|
||||
|
||||
import SearchModels from './SearchModels';
|
||||
|
||||
// import { addNewModel } from 'app/socketio/actions';
|
||||
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
@ -24,12 +22,13 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { Field, Formik } from 'formik';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { InvokeModelConfigProps } from 'app/types/invokeai';
|
||||
import type { RootState } from 'app/store/store';
|
||||
import { setAddNewModelUIOption } from 'features/ui/store/uiSlice';
|
||||
import type { FieldInputProps, FormikProps } from 'formik';
|
||||
import type { InvokeModelConfigProps } from 'app/types/invokeai';
|
||||
import IAIForm from 'common/components/IAIForm';
|
||||
import { IAIFormItemWrapper } from 'common/components/IAIForms/IAIFormItemWrapper';
|
||||
import { setAddNewModelUIOption } from 'features/ui/store/uiSlice';
|
||||
import type { FieldInputProps, FormikProps } from 'formik';
|
||||
import SearchModels from './SearchModels';
|
||||
|
||||
const MIN_MODEL_SIZE = 64;
|
||||
const MAX_MODEL_SIZE = 2048;
|
@ -0,0 +1,10 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import MergeModels from 'features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel/MergeModels';
|
||||
|
||||
export default function MergeModelsPanel() {
|
||||
return (
|
||||
<Flex>
|
||||
<MergeModels />
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { RootState } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
|
||||
import { useListModelsQuery } from 'services/api/endpoints/models';
|
||||
import CheckpointModelEdit from './ModelManagerPanel/CheckpointModelEdit';
|
||||
import DiffusersModelEdit from './ModelManagerPanel/DiffusersModelEdit';
|
||||
import ModelList from './ModelManagerPanel/ModelList';
|
||||
|
||||
export default function ModelManagerPanel() {
|
||||
const { data: pipelineModels } = useListModelsQuery({
|
||||
model_type: 'pipeline',
|
||||
});
|
||||
|
||||
const openModel = useAppSelector(
|
||||
(state: RootState) => state.system.openModel
|
||||
);
|
||||
|
||||
const renderModelEditTabs = () => {
|
||||
if (!openModel || !pipelineModels) return;
|
||||
|
||||
if (pipelineModels['entities'][openModel]['model_format'] === 'diffusers') {
|
||||
return (
|
||||
<DiffusersModelEdit
|
||||
modelToEdit={openModel}
|
||||
retrievedModel={pipelineModels['entities'][openModel]}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<CheckpointModelEdit
|
||||
modelToEdit={openModel}
|
||||
retrievedModel={pipelineModels['entities'][openModel]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Flex width="100%" columnGap={8}>
|
||||
<ModelList />
|
||||
{renderModelEditTabs()}
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
import { Box, Flex, Heading, Spacer, Spinner, Text } from '@chakra-ui/react';
|
||||
import { Box, Flex, Spinner, Text } from '@chakra-ui/react';
|
||||
import IAIButton from 'common/components/IAIButton';
|
||||
import IAIInput from 'common/components/IAIInput';
|
||||
|
||||
import AddModel from './AddModel';
|
||||
import MergeModels from './MergeModels';
|
||||
import ModelListItem from './ModelListItem';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -185,13 +183,6 @@ const ModelList = () => {
|
||||
|
||||
return (
|
||||
<Flex flexDirection="column" rowGap={4} width="50%" minWidth="50%">
|
||||
<Flex justifyContent="space-between" alignItems="center" gap={2}>
|
||||
<Heading size="md">{t('modelManager.availableModels')}</Heading>
|
||||
<Spacer />
|
||||
<AddModel />
|
||||
<MergeModels />
|
||||
</Flex>
|
||||
|
||||
<IAIInput
|
||||
onChange={handleSearchFilter}
|
||||
label={t('modelManager.search')}
|
Loading…
Reference in New Issue
Block a user