mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
added import model form and importqueue
This commit is contained in:
parent
c7d462b222
commit
87ce74e05d
@ -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",
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user