Merge branch 'main' into feat/install_docs_update

This commit is contained in:
Millun Atluri 2024-01-27 11:55:19 -05:00 committed by GitHub
commit c003967eaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 67 additions and 35 deletions

View File

@ -14,10 +14,12 @@ import { $openAPISchemaUrl } from 'app/store/nanostores/openAPISchemaUrl';
import { $projectId } from 'app/store/nanostores/projectId'; import { $projectId } from 'app/store/nanostores/projectId';
import { $queueId, DEFAULT_QUEUE_ID } from 'app/store/nanostores/queueId'; import { $queueId, DEFAULT_QUEUE_ID } from 'app/store/nanostores/queueId';
import { $store } from 'app/store/nanostores/store'; import { $store } from 'app/store/nanostores/store';
import { $workflowCategories } from 'app/store/nanostores/workflowCategories';
import { createStore } from 'app/store/store'; import { createStore } from 'app/store/store';
import type { PartialAppConfig } from 'app/types/invokeai'; import type { PartialAppConfig } from 'app/types/invokeai';
import Loading from 'common/components/Loading/Loading'; import Loading from 'common/components/Loading/Loading';
import AppDndContext from 'features/dnd/components/AppDndContext'; import AppDndContext from 'features/dnd/components/AppDndContext';
import type { WorkflowCategory } from 'features/nodes/types/workflow';
import type { PropsWithChildren, ReactNode } from 'react'; import type { PropsWithChildren, ReactNode } from 'react';
import React, { lazy, memo, useEffect, useMemo } from 'react'; import React, { lazy, memo, useEffect, useMemo } from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
@ -45,6 +47,7 @@ interface Props extends PropsWithChildren {
socketOptions?: Partial<ManagerOptions & SocketOptions>; socketOptions?: Partial<ManagerOptions & SocketOptions>;
isDebugging?: boolean; isDebugging?: boolean;
logo?: ReactNode; logo?: ReactNode;
workflowCategories?: WorkflowCategory[];
} }
const InvokeAIUI = ({ const InvokeAIUI = ({
@ -62,6 +65,7 @@ const InvokeAIUI = ({
socketOptions, socketOptions,
isDebugging = false, isDebugging = false,
logo, logo,
workflowCategories,
}: Props) => { }: Props) => {
useEffect(() => { useEffect(() => {
// configure API client token // configure API client token
@ -156,6 +160,16 @@ const InvokeAIUI = ({
}; };
}, [logo]); }, [logo]);
useEffect(() => {
if (workflowCategories) {
$workflowCategories.set(workflowCategories);
}
return () => {
$workflowCategories.set([]);
};
}, [workflowCategories]);
useEffect(() => { useEffect(() => {
if (socketOptions) { if (socketOptions) {
$socketOptions.set(socketOptions); $socketOptions.set(socketOptions);

View File

@ -0,0 +1,7 @@
import type { WorkflowCategory } from 'features/nodes/types/workflow';
import { atom } from 'nanostores';
export const $workflowCategories = atom<WorkflowCategory[]>([
'user',
'default',
]);

View File

@ -11,10 +11,10 @@ import {
Input, Input,
InputGroup, InputGroup,
InputRightElement, InputRightElement,
Spacer,
} from '@invoke-ai/ui'; } from '@invoke-ai/ui';
import { useStore } from '@nanostores/react'; import { useStore } from '@nanostores/react';
import { $projectId } from 'app/store/nanostores/projectId'; import { $projectId } from 'app/store/nanostores/projectId';
import { $workflowCategories } from 'app/store/nanostores/workflowCategories';
import { import {
IAINoContentFallback, IAINoContentFallback,
IAINoContentFallbackWithSpinner, IAINoContentFallbackWithSpinner,
@ -58,10 +58,13 @@ const DIRECTION_OPTIONS: ComboboxOption[] = [
const WorkflowLibraryList = () => { const WorkflowLibraryList = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [category, setCategory] = useState<WorkflowCategory>('user'); const workflowCategories = useStore($workflowCategories);
const [selectedCategory, setSelectedCategory] =
useState<WorkflowCategory>('user');
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
const [query, setQuery] = useState(''); const [query, setQuery] = useState('');
const projectId = useStore($projectId); const projectId = useStore($projectId);
const orderByOptions = useMemo(() => { const orderByOptions = useMemo(() => {
return projectId return projectId
? ORDER_BY_OPTIONS.filter((option) => option.value !== 'opened_at') ? ORDER_BY_OPTIONS.filter((option) => option.value !== 'opened_at')
@ -75,13 +78,13 @@ const WorkflowLibraryList = () => {
const [debouncedQuery] = useDebounce(query, 500); const [debouncedQuery] = useDebounce(query, 500);
const queryArg = useMemo<Parameters<typeof useListWorkflowsQuery>[0]>(() => { const queryArg = useMemo<Parameters<typeof useListWorkflowsQuery>[0]>(() => {
if (category !== 'default') { if (selectedCategory !== 'default') {
return { return {
page, page,
per_page: PER_PAGE, per_page: PER_PAGE,
order_by, order_by,
direction, direction,
category, category: selectedCategory,
query: debouncedQuery, query: debouncedQuery,
}; };
} }
@ -90,10 +93,10 @@ const WorkflowLibraryList = () => {
per_page: PER_PAGE, per_page: PER_PAGE,
order_by: 'name' as const, order_by: 'name' as const,
direction: 'ASC' as const, direction: 'ASC' as const,
category, category: selectedCategory,
query: debouncedQuery, query: debouncedQuery,
}; };
}, [category, debouncedQuery, direction, order_by, page]); }, [selectedCategory, debouncedQuery, direction, order_by, page]);
const { data, isLoading, isError, isFetching } = const { data, isLoading, isError, isFetching } =
useListWorkflowsQuery(queryArg); useListWorkflowsQuery(queryArg);
@ -154,43 +157,43 @@ const WorkflowLibraryList = () => {
); );
const handleSetCategory = useCallback((category: WorkflowCategory) => { const handleSetCategory = useCallback((category: WorkflowCategory) => {
setCategory(category); setSelectedCategory(category);
setPage(0); setPage(0);
}, []); }, []);
return ( return (
<> <>
<Flex gap={4} alignItems="center" h={10} flexShrink={0} flexGrow={0}> <Flex
<ButtonGroup> gap={4}
<Button alignItems="center"
variant={category === 'user' ? undefined : 'ghost'} h={16}
onClick={handleSetCategory.bind(null, 'user')} flexShrink={0}
isChecked={category === 'user'} flexGrow={0}
justifyContent="space-between"
> >
{t('workflows.userWorkflows')} <ButtonGroup alignSelf="flex-end">
</Button> {workflowCategories.map((category) => (
{projectId ? (
<Button <Button
variant={category === 'project' ? undefined : 'ghost'} key={category}
onClick={handleSetCategory.bind(null, 'project')} variant={selectedCategory === category ? undefined : 'ghost'}
isChecked={category === 'project'} onClick={handleSetCategory.bind(null, category)}
isChecked={selectedCategory === category}
> >
{t('workflows.projectWorkflows')} {t(`workflows.${category}Workflows`)}
</Button> </Button>
) : ( ))}
<Button
variant={category === 'default' ? undefined : 'ghost'}
onClick={handleSetCategory.bind(null, 'default')}
isChecked={category === 'default'}
>
{t('workflows.defaultWorkflows')}
</Button>
)}
</ButtonGroup> </ButtonGroup>
<Spacer /> {selectedCategory !== 'default' && (
{category !== 'default' && (
<> <>
<FormControl isDisabled={isFetching} w={64} minW={56}> <FormControl
isDisabled={isFetching}
sx={{
flexDir: 'column',
alignItems: 'flex-start',
gap: 1,
maxW: 56,
}}
>
<FormLabel>{t('common.orderBy')}</FormLabel> <FormLabel>{t('common.orderBy')}</FormLabel>
<Combobox <Combobox
value={valueOrderBy} value={valueOrderBy}
@ -198,7 +201,15 @@ const WorkflowLibraryList = () => {
onChange={onChangeOrderBy} onChange={onChangeOrderBy}
/> />
</FormControl> </FormControl>
<FormControl isDisabled={isFetching} w={64} minW={56}> <FormControl
isDisabled={isFetching}
sx={{
flexDir: 'column',
alignItems: 'flex-start',
gap: 1,
maxW: 56,
}}
>
<FormLabel>{t('common.direction')}</FormLabel> <FormLabel>{t('common.direction')}</FormLabel>
<Combobox <Combobox
value={valueDirection} value={valueDirection}
@ -208,7 +219,7 @@ const WorkflowLibraryList = () => {
</FormControl> </FormControl>
</> </>
)} )}
<InputGroup w="20rem"> <InputGroup w="20rem" alignSelf="flex-end">
<Input <Input
placeholder={t('workflows.searchWorkflows')} placeholder={t('workflows.searchWorkflows')}
value={query} value={query}