added import model form and importqueue

This commit is contained in:
Jennifer Player 2024-02-20 13:39:27 -05:00 committed by psychedelicious
parent c7d462b222
commit 87ce74e05d
3 changed files with 167 additions and 4 deletions

View File

@ -701,6 +701,7 @@
"availableModels": "Available Models",
"baseModel": "Base Model",
"cached": "cached",
"cancel": "Cancel",
"cannotUseSpaces": "Cannot Use Spaces",
"checkpointFolder": "Checkpoint Folder",
"checkpointModels": "Checkpoints",
@ -743,6 +744,7 @@
"heightValidationMsg": "Default height of your model.",
"ignoreMismatch": "Ignore Mismatches Between Selected Models",
"importModels": "Import Models",
"importQueue": "Import Queue",
"inpainting": "v1 Inpainting",
"interpolationType": "Interpolation Type",
"inverseSigmoid": "Inverse Sigmoid",
@ -796,6 +798,7 @@
"pickModelType": "Pick Model Type",
"predictionType": "Prediction Type (for Stable Diffusion 2.x Models and occasional Stable Diffusion 1.x Models)",
"quickAdd": "Quick Add",
"removeFromQueue": "Remove From Queue",
"repo_id": "Repo ID",
"repoIDValidationMsg": "Online repository of your model",
"safetensorModels": "SafeTensors",

View File

@ -1,10 +1,85 @@
import { Box } from '@invoke-ai/ui-library';
import { Button, Box, Flex, FormControl, FormLabel, Heading, Input, Text, Divider } from '@invoke-ai/ui-library';
import { t } from 'i18next';
import { CSSProperties } from 'react';
import { useImportMainModelsMutation } from '../../../services/api/endpoints/models';
import { useForm } from '@mantine/form';
import { useAppDispatch } from 'app/store/storeHooks';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import { ImportQueue } from './ImportQueue';
const formStyles: CSSProperties = {
width: '100%',
};
type ExtendedImportModelConfig = {
location: string;
};
//jenn's workspace
export const ImportModels = () => {
const dispatch = useAppDispatch();
const [importMainModel, { isLoading }] = useImportMainModelsMutation();
const addModelForm = useForm({
initialValues: {
location: '',
},
});
console.log('addModelForm', addModelForm.values.location)
const handleAddModelSubmit = (values: ExtendedImportModelConfig) => {
importMainModel({ source: values.location, config: undefined })
.unwrap()
.then((_) => {
dispatch(
addToast(
makeToast({
title: t('toast.modelAddedSimple'),
status: 'success',
})
)
);
addModelForm.reset();
})
.catch((error) => {
if (error) {
dispatch(
addToast(
makeToast({
title: `${error.data.detail} `,
status: 'error',
})
)
);
}
});
};
return (
<Box layerStyle="first" p={2} borderRadius="base" w="full" h="full">
Import Models
<Box layerStyle="first" p={3} borderRadius="base" w="full" h="full">
<Box w="full" p={4}>
<Heading fontSize="xl">Add Model</Heading>
</Box>
<Box layerStyle="second" p={3} borderRadius="base" w="full" h="full">
<form onSubmit={addModelForm.onSubmit((v) => handleAddModelSubmit(v))} style={formStyles}>
<Flex gap={2} alignItems="flex-end" justifyContent="space-between">
<FormControl>
<Flex direction="column" w="full">
<FormLabel>{t('modelManager.modelLocation')}</FormLabel>
<Input {...addModelForm.getInputProps('location')} />
</Flex>
</FormControl>
<Button isDisabled={!addModelForm.values.location} isLoading={isLoading} type="submit">
{t('modelManager.addModel')}
</Button>
</Flex>
</form>
<Divider mt="5" mb="3" />
<Text>{t('modelManager.importQueue')}</Text>
<ImportQueue />
</Box>
</Box>
);
};

View File

@ -0,0 +1,85 @@
import {
Button,
Box,
Flex,
FormControl,
FormLabel,
Heading,
IconButton,
Input,
InputGroup,
InputRightElement,
Progress,
Text,
} from '@invoke-ai/ui-library';
import { t } from 'i18next';
import { useMemo } from 'react';
import { useGetModelImportsQuery } from '../../../services/api/endpoints/models';
import { useAppDispatch } from 'app/store/storeHooks';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import { PiXBold } from 'react-icons/pi';
export const ImportQueue = () => {
const dispatch = useAppDispatch();
// start with this data then pull from sockets (idk how to do that yet, also might not even use this and just use socket)
const { data } = useGetModelImportsQuery();
const progressValues = useMemo(() => {
if (!data) {
return [];
}
const values = [];
for (let i = 0; i < data.length; i++) {
let value;
if (data[i] && data[i]?.bytes && data[i]?.total_bytes) {
value = (data[i]?.bytes / data[i]?.total_bytes) * 100;
}
values.push(value || undefined);
}
return values;
}, [data]);
return (
<Box mt={3} layerStyle="first" p={3} borderRadius="base" w="full" h="full">
<Flex direction="column" gap="2">
{data?.map((model, i) => (
<Flex gap="3" w="full" alignItems="center" textAlign="center">
<Text w="20%" whiteSpace="nowrap" overflow="hidden" text-overflow="ellipsis">
{model.source.repo_id}
</Text>
<Progress
value={progressValues[i]}
isIndeterminate={progressValues[i] === undefined}
aria-label={t('accessibility.invokeProgressBar')}
h={2}
w="50%"
/>
<Text w="20%">{model.status}</Text>
{model.status === 'completed' ? (
<IconButton
isRound={true}
size="xs"
tooltip={t('modelManager.removeFromQueue')}
aria-label={t('modelManager.removeFromQueue')}
icon={<PiXBold />}
// onClick={handleRemove}
/>
) : (
<IconButton
isRound={true}
size="xs"
tooltip={t('modelManager.cancel')}
aria-label={t('modelManager.cancel')}
icon={<PiXBold />}
// onClick={handleCancel}
colorScheme="error"
/>
)}
</Flex>
))}
</Flex>
</Box>
);
};