added add all button to scan models

This commit is contained in:
Jennifer Player 2024-02-27 09:43:02 -05:00 committed by psychedelicious
parent d23f2de9d7
commit 32b8478974
4 changed files with 82 additions and 26 deletions

View File

@ -691,6 +691,7 @@
}, },
"modelManager": { "modelManager": {
"active": "active", "active": "active",
"addAll": "Add All",
"addCheckpointModel": "Add Checkpoint / Safetensor Model", "addCheckpointModel": "Add Checkpoint / Safetensor Model",
"addDifference": "Add Difference", "addDifference": "Add Difference",
"addDiffuserModel": "Add Diffusers", "addDiffuserModel": "Add Diffusers",

View File

@ -1,5 +1,6 @@
import { Box, Button, Flex, Text } from '@invoke-ai/ui-library'; import { Box, Button, Flex, Text } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks'; import { useAppDispatch } from 'app/store/storeHooks';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import { addToast } from 'features/system/store/systemSlice'; import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast'; import { makeToast } from 'features/system/util/makeToast';
import { t } from 'i18next'; import { t } from 'i18next';
@ -57,9 +58,11 @@ export const ImportQueue = () => {
</Button> </Button>
</Flex> </Flex>
<Box mt={3} layerStyle="first" p={3} borderRadius="base" w="full" h="full"> <Box mt={3} layerStyle="first" p={3} borderRadius="base" w="full" h="full">
<ScrollableContent>
<Flex flexDir="column-reverse" gap="2"> <Flex flexDir="column-reverse" gap="2">
{data?.map((model) => <ImportQueueItem key={model.id} model={model} />)} {data?.map((model) => <ImportQueueItem key={model.id} model={model} />)}
</Flex> </Flex>
</ScrollableContent>
</Box> </Box>
</Flex> </Flex>
); );

View File

@ -121,7 +121,7 @@ export const ImportQueueItem = (props: ModelListItemProps) => {
</Box> </Box>
<Box minW="20px"> <Box minW="20px">
{(model.status === 'downloading' || model.status === 'waiting') && ( {(model.status === 'downloading' || model.status === 'waiting' || model.status === 'running') && (
<IconButton <IconButton
isRound={true} isRound={true}
size="xs" size="xs"

View File

@ -1,10 +1,22 @@
import { Divider, Flex, Heading, IconButton, Input, InputGroup, InputRightElement } from '@invoke-ai/ui-library'; import {
Button,
Divider,
Flex,
Heading,
IconButton,
Input,
InputGroup,
InputRightElement,
} from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent'; import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import type { ChangeEventHandler } from 'react'; import type { ChangeEventHandler } from 'react';
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { PiXBold } from 'react-icons/pi'; import { PiXBold } from 'react-icons/pi';
import type { ScanFolderResponse } from 'services/api/endpoints/models'; import { type ScanFolderResponse, useImportMainModelsMutation } from 'services/api/endpoints/models';
import { ScanModelResultItem } from './ScanModelResultItem'; import { ScanModelResultItem } from './ScanModelResultItem';
@ -15,6 +27,9 @@ type ScanModelResultsProps = {
export const ScanModelsResults = ({ results }: ScanModelResultsProps) => { export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [searchTerm, setSearchTerm] = useState(''); const [searchTerm, setSearchTerm] = useState('');
const dispatch = useAppDispatch();
const [importMainModel] = useImportMainModelsMutation();
const filteredResults = useMemo(() => { const filteredResults = useMemo(() => {
return results.filter((result) => { return results.filter((result) => {
@ -31,6 +46,38 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
setSearchTerm(''); setSearchTerm('');
}, []); }, []);
const handleAddAll = useCallback(() => {
for (const result of filteredResults) {
if (result.is_installed) {
continue;
}
importMainModel({ source: result.path, config: undefined })
.unwrap()
.then((_) => {
dispatch(
addToast(
makeToast({
title: t('toast.modelAddedSimple'),
status: 'success',
})
)
);
})
.catch((error) => {
if (error) {
dispatch(
addToast(
makeToast({
title: `${error.data.detail} `,
status: 'error',
})
)
);
}
});
}
}, [importMainModel, filteredResults, dispatch, t]);
return ( return (
<> <>
<Divider mt={4} /> <Divider mt={4} />
@ -39,6 +86,10 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
<Heading fontSize="md" as="h4"> <Heading fontSize="md" as="h4">
{t('modelManager.scanResults')} {t('modelManager.scanResults')}
</Heading> </Heading>
<Flex alignItems="center" gap="4">
<Button onClick={handleAddAll} isDisabled={filteredResults.length === 0}>
{t('modelManager.addAll')}
</Button>
<InputGroup maxW="300px" size="xs"> <InputGroup maxW="300px" size="xs">
<Input <Input
placeholder={t('modelManager.search')} placeholder={t('modelManager.search')}
@ -61,6 +112,7 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
)} )}
</InputGroup> </InputGroup>
</Flex> </Flex>
</Flex>
<Flex height="100%" layerStyle="third" borderRadius="base" p={4} mt={4} mb={4}> <Flex height="100%" layerStyle="third" borderRadius="base" p={4} mt={4} mb={4}>
<ScrollableContent> <ScrollableContent>
<Flex flexDir="column" gap={3}> <Flex flexDir="column" gap={3}>