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": {
"active": "active",
"addAll": "Add All",
"addCheckpointModel": "Add Checkpoint / Safetensor Model",
"addDifference": "Add Difference",
"addDiffuserModel": "Add Diffusers",

View File

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

View File

@ -121,7 +121,7 @@ export const ImportQueueItem = (props: ModelListItemProps) => {
</Box>
<Box minW="20px">
{(model.status === 'downloading' || model.status === 'waiting') && (
{(model.status === 'downloading' || model.status === 'waiting' || model.status === 'running') && (
<IconButton
isRound={true}
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 { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import type { ChangeEventHandler } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
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';
@ -15,6 +27,9 @@ type ScanModelResultsProps = {
export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
const { t } = useTranslation();
const [searchTerm, setSearchTerm] = useState('');
const dispatch = useAppDispatch();
const [importMainModel] = useImportMainModelsMutation();
const filteredResults = useMemo(() => {
return results.filter((result) => {
@ -31,6 +46,38 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
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 (
<>
<Divider mt={4} />
@ -39,27 +86,32 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
<Heading fontSize="md" as="h4">
{t('modelManager.scanResults')}
</Heading>
<InputGroup maxW="300px" size="xs">
<Input
placeholder={t('modelManager.search')}
value={searchTerm}
data-testid="board-search-input"
onChange={handleSearch}
size="xs"
/>
<Flex alignItems="center" gap="4">
<Button onClick={handleAddAll} isDisabled={filteredResults.length === 0}>
{t('modelManager.addAll')}
</Button>
<InputGroup maxW="300px" size="xs">
<Input
placeholder={t('modelManager.search')}
value={searchTerm}
data-testid="board-search-input"
onChange={handleSearch}
size="xs"
/>
{searchTerm && (
<InputRightElement h="full" pe={2}>
<IconButton
size="sm"
variant="link"
aria-label={t('boards.clearSearch')}
icon={<PiXBold />}
onClick={clearSearch}
/>
</InputRightElement>
)}
</InputGroup>
{searchTerm && (
<InputRightElement h="full" pe={2}>
<IconButton
size="sm"
variant="link"
aria-label={t('boards.clearSearch')}
icon={<PiXBold />}
onClick={clearSearch}
/>
</InputRightElement>
)}
</InputGroup>
</Flex>
</Flex>
<Flex height="100%" layerStyle="third" borderRadius="base" p={4} mt={4} mb={4}>
<ScrollableContent>