mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
workflow library updates (#5568)
* dont show duplicate toasts if workflow actions fail due to auth * dynamic order by options based on projectId * add endpointName to authtoast to makeit unique per endpoint * lint * update toast logic to check based on endpoint name w type safety * fix save as endpoit name * lint * fix type --------- Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
This commit is contained in:
parent
57dafd294d
commit
89da976949
@ -61,13 +61,21 @@ const WorkflowLibraryList = () => {
|
||||
const [category, setCategory] = useState<WorkflowCategory>('user');
|
||||
const [page, setPage] = useState(0);
|
||||
const [query, setQuery] = useState('');
|
||||
const [order_by, setOrderBy] = useState<WorkflowRecordOrderBy>('opened_at');
|
||||
const projectId = useStore($projectId);
|
||||
const orderByOptions = useMemo(() => {
|
||||
return projectId
|
||||
? ORDER_BY_OPTIONS.filter((option) => option.value !== 'opened_at')
|
||||
: ORDER_BY_OPTIONS;
|
||||
}, [projectId]);
|
||||
|
||||
const [order_by, setOrderBy] = useState<WorkflowRecordOrderBy>(
|
||||
orderByOptions[0]?.value as WorkflowRecordOrderBy
|
||||
);
|
||||
const [direction, setDirection] = useState<SQLiteDirection>('ASC');
|
||||
const [debouncedQuery] = useDebounce(query, 500);
|
||||
const projectId = useStore($projectId);
|
||||
|
||||
const queryArg = useMemo<Parameters<typeof useListWorkflowsQuery>[0]>(() => {
|
||||
if (category === 'user') {
|
||||
if (category !== 'default') {
|
||||
return {
|
||||
page,
|
||||
per_page: PER_PAGE,
|
||||
@ -101,8 +109,8 @@ const WorkflowLibraryList = () => {
|
||||
[order_by]
|
||||
);
|
||||
const valueOrderBy = useMemo(
|
||||
() => ORDER_BY_OPTIONS.find((o) => o.value === order_by),
|
||||
[order_by]
|
||||
() => orderByOptions.find((o) => o.value === order_by),
|
||||
[order_by, orderByOptions]
|
||||
);
|
||||
|
||||
const onChangeDirection = useCallback<ComboboxOnChange>(
|
||||
@ -186,7 +194,7 @@ const WorkflowLibraryList = () => {
|
||||
<FormLabel>{t('common.orderBy')}</FormLabel>
|
||||
<Combobox
|
||||
value={valueOrderBy}
|
||||
options={ORDER_BY_OPTIONS}
|
||||
options={orderByOptions}
|
||||
onChange={onChangeOrderBy}
|
||||
/>
|
||||
</FormControl>
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { useToast } from '@invoke-ai/ui';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDeleteWorkflowMutation } from 'services/api/endpoints/workflows';
|
||||
import {
|
||||
useDeleteWorkflowMutation,
|
||||
workflowsApi,
|
||||
} from 'services/api/endpoints/workflows';
|
||||
|
||||
type UseDeleteLibraryWorkflowOptions = {
|
||||
onSuccess?: () => void;
|
||||
@ -22,6 +26,7 @@ export const useDeleteLibraryWorkflow: UseDeleteLibraryWorkflow = ({
|
||||
onError,
|
||||
}) => {
|
||||
const toaster = useAppToaster();
|
||||
const toast = useToast();
|
||||
const { t } = useTranslation();
|
||||
const [_deleteWorkflow, deleteWorkflowResult] = useDeleteWorkflowMutation();
|
||||
|
||||
@ -34,14 +39,20 @@ export const useDeleteLibraryWorkflow: UseDeleteLibraryWorkflow = ({
|
||||
});
|
||||
onSuccess && onSuccess();
|
||||
} catch {
|
||||
toaster({
|
||||
title: t('toast.problemDeletingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
if (
|
||||
!toast.isActive(
|
||||
`auth-error-toast-${workflowsApi.endpoints.deleteWorkflow.name}`
|
||||
)
|
||||
) {
|
||||
toaster({
|
||||
title: t('toast.problemDeletingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
onError && onError();
|
||||
}
|
||||
},
|
||||
[_deleteWorkflow, toaster, t, onSuccess, onError]
|
||||
[_deleteWorkflow, toaster, t, onSuccess, onError, toast]
|
||||
);
|
||||
|
||||
return { deleteWorkflow, deleteWorkflowResult };
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { useToast } from '@invoke-ai/ui';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLazyGetWorkflowQuery } from 'services/api/endpoints/workflows';
|
||||
import {
|
||||
useLazyGetWorkflowQuery,
|
||||
workflowsApi,
|
||||
} from 'services/api/endpoints/workflows';
|
||||
|
||||
type UseGetAndLoadLibraryWorkflowOptions = {
|
||||
onSuccess?: () => void;
|
||||
@ -25,6 +29,7 @@ export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({
|
||||
}) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const toaster = useAppToaster();
|
||||
const toast = useToast();
|
||||
const { t } = useTranslation();
|
||||
const [_getAndLoadWorkflow, getAndLoadWorkflowResult] =
|
||||
useLazyGetWorkflowQuery();
|
||||
@ -38,14 +43,20 @@ export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({
|
||||
// No toast - the listener for this action does that after the workflow is loaded
|
||||
onSuccess && onSuccess();
|
||||
} catch {
|
||||
toaster({
|
||||
title: t('toast.problemRetrievingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
if (
|
||||
!toast.isActive(
|
||||
`auth-error-toast-${workflowsApi.endpoints.getWorkflow.name}`
|
||||
)
|
||||
) {
|
||||
toaster({
|
||||
title: t('toast.problemRetrievingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
onError && onError();
|
||||
}
|
||||
},
|
||||
[_getAndLoadWorkflow, dispatch, onSuccess, toaster, t, onError]
|
||||
[_getAndLoadWorkflow, dispatch, onSuccess, toaster, t, onError, toast]
|
||||
);
|
||||
|
||||
return { getAndLoadWorkflow, getAndLoadWorkflowResult };
|
||||
|
@ -12,6 +12,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
useCreateWorkflowMutation,
|
||||
useUpdateWorkflowMutation,
|
||||
workflowsApi,
|
||||
} from 'services/api/endpoints/workflows';
|
||||
import type { O } from 'ts-toolbelt';
|
||||
|
||||
@ -60,12 +61,23 @@ export const useSaveLibraryWorkflow: UseSaveLibraryWorkflow = () => {
|
||||
isClosable: true,
|
||||
});
|
||||
} catch (e) {
|
||||
toast.update(toastRef.current, {
|
||||
title: t('workflows.problemSavingWorkflow'),
|
||||
status: 'error',
|
||||
duration: 1000,
|
||||
isClosable: true,
|
||||
});
|
||||
if (
|
||||
!toast.isActive(
|
||||
`auth-error-toast-${workflowsApi.endpoints.createWorkflow.name}`
|
||||
) &&
|
||||
!toast.isActive(
|
||||
`auth-error-toast-${workflowsApi.endpoints.updateWorkflow.name}`
|
||||
)
|
||||
) {
|
||||
toast.update(toastRef.current, {
|
||||
title: t('workflows.problemSavingWorkflow'),
|
||||
status: 'error',
|
||||
duration: 1000,
|
||||
isClosable: true,
|
||||
});
|
||||
} else {
|
||||
toast.close(toastRef.current);
|
||||
}
|
||||
}
|
||||
}, [updateWorkflow, dispatch, toast, t, createWorkflow]);
|
||||
return {
|
||||
|
@ -9,7 +9,10 @@ import {
|
||||
} from 'features/nodes/store/workflowSlice';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCreateWorkflowMutation } from 'services/api/endpoints/workflows';
|
||||
import {
|
||||
useCreateWorkflowMutation,
|
||||
workflowsApi,
|
||||
} from 'services/api/endpoints/workflows';
|
||||
|
||||
type SaveWorkflowAsArg = {
|
||||
name: string;
|
||||
@ -59,12 +62,20 @@ export const useSaveWorkflowAs: UseSaveWorkflowAs = () => {
|
||||
});
|
||||
} catch (e) {
|
||||
onError && onError();
|
||||
toast.update(toastRef.current, {
|
||||
title: t('workflows.problemSavingWorkflow'),
|
||||
status: 'error',
|
||||
duration: 1000,
|
||||
isClosable: true,
|
||||
});
|
||||
if (
|
||||
!toast.isActive(
|
||||
`auth-error-toast-${workflowsApi.endpoints.createWorkflow.name}`
|
||||
)
|
||||
) {
|
||||
toast.update(toastRef.current, {
|
||||
title: t('workflows.problemSavingWorkflow'),
|
||||
status: 'error',
|
||||
duration: 1000,
|
||||
isClosable: true,
|
||||
});
|
||||
} else {
|
||||
toast.close(toastRef.current);
|
||||
}
|
||||
}
|
||||
},
|
||||
[toast, createWorkflow, dispatch, t]
|
||||
|
@ -27,7 +27,8 @@ export const authToastMiddleware: Middleware =
|
||||
if (isRejectedWithValue(action)) {
|
||||
try {
|
||||
const parsed = zRejectedForbiddenAction.parse(action);
|
||||
if (parsed.meta?.arg?.endpointName === 'getImageDTO') {
|
||||
const endpointName = parsed.meta?.arg?.endpointName;
|
||||
if (endpointName === 'getImageDTO') {
|
||||
// do not show toast if problem is image access
|
||||
return;
|
||||
}
|
||||
@ -39,6 +40,7 @@ export const authToastMiddleware: Middleware =
|
||||
: undefined;
|
||||
dispatch(
|
||||
addToast({
|
||||
id: `auth-error-toast-${endpointName}`,
|
||||
title: t('common.somethingWentWrong'),
|
||||
status: 'error',
|
||||
description: customMessage,
|
||||
|
Loading…
Reference in New Issue
Block a user