mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into pr-labeler
This commit is contained in:
commit
03ac93bfc7
@ -45,7 +45,7 @@ export const useSocketIO = () => {
|
|||||||
const socketOptions = useMemo(() => {
|
const socketOptions = useMemo(() => {
|
||||||
const options: Partial<ManagerOptions & SocketOptions> = {
|
const options: Partial<ManagerOptions & SocketOptions> = {
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
path: '/ws/socket.io',
|
path: `${window.location.pathname}ws/socket.io`,
|
||||||
autoConnect: false, // achtung! removing this breaks the dynamic middleware
|
autoConnect: false, // achtung! removing this breaks the dynamic middleware
|
||||||
forceNew: true,
|
forceNew: true,
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,7 @@ const workflowKeys = [
|
|||||||
'notes',
|
'notes',
|
||||||
'exposedFields',
|
'exposedFields',
|
||||||
'meta',
|
'meta',
|
||||||
|
'id',
|
||||||
] satisfies (keyof WorkflowV2)[];
|
] satisfies (keyof WorkflowV2)[];
|
||||||
|
|
||||||
export type BuildWorkflowFunction = (arg: BuildWorkflowArg) => WorkflowV2;
|
export type BuildWorkflowFunction = (arg: BuildWorkflowArg) => WorkflowV2;
|
||||||
|
@ -61,13 +61,21 @@ const WorkflowLibraryList = () => {
|
|||||||
const [category, setCategory] = useState<WorkflowCategory>('user');
|
const [category, setCategory] = useState<WorkflowCategory>('user');
|
||||||
const [page, setPage] = useState(0);
|
const [page, setPage] = useState(0);
|
||||||
const [query, setQuery] = useState('');
|
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 [direction, setDirection] = useState<SQLiteDirection>('ASC');
|
||||||
const [debouncedQuery] = useDebounce(query, 500);
|
const [debouncedQuery] = useDebounce(query, 500);
|
||||||
const projectId = useStore($projectId);
|
|
||||||
|
|
||||||
const queryArg = useMemo<Parameters<typeof useListWorkflowsQuery>[0]>(() => {
|
const queryArg = useMemo<Parameters<typeof useListWorkflowsQuery>[0]>(() => {
|
||||||
if (category === 'user') {
|
if (category !== 'default') {
|
||||||
return {
|
return {
|
||||||
page,
|
page,
|
||||||
per_page: PER_PAGE,
|
per_page: PER_PAGE,
|
||||||
@ -101,8 +109,8 @@ const WorkflowLibraryList = () => {
|
|||||||
[order_by]
|
[order_by]
|
||||||
);
|
);
|
||||||
const valueOrderBy = useMemo(
|
const valueOrderBy = useMemo(
|
||||||
() => ORDER_BY_OPTIONS.find((o) => o.value === order_by),
|
() => orderByOptions.find((o) => o.value === order_by),
|
||||||
[order_by]
|
[order_by, orderByOptions]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onChangeDirection = useCallback<ComboboxOnChange>(
|
const onChangeDirection = useCallback<ComboboxOnChange>(
|
||||||
@ -186,7 +194,7 @@ const WorkflowLibraryList = () => {
|
|||||||
<FormLabel>{t('common.orderBy')}</FormLabel>
|
<FormLabel>{t('common.orderBy')}</FormLabel>
|
||||||
<Combobox
|
<Combobox
|
||||||
value={valueOrderBy}
|
value={valueOrderBy}
|
||||||
options={ORDER_BY_OPTIONS}
|
options={orderByOptions}
|
||||||
onChange={onChangeOrderBy}
|
onChange={onChangeOrderBy}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
|
import { useToast } from '@invoke-ai/ui';
|
||||||
import { useAppToaster } from 'app/components/Toaster';
|
import { useAppToaster } from 'app/components/Toaster';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useDeleteWorkflowMutation } from 'services/api/endpoints/workflows';
|
import {
|
||||||
|
useDeleteWorkflowMutation,
|
||||||
|
workflowsApi,
|
||||||
|
} from 'services/api/endpoints/workflows';
|
||||||
|
|
||||||
type UseDeleteLibraryWorkflowOptions = {
|
type UseDeleteLibraryWorkflowOptions = {
|
||||||
onSuccess?: () => void;
|
onSuccess?: () => void;
|
||||||
@ -22,6 +26,7 @@ export const useDeleteLibraryWorkflow: UseDeleteLibraryWorkflow = ({
|
|||||||
onError,
|
onError,
|
||||||
}) => {
|
}) => {
|
||||||
const toaster = useAppToaster();
|
const toaster = useAppToaster();
|
||||||
|
const toast = useToast();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [_deleteWorkflow, deleteWorkflowResult] = useDeleteWorkflowMutation();
|
const [_deleteWorkflow, deleteWorkflowResult] = useDeleteWorkflowMutation();
|
||||||
|
|
||||||
@ -34,14 +39,20 @@ export const useDeleteLibraryWorkflow: UseDeleteLibraryWorkflow = ({
|
|||||||
});
|
});
|
||||||
onSuccess && onSuccess();
|
onSuccess && onSuccess();
|
||||||
} catch {
|
} catch {
|
||||||
|
if (
|
||||||
|
!toast.isActive(
|
||||||
|
`auth-error-toast-${workflowsApi.endpoints.deleteWorkflow.name}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
toaster({
|
toaster({
|
||||||
title: t('toast.problemDeletingWorkflow'),
|
title: t('toast.problemDeletingWorkflow'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
});
|
});
|
||||||
|
}
|
||||||
onError && onError();
|
onError && onError();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_deleteWorkflow, toaster, t, onSuccess, onError]
|
[_deleteWorkflow, toaster, t, onSuccess, onError, toast]
|
||||||
);
|
);
|
||||||
|
|
||||||
return { deleteWorkflow, deleteWorkflowResult };
|
return { deleteWorkflow, deleteWorkflowResult };
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
import { useToast } from '@invoke-ai/ui';
|
||||||
import { useAppToaster } from 'app/components/Toaster';
|
import { useAppToaster } from 'app/components/Toaster';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useLazyGetWorkflowQuery } from 'services/api/endpoints/workflows';
|
import {
|
||||||
|
useLazyGetWorkflowQuery,
|
||||||
|
workflowsApi,
|
||||||
|
} from 'services/api/endpoints/workflows';
|
||||||
|
|
||||||
type UseGetAndLoadLibraryWorkflowOptions = {
|
type UseGetAndLoadLibraryWorkflowOptions = {
|
||||||
onSuccess?: () => void;
|
onSuccess?: () => void;
|
||||||
@ -25,6 +29,7 @@ export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const toaster = useAppToaster();
|
const toaster = useAppToaster();
|
||||||
|
const toast = useToast();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [_getAndLoadWorkflow, getAndLoadWorkflowResult] =
|
const [_getAndLoadWorkflow, getAndLoadWorkflowResult] =
|
||||||
useLazyGetWorkflowQuery();
|
useLazyGetWorkflowQuery();
|
||||||
@ -38,14 +43,20 @@ export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({
|
|||||||
// No toast - the listener for this action does that after the workflow is loaded
|
// No toast - the listener for this action does that after the workflow is loaded
|
||||||
onSuccess && onSuccess();
|
onSuccess && onSuccess();
|
||||||
} catch {
|
} catch {
|
||||||
|
if (
|
||||||
|
!toast.isActive(
|
||||||
|
`auth-error-toast-${workflowsApi.endpoints.getWorkflow.name}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
toaster({
|
toaster({
|
||||||
title: t('toast.problemRetrievingWorkflow'),
|
title: t('toast.problemRetrievingWorkflow'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
});
|
});
|
||||||
|
}
|
||||||
onError && onError();
|
onError && onError();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_getAndLoadWorkflow, dispatch, onSuccess, toaster, t, onError]
|
[_getAndLoadWorkflow, dispatch, onSuccess, toaster, t, onError, toast]
|
||||||
);
|
);
|
||||||
|
|
||||||
return { getAndLoadWorkflow, getAndLoadWorkflowResult };
|
return { getAndLoadWorkflow, getAndLoadWorkflowResult };
|
||||||
|
@ -12,6 +12,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import {
|
import {
|
||||||
useCreateWorkflowMutation,
|
useCreateWorkflowMutation,
|
||||||
useUpdateWorkflowMutation,
|
useUpdateWorkflowMutation,
|
||||||
|
workflowsApi,
|
||||||
} from 'services/api/endpoints/workflows';
|
} from 'services/api/endpoints/workflows';
|
||||||
import type { O } from 'ts-toolbelt';
|
import type { O } from 'ts-toolbelt';
|
||||||
|
|
||||||
@ -60,12 +61,23 @@ export const useSaveLibraryWorkflow: UseSaveLibraryWorkflow = () => {
|
|||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (
|
||||||
|
!toast.isActive(
|
||||||
|
`auth-error-toast-${workflowsApi.endpoints.createWorkflow.name}`
|
||||||
|
) &&
|
||||||
|
!toast.isActive(
|
||||||
|
`auth-error-toast-${workflowsApi.endpoints.updateWorkflow.name}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
toast.update(toastRef.current, {
|
toast.update(toastRef.current, {
|
||||||
title: t('workflows.problemSavingWorkflow'),
|
title: t('workflows.problemSavingWorkflow'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
toast.close(toastRef.current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [updateWorkflow, dispatch, toast, t, createWorkflow]);
|
}, [updateWorkflow, dispatch, toast, t, createWorkflow]);
|
||||||
return {
|
return {
|
||||||
|
@ -9,7 +9,10 @@ import {
|
|||||||
} from 'features/nodes/store/workflowSlice';
|
} from 'features/nodes/store/workflowSlice';
|
||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useCreateWorkflowMutation } from 'services/api/endpoints/workflows';
|
import {
|
||||||
|
useCreateWorkflowMutation,
|
||||||
|
workflowsApi,
|
||||||
|
} from 'services/api/endpoints/workflows';
|
||||||
|
|
||||||
type SaveWorkflowAsArg = {
|
type SaveWorkflowAsArg = {
|
||||||
name: string;
|
name: string;
|
||||||
@ -59,12 +62,20 @@ export const useSaveWorkflowAs: UseSaveWorkflowAs = () => {
|
|||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
onError && onError();
|
onError && onError();
|
||||||
|
if (
|
||||||
|
!toast.isActive(
|
||||||
|
`auth-error-toast-${workflowsApi.endpoints.createWorkflow.name}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
toast.update(toastRef.current, {
|
toast.update(toastRef.current, {
|
||||||
title: t('workflows.problemSavingWorkflow'),
|
title: t('workflows.problemSavingWorkflow'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
toast.close(toastRef.current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[toast, createWorkflow, dispatch, t]
|
[toast, createWorkflow, dispatch, t]
|
||||||
|
@ -32,7 +32,7 @@ if (import.meta.env.MODE === 'package') {
|
|||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
debug: false,
|
debug: false,
|
||||||
backend: {
|
backend: {
|
||||||
loadPath: '/locales/{{lng}}.json',
|
loadPath: `${window.location.href.replace(/\/$/, '')}/locales/{{lng}}.json`,
|
||||||
},
|
},
|
||||||
interpolation: {
|
interpolation: {
|
||||||
escapeValue: false,
|
escapeValue: false,
|
||||||
|
@ -27,7 +27,8 @@ export const authToastMiddleware: Middleware =
|
|||||||
if (isRejectedWithValue(action)) {
|
if (isRejectedWithValue(action)) {
|
||||||
try {
|
try {
|
||||||
const parsed = zRejectedForbiddenAction.parse(action);
|
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
|
// do not show toast if problem is image access
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -39,6 +40,7 @@ export const authToastMiddleware: Middleware =
|
|||||||
: undefined;
|
: undefined;
|
||||||
dispatch(
|
dispatch(
|
||||||
addToast({
|
addToast({
|
||||||
|
id: `auth-error-toast-${endpointName}`,
|
||||||
title: t('common.somethingWentWrong'),
|
title: t('common.somethingWentWrong'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
description: customMessage,
|
description: customMessage,
|
||||||
|
@ -57,7 +57,9 @@ const dynamicBaseQuery: BaseQueryFn<
|
|||||||
const projectId = $projectId.get();
|
const projectId = $projectId.get();
|
||||||
|
|
||||||
const rawBaseQuery = fetchBaseQuery({
|
const rawBaseQuery = fetchBaseQuery({
|
||||||
baseUrl: `${baseUrl ?? ''}/api/v1`,
|
baseUrl: baseUrl
|
||||||
|
? `${baseUrl}/api/v1`
|
||||||
|
: `${window.location.href.replace(/\/$/, '')}/api/v1`,
|
||||||
prepareHeaders: (headers) => {
|
prepareHeaders: (headers) => {
|
||||||
if (authToken) {
|
if (authToken) {
|
||||||
headers.set('Authorization', `Bearer ${authToken}`);
|
headers.set('Authorization', `Bearer ${authToken}`);
|
||||||
|
@ -26,8 +26,9 @@ export const receivedOpenAPISchema = createAsyncThunk(
|
|||||||
'nodes/receivedOpenAPISchema',
|
'nodes/receivedOpenAPISchema',
|
||||||
async (_, { rejectWithValue }) => {
|
async (_, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const url = [window.location.origin, 'openapi.json'].join('/');
|
const response = await fetch(
|
||||||
const response = await fetch(url);
|
`${window.location.href.replace(/\/$/, '')}/openapi.json`
|
||||||
|
);
|
||||||
const openAPISchema = await response.json();
|
const openAPISchema = await response.json();
|
||||||
|
|
||||||
const schemaJSON = JSON.parse(
|
const schemaJSON = JSON.parse(
|
||||||
|
@ -1 +1 @@
|
|||||||
__version__ = "3.6.1"
|
__version__ = "3.6.2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user