mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): misc MM cleanup
This commit is contained in:
parent
816fb53a14
commit
b5ce28e60b
@ -11,7 +11,7 @@ const AddModels = () => {
|
|||||||
const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>('simple');
|
const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>('simple');
|
||||||
const handleAddModelSimple = useCallback(() => setAddModelMode('simple'), []);
|
const handleAddModelSimple = useCallback(() => setAddModelMode('simple'), []);
|
||||||
const handleAddModelAdvanced = useCallback(() => setAddModelMode('advanced'), []);
|
const handleAddModelAdvanced = useCallback(() => setAddModelMode('advanced'), []);
|
||||||
const { data } = useGetModelImportsQuery({});
|
const { data } = useGetModelImportsQuery();
|
||||||
console.log({ data });
|
console.log({ data });
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column" width="100%" overflow="scroll" maxHeight={window.innerHeight - 250} gap={4}>
|
<Flex flexDirection="column" width="100%" overflow="scroll" maxHeight={window.innerHeight - 250} gap={4}>
|
||||||
@ -27,7 +27,7 @@ const AddModels = () => {
|
|||||||
{addModelMode === 'simple' && <SimpleAddModels />}
|
{addModelMode === 'simple' && <SimpleAddModels />}
|
||||||
{addModelMode === 'advanced' && <AdvancedAddModels />}
|
{addModelMode === 'advanced' && <AdvancedAddModels />}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex>{data?.map((model) => <Text>{model.status}</Text>)}</Flex>
|
<Flex>{data?.map((model) => <Text key={model.id}>{model.status}</Text>)}</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ export const ScanModelsForm = () => {
|
|||||||
setErrorMessage(error.data.detail);
|
setErrorMessage(error.data.detail);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [scanPath]);
|
}, [_scanModels, scanPath]);
|
||||||
|
|
||||||
const handleSetScanPath: ChangeEventHandler<HTMLInputElement> = useCallback((e) => {
|
const handleSetScanPath: ChangeEventHandler<HTMLInputElement> = useCallback((e) => {
|
||||||
setScanPath(e.target.value);
|
setScanPath(e.target.value);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Box, Button, Flex, Heading } from '@invoke-ai/ui-library';
|
import { Box, Button, Flex, Heading } from '@invoke-ai/ui-library';
|
||||||
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { SyncModelsIconButton } from 'features/modelManager/components/SyncModels/SyncModelsIconButton';
|
import { SyncModelsIconButton } from 'features/modelManager/components/SyncModels/SyncModelsIconButton';
|
||||||
|
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import ModelList from './ModelManagerPanel/ModelList';
|
import ModelList from './ModelManagerPanel/ModelList';
|
||||||
import { ModelListNavigation } from './ModelManagerPanel/ModelListNavigation';
|
import { ModelListNavigation } from './ModelManagerPanel/ModelListNavigation';
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { useAppDispatch } from '../../../app/store/storeHooks';
|
|
||||||
import { setSelectedModelKey } from '../store/modelManagerV2Slice';
|
|
||||||
|
|
||||||
export const ModelManager = () => {
|
export const ModelManager = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
|
Box,
|
||||||
Button,
|
Button,
|
||||||
ConfirmationAlertDialog,
|
ConfirmationAlertDialog,
|
||||||
Flex,
|
Flex,
|
||||||
@ -8,7 +9,6 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
Box,
|
|
||||||
} from '@invoke-ai/ui-library';
|
} from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||||
|
@ -40,9 +40,8 @@ export const ModelTypeFilter = () => {
|
|||||||
<MenuItem onClick={clearModelType}>All Models</MenuItem>
|
<MenuItem onClick={clearModelType}>All Models</MenuItem>
|
||||||
{Object.keys(MODEL_TYPE_LABELS).map((option) => (
|
{Object.keys(MODEL_TYPE_LABELS).map((option) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
sx={{
|
key={option}
|
||||||
backgroundColor: filteredModelType === option ? 'base.700' : 'transparent',
|
bg={filteredModelType === option ? 'base.700' : 'transparent'}
|
||||||
}}
|
|
||||||
onClick={selectModelType.bind(null, option)}
|
onClick={selectModelType.bind(null, option)}
|
||||||
>
|
>
|
||||||
{MODEL_TYPE_LABELS[option]}
|
{MODEL_TYPE_LABELS[option]}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Box } from '@invoke-ai/ui-library';
|
import { Box } from '@invoke-ai/ui-library';
|
||||||
import { useAppSelector } from '../../../app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
|
||||||
import { ImportModels } from './ImportModels';
|
import { ImportModels } from './ImportModels';
|
||||||
import { Model } from './ModelPanel/Model';
|
import { Model } from './ModelPanel/Model';
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox } from '@invoke-ai/ui-library';
|
||||||
import { typedMemo } from 'common/util/typedMemo';
|
import { typedMemo } from 'common/util/typedMemo';
|
||||||
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
@ -8,8 +8,8 @@ import type { AnyModelConfig } from 'services/api/types';
|
|||||||
|
|
||||||
const options: ComboboxOption[] = [
|
const options: ComboboxOption[] = [
|
||||||
{ value: 'none', label: '-' },
|
{ value: 'none', label: '-' },
|
||||||
{ value: true as any, label: 'True' },
|
{ value: 'true', label: 'True' },
|
||||||
{ value: false as any, label: 'False' },
|
{ value: 'false', label: 'False' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const BooleanSelect = <T extends AnyModelConfig>(props: UseControllerProps<T>) => {
|
const BooleanSelect = <T extends AnyModelConfig>(props: UseControllerProps<T>) => {
|
||||||
@ -17,7 +17,7 @@ const BooleanSelect = <T extends AnyModelConfig>(props: UseControllerProps<T>) =
|
|||||||
const value = useMemo(() => options.find((o) => o.value === field.value), [field.value]);
|
const value = useMemo(() => options.find((o) => o.value === field.value), [field.value]);
|
||||||
const onChange = useCallback<ComboboxOnChange>(
|
const onChange = useCallback<ComboboxOnChange>(
|
||||||
(v) => {
|
(v) => {
|
||||||
v?.value === 'none' ? field.onChange(undefined) : field.onChange(v?.value);
|
v?.value === 'none' ? field.onChange(undefined) : field.onChange(v?.value === 'true');
|
||||||
},
|
},
|
||||||
[field]
|
[field]
|
||||||
);
|
);
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox } from '@invoke-ai/ui-library';
|
||||||
import { typedMemo } from 'common/util/typedMemo';
|
import { typedMemo } from 'common/util/typedMemo';
|
||||||
import { LORA_MODEL_FORMAT_MAP, MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
import { LORA_MODEL_FORMAT_MAP } from 'features/parameters/types/constants';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import type { UseControllerProps } from 'react-hook-form';
|
import type { UseControllerProps } from 'react-hook-form';
|
||||||
import { useController } from 'react-hook-form';
|
import { useController } from 'react-hook-form';
|
||||||
import type { AnyModelConfig } from 'services/api/types';
|
import type { AnyModelConfig } from 'services/api/types';
|
||||||
|
|
||||||
const options: ComboboxOption[] = [
|
|
||||||
{ value: 'sd-1', label: MODEL_TYPE_MAP['sd-1'] },
|
|
||||||
{ value: 'sd-2', label: MODEL_TYPE_MAP['sd-2'] },
|
|
||||||
{ value: 'sdxl', label: MODEL_TYPE_MAP['sdxl'] },
|
|
||||||
{ value: 'sdxl-refiner', label: MODEL_TYPE_MAP['sdxl-refiner'] },
|
|
||||||
];
|
|
||||||
|
|
||||||
const ModelFormatSelect = <T extends AnyModelConfig>(props: UseControllerProps<T>) => {
|
const ModelFormatSelect = <T extends AnyModelConfig>(props: UseControllerProps<T>) => {
|
||||||
const { field, formState } = useController(props);
|
const { field, formState } = useController(props);
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox } from '@invoke-ai/ui-library';
|
||||||
import { typedMemo } from 'common/util/typedMemo';
|
import { typedMemo } from 'common/util/typedMemo';
|
||||||
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
import { MODEL_TYPE_LABELS } from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelTypeFilter';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import type { UseControllerProps } from 'react-hook-form';
|
import type { UseControllerProps } from 'react-hook-form';
|
||||||
import { useController } from 'react-hook-form';
|
import { useController } from 'react-hook-form';
|
||||||
import type { AnyModelConfig } from 'services/api/types';
|
import type { AnyModelConfig } from 'services/api/types';
|
||||||
import { MODEL_TYPE_LABELS } from '../../ModelManagerPanel/ModelTypeFilter';
|
|
||||||
|
|
||||||
const options: ComboboxOption[] = [
|
const options: ComboboxOption[] = [
|
||||||
{ value: 'main', label: MODEL_TYPE_LABELS['main'] as string },
|
{ value: 'main', label: MODEL_TYPE_LABELS['main'] as string },
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox } from '@invoke-ai/ui-library';
|
||||||
import { typedMemo } from 'common/util/typedMemo';
|
import { typedMemo } from 'common/util/typedMemo';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import type { UseControllerProps } from 'react-hook-form';
|
import type { UseControllerProps } from 'react-hook-form';
|
||||||
import { useController } from 'react-hook-form';
|
import { useController } from 'react-hook-form';
|
||||||
import type { AnyModelConfig, CheckpointModelConfig, DiffusersModelConfig } from 'services/api/types';
|
import type { AnyModelConfig } from 'services/api/types';
|
||||||
|
|
||||||
const options: ComboboxOption[] = [
|
const options: ComboboxOption[] = [
|
||||||
{ value: 'normal', label: 'Normal' },
|
{ value: 'normal', label: 'Normal' },
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useAppSelector } from '../../../../app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
|
||||||
import { ModelEdit } from './ModelEdit';
|
import { ModelEdit } from './ModelEdit';
|
||||||
import { ModelView } from './ModelView';
|
import { ModelView } from './ModelView';
|
||||||
|
|
||||||
|
@ -1,41 +1,43 @@
|
|||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
|
||||||
import { useAppDispatch, useAppSelector } from '../../../../app/store/storeHooks';
|
|
||||||
import { useGetModelConfigQuery, useUpdateModelsMutation } from '../../../../services/api/endpoints/models';
|
|
||||||
import {
|
import {
|
||||||
Flex,
|
|
||||||
Text,
|
|
||||||
Heading,
|
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Flex,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormLabel,
|
|
||||||
Textarea,
|
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
|
FormLabel,
|
||||||
|
Heading,
|
||||||
|
Input,
|
||||||
|
Text,
|
||||||
|
Textarea,
|
||||||
} from '@invoke-ai/ui-library';
|
} from '@invoke-ai/ui-library';
|
||||||
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { setSelectedModelMode } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||||
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import {
|
import type { SubmitHandler } from 'react-hook-form';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useGetModelConfigQuery, useUpdateModelsMutation } from 'services/api/endpoints/models';
|
||||||
|
import type {
|
||||||
AnyModelConfig,
|
AnyModelConfig,
|
||||||
CheckpointModelConfig,
|
CheckpointModelConfig,
|
||||||
ControlNetConfig,
|
ControlNetModelConfig,
|
||||||
DiffusersModelConfig,
|
DiffusersModelConfig,
|
||||||
IPAdapterConfig,
|
IPAdapterModelConfig,
|
||||||
LoRAConfig,
|
LoRAModelConfig,
|
||||||
T2IAdapterConfig,
|
T2IAdapterModelConfig,
|
||||||
TextualInversionConfig,
|
TextualInversionModelConfig,
|
||||||
VAEConfig,
|
VAEModelConfig,
|
||||||
} from '../../../../services/api/types';
|
} from 'services/api/types';
|
||||||
import { setSelectedModelMode } from '../../store/modelManagerV2Slice';
|
|
||||||
import BaseModelSelect from './Fields/BaseModelSelect';
|
import BaseModelSelect from './Fields/BaseModelSelect';
|
||||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
|
||||||
import ModelTypeSelect from './Fields/ModelTypeSelect';
|
|
||||||
import ModelVariantSelect from './Fields/ModelVariantSelect';
|
|
||||||
import RepoVariantSelect from './Fields/RepoVariantSelect';
|
|
||||||
import PredictionTypeSelect from './Fields/PredictionTypeSelect';
|
|
||||||
import BooleanSelect from './Fields/BooleanSelect';
|
import BooleanSelect from './Fields/BooleanSelect';
|
||||||
import ModelFormatSelect from './Fields/ModelFormatSelect';
|
import ModelFormatSelect from './Fields/ModelFormatSelect';
|
||||||
import { useTranslation } from 'react-i18next';
|
import ModelTypeSelect from './Fields/ModelTypeSelect';
|
||||||
import { addToast } from '../../../system/store/systemSlice';
|
import ModelVariantSelect from './Fields/ModelVariantSelect';
|
||||||
import { makeToast } from '../../../system/util/makeToast';
|
import PredictionTypeSelect from './Fields/PredictionTypeSelect';
|
||||||
|
import RepoVariantSelect from './Fields/RepoVariantSelect';
|
||||||
|
|
||||||
export const ModelEdit = () => {
|
export const ModelEdit = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
@ -63,19 +65,19 @@ export const ModelEdit = () => {
|
|||||||
|
|
||||||
switch (modelType) {
|
switch (modelType) {
|
||||||
case 'lora':
|
case 'lora':
|
||||||
return data as LoRAConfig;
|
return data as LoRAModelConfig;
|
||||||
case 'embedding':
|
case 'embedding':
|
||||||
return data as TextualInversionConfig;
|
return data as TextualInversionModelConfig;
|
||||||
case 't2i_adapter':
|
case 't2i_adapter':
|
||||||
return data as T2IAdapterConfig;
|
return data as T2IAdapterModelConfig;
|
||||||
case 'ip_adapter':
|
case 'ip_adapter':
|
||||||
return data as IPAdapterConfig;
|
return data as IPAdapterModelConfig;
|
||||||
case 'controlnet':
|
case 'controlnet':
|
||||||
return data as ControlNetConfig;
|
return data as ControlNetModelConfig;
|
||||||
case 'vae':
|
case 'vae':
|
||||||
return data as VAEConfig;
|
return data as VAEModelConfig;
|
||||||
default:
|
default:
|
||||||
return data as DiffusersModelConfig;
|
return null;
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
|
import { Box,Button, Flex, Heading, Text } from '@invoke-ai/ui-library';
|
||||||
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 { useGetModelMetadataQuery, useGetModelConfigQuery } from '../../../../services/api/endpoints/models';
|
import DataViewer from 'features/gallery/components/ImageMetadataViewer/DataViewer';
|
||||||
import { Flex, Text, Heading, Button, Box } from '@invoke-ai/ui-library';
|
import { setSelectedModelMode } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||||
import DataViewer from '../../../gallery/components/ImageMetadataViewer/DataViewer';
|
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import {
|
|
||||||
CheckpointModelConfig,
|
|
||||||
ControlNetConfig,
|
|
||||||
DiffusersModelConfig,
|
|
||||||
IPAdapterConfig,
|
|
||||||
LoRAConfig,
|
|
||||||
T2IAdapterConfig,
|
|
||||||
TextualInversionConfig,
|
|
||||||
VAEConfig,
|
|
||||||
} from '../../../../services/api/types';
|
|
||||||
import { ModelAttrView } from './ModelAttrView';
|
|
||||||
import { IoPencil } from 'react-icons/io5';
|
import { IoPencil } from 'react-icons/io5';
|
||||||
import { setSelectedModelMode } from '../../store/modelManagerV2Slice';
|
import { useGetModelConfigQuery,useGetModelMetadataQuery } from 'services/api/endpoints/models';
|
||||||
|
import type {
|
||||||
|
CheckpointModelConfig,
|
||||||
|
ControlNetModelConfig,
|
||||||
|
DiffusersModelConfig,
|
||||||
|
IPAdapterModelConfig,
|
||||||
|
LoRAModelConfig,
|
||||||
|
T2IAdapterModelConfig,
|
||||||
|
TextualInversionModelConfig,
|
||||||
|
VAEModelConfig,
|
||||||
|
} from 'services/api/types';
|
||||||
|
|
||||||
|
import { ModelAttrView } from './ModelAttrView';
|
||||||
|
|
||||||
export const ModelView = () => {
|
export const ModelView = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
@ -41,17 +42,17 @@ export const ModelView = () => {
|
|||||||
|
|
||||||
switch (modelType) {
|
switch (modelType) {
|
||||||
case 'lora':
|
case 'lora':
|
||||||
return data as LoRAConfig;
|
return data as LoRAModelConfig;
|
||||||
case 'embedding':
|
case 'embedding':
|
||||||
return data as TextualInversionConfig;
|
return data as TextualInversionModelConfig;
|
||||||
case 't2i_adapter':
|
case 't2i_adapter':
|
||||||
return data as T2IAdapterConfig;
|
return data as T2IAdapterModelConfig;
|
||||||
case 'ip_adapter':
|
case 'ip_adapter':
|
||||||
return data as IPAdapterConfig;
|
return data as IPAdapterModelConfig;
|
||||||
case 'controlnet':
|
case 'controlnet':
|
||||||
return data as ControlNetConfig;
|
return data as ControlNetModelConfig;
|
||||||
case 'vae':
|
case 'vae':
|
||||||
return data as VAEConfig;
|
return data as VAEModelConfig;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,9 @@
|
|||||||
import { Flex, Heading, Tab, TabList, TabPanel, TabPanels, Tabs, Box, Button } from '@invoke-ai/ui-library';
|
import { Flex } from '@invoke-ai/ui-library';
|
||||||
import ImportModelsPanel from 'features/modelManager/subpanels/ImportModelsPanel';
|
import { ModelManager } from 'features/modelManagerV2/subpanels/ModelManager';
|
||||||
import MergeModelsPanel from 'features/modelManager/subpanels/MergeModelsPanel';
|
import { ModelPane } from 'features/modelManagerV2/subpanels/ModelPane';
|
||||||
import ModelManagerPanel from 'features/modelManager/subpanels/ModelManagerPanel';
|
import { memo } from 'react';
|
||||||
import ModelManagerSettingsPanel from 'features/modelManager/subpanels/ModelManagerSettingsPanel';
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import { memo, useMemo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { SyncModelsIconButton } from '../../../modelManager/components/SyncModels/SyncModelsIconButton';
|
|
||||||
import { ModelManager } from '../../../modelManagerV2/subpanels/ModelManager';
|
|
||||||
import { ModelPane } from '../../../modelManagerV2/subpanels/ModelPane';
|
|
||||||
|
|
||||||
type ModelManagerTabName = 'modelManager' | 'importModels' | 'mergeModels' | 'settings';
|
|
||||||
|
|
||||||
const ModelManagerTab = () => {
|
const ModelManagerTab = () => {
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex w="full" h="full" gap="2">
|
<Flex w="full" h="full" gap="2">
|
||||||
<ModelManager />
|
<ModelManager />
|
||||||
|
Loading…
Reference in New Issue
Block a user