mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
refactor workflow thumbnails to be separate flow/endpoints
This commit is contained in:
committed by
psychedelicious
parent
d4423aa16f
commit
ab4433da2f
@@ -1,5 +1,6 @@
|
||||
import type { FormControlProps } from '@invoke-ai/ui-library';
|
||||
import { Flex, FormControl, FormControlGroup, FormLabel, Input, Textarea } from '@invoke-ai/ui-library';
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||
@@ -11,19 +12,20 @@ import {
|
||||
workflowNameChanged,
|
||||
workflowNotesChanged,
|
||||
workflowTagsChanged,
|
||||
workflowThumbnailChanged,
|
||||
workflowVersionChanged,
|
||||
} from 'features/nodes/store/workflowSlice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetWorkflowQuery } from 'services/api/endpoints/workflows';
|
||||
|
||||
import { WorkflowThumbnailField } from './WorkflowThumbnailField';
|
||||
import { WorkflowThumbnailEditor } from './WorkflowThumbnail/WorkflowThumbnailEditor';
|
||||
|
||||
const selector = createMemoizedSelector(selectWorkflowSlice, (workflow) => {
|
||||
const { author, name, description, tags, version, contact, notes, thumbnail } = workflow;
|
||||
const { id, author, name, description, tags, version, contact, notes } = workflow;
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
author,
|
||||
description,
|
||||
@@ -31,14 +33,15 @@ const selector = createMemoizedSelector(selectWorkflowSlice, (workflow) => {
|
||||
version,
|
||||
contact,
|
||||
notes,
|
||||
thumbnail,
|
||||
};
|
||||
});
|
||||
|
||||
const WorkflowGeneralTab = () => {
|
||||
const { author, name, description, tags, version, contact, notes, thumbnail } = useAppSelector(selector);
|
||||
const { id, author, name, description, tags, version, contact, notes } = useAppSelector(selector);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { data } = useGetWorkflowQuery(id ?? skipToken);
|
||||
|
||||
const handleChangeName = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => {
|
||||
dispatch(workflowNameChanged(e.target.value));
|
||||
@@ -83,13 +86,6 @@ const WorkflowGeneralTab = () => {
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const handleChangeThumbnail = useCallback(
|
||||
(localImageUrl: string | null) => {
|
||||
dispatch(workflowThumbnailChanged(localImageUrl));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@@ -100,15 +96,14 @@ const WorkflowGeneralTab = () => {
|
||||
<FormLabel>{t('nodes.workflowName')}</FormLabel>
|
||||
<Input variant="darkFilled" value={name} onChange={handleChangeName} />
|
||||
</FormControl>
|
||||
|
||||
<FormControl>
|
||||
<FormLabel>{t('workflows.workflowThumbnail')}</FormLabel>
|
||||
<WorkflowThumbnailEditor thumbnailUrl={data?.thumbnail_url || null} workflowId={id} />
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('nodes.workflowVersion')}</FormLabel>
|
||||
<Input variant="darkFilled" value={version} onChange={handleChangeVersion} />
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>Thumbnail</FormLabel>
|
||||
<WorkflowThumbnailField imageUrl={thumbnail} onChange={handleChangeThumbnail} />
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('nodes.workflowAuthor')}</FormLabel>
|
||||
<Input variant="darkFilled" value={author} onChange={handleChangeAuthor} />
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Button, Flex } from '@invoke-ai/ui-library';
|
||||
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDeleteWorkflowThumbnailMutation, useSetWorkflowThumbnailMutation } from 'services/api/endpoints/workflows';
|
||||
|
||||
import { WorkflowThumbnailField } from './WorkflowThumbnailField';
|
||||
|
||||
export const WorkflowThumbnailEditor = ({
|
||||
workflowId,
|
||||
thumbnailUrl,
|
||||
}: {
|
||||
workflowId?: string;
|
||||
thumbnailUrl: string | null;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [localThumbnailUrl, setLocalThumbnailUrl] = useState<string | null>(null);
|
||||
const [canSaveChanges, setCanSaveChanges] = useState(false);
|
||||
|
||||
const [setThumbnail, { isLoading }] = useSetWorkflowThumbnailMutation();
|
||||
const [deleteThumbnail, { isLoading: isDeleting }] = useDeleteWorkflowThumbnailMutation();
|
||||
|
||||
const handleLocalThumbnailUrlChange = useCallback((url: string | null) => {
|
||||
setLocalThumbnailUrl(url);
|
||||
setCanSaveChanges(true);
|
||||
}, []);
|
||||
|
||||
const handleSaveChanges = useCallback(async () => {
|
||||
if (!workflowId) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (localThumbnailUrl) {
|
||||
const blob = await convertImageUrlToBlob(localThumbnailUrl);
|
||||
if (!blob) {
|
||||
return;
|
||||
}
|
||||
const file = new File([blob], 'workflow_thumbnail.png', { type: 'image/png' });
|
||||
await setThumbnail({ workflow_id: workflowId, image: file }).unwrap();
|
||||
} else {
|
||||
await deleteThumbnail(workflowId).unwrap();
|
||||
}
|
||||
|
||||
setCanSaveChanges(false);
|
||||
toast({ status: 'success', title: 'Workflow thumbnail updated' });
|
||||
} catch (error) {
|
||||
toast({ status: 'error', title: 'Failed to update thumbnail' });
|
||||
}
|
||||
}, [deleteThumbnail, setThumbnail, workflowId, localThumbnailUrl]);
|
||||
|
||||
return (
|
||||
<Flex alignItems="center" gap={4}>
|
||||
<WorkflowThumbnailField imageUrl={thumbnailUrl} onChange={handleLocalThumbnailUrlChange} />
|
||||
|
||||
<Button size="sm" isLoading={isLoading || isDeleting} onClick={handleSaveChanges} isDisabled={!canSaveChanges}>
|
||||
{t('common.saveChanges')}
|
||||
</Button>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -10,7 +10,7 @@ export const WorkflowThumbnailField = ({
|
||||
onChange,
|
||||
}: {
|
||||
imageUrl: string | null;
|
||||
onChange: (localImageUrl: string | null) => void;
|
||||
onChange: (localThumbnailUrl: string | null) => void;
|
||||
}) => {
|
||||
const [thumbnail, setThumbnail] = useState<File | null>(null);
|
||||
|
||||
@@ -48,7 +48,8 @@ export const WorkflowThumbnailField = ({
|
||||
|
||||
const handleResetImage = useCallback(() => {
|
||||
setThumbnail(null);
|
||||
}, []);
|
||||
onChange(null);
|
||||
}, [onChange]);
|
||||
|
||||
const { getInputProps, getRootProps } = useDropzone({
|
||||
accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg', '.png'] },
|
||||
@@ -64,9 +65,8 @@ export const WorkflowThumbnailField = ({
|
||||
src={URL.createObjectURL(thumbnail)}
|
||||
objectFit="cover"
|
||||
objectPosition="50% 50%"
|
||||
w={65}
|
||||
h={65}
|
||||
minWidth={65}
|
||||
w={100}
|
||||
h={100}
|
||||
borderRadius="base"
|
||||
/>
|
||||
<IconButton
|
||||
@@ -89,8 +89,8 @@ export const WorkflowThumbnailField = ({
|
||||
<Tooltip label={t('stylePresets.uploadImage')}>
|
||||
<Flex
|
||||
as={Button}
|
||||
w={65}
|
||||
h={65}
|
||||
w={100}
|
||||
h={100}
|
||||
opacity={0.3}
|
||||
borderRadius="base"
|
||||
alignItems="center"
|
||||
@@ -109,10 +109,6 @@ export const workflowSlice = createSlice({
|
||||
state.name = action.payload;
|
||||
state.isTouched = true;
|
||||
},
|
||||
workflowThumbnailChanged: (state, action: PayloadAction<string | null>) => {
|
||||
state.thumbnail = action.payload;
|
||||
state.isTouched = true;
|
||||
},
|
||||
workflowCategoryChanged: (state, action: PayloadAction<WorkflowCategory | undefined>) => {
|
||||
if (action.payload) {
|
||||
state.meta.category = action.payload;
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import type { ToastId } from '@invoke-ai/ui-library';
|
||||
import { useToast } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
|
||||
import { $builtWorkflow } from 'features/nodes/hooks/useWorkflowWatcher';
|
||||
import {
|
||||
formFieldInitialValuesChanged,
|
||||
selectWorkflowThumbnail,
|
||||
workflowIDChanged,
|
||||
workflowSaved,
|
||||
} from 'features/nodes/store/workflowSlice';
|
||||
import { formFieldInitialValuesChanged, workflowIDChanged, workflowSaved } from 'features/nodes/store/workflowSlice';
|
||||
import type { WorkflowV3 } from 'features/nodes/types/workflow';
|
||||
import { useGetFormFieldInitialValues } from 'features/workflowLibrary/hooks/useGetFormInitialValues';
|
||||
import { workflowUpdated } from 'features/workflowLibrary/store/actions';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useCreateWorkflowMutation, useUpdateWorkflowMutation, workflowsApi } from 'services/api/endpoints/workflows';
|
||||
import type { SetRequired } from 'type-fest';
|
||||
|
||||
@@ -33,7 +26,6 @@ export const useSaveLibraryWorkflow: UseSaveLibraryWorkflow = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const getFormFieldInitialValues = useGetFormFieldInitialValues();
|
||||
const thumbnail = useSelector(selectWorkflowThumbnail);
|
||||
const [updateWorkflow, updateWorkflowResult] = useUpdateWorkflowMutation();
|
||||
const [createWorkflow, createWorkflowResult] = useCreateWorkflowMutation();
|
||||
const toast = useToast();
|
||||
@@ -50,13 +42,11 @@ export const useSaveLibraryWorkflow: UseSaveLibraryWorkflow = () => {
|
||||
isClosable: false,
|
||||
});
|
||||
try {
|
||||
const blob = thumbnail ? await convertImageUrlToBlob(thumbnail) : null;
|
||||
const image = blob ? new File([blob], 'thumbnail.png', { type: 'image/png' }) : null;
|
||||
if (isWorkflowWithID(workflow)) {
|
||||
await updateWorkflow({ workflow, image }).unwrap();
|
||||
await updateWorkflow(workflow).unwrap();
|
||||
dispatch(workflowUpdated());
|
||||
} else {
|
||||
const data = await createWorkflow({ workflow, image }).unwrap();
|
||||
const data = await createWorkflow(workflow).unwrap();
|
||||
dispatch(workflowIDChanged(data.workflow.id));
|
||||
}
|
||||
dispatch(workflowSaved());
|
||||
@@ -83,7 +73,7 @@ export const useSaveLibraryWorkflow: UseSaveLibraryWorkflow = () => {
|
||||
toast.close(toastRef.current);
|
||||
}
|
||||
}
|
||||
}, [toast, t, dispatch, getFormFieldInitialValues, updateWorkflow, createWorkflow, thumbnail]);
|
||||
}, [toast, t, dispatch, getFormFieldInitialValues, updateWorkflow, createWorkflow]);
|
||||
return {
|
||||
saveWorkflow,
|
||||
isLoading: updateWorkflowResult.isLoading || createWorkflowResult.isLoading,
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import type { ToastId } from '@invoke-ai/ui-library';
|
||||
import { useToast } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
|
||||
import { $builtWorkflow } from 'features/nodes/hooks/useWorkflowWatcher';
|
||||
import {
|
||||
formFieldInitialValuesChanged,
|
||||
selectWorkflowThumbnail,
|
||||
workflowCategoryChanged,
|
||||
workflowIDChanged,
|
||||
workflowNameChanged,
|
||||
@@ -16,7 +14,6 @@ import { useGetFormFieldInitialValues } from 'features/workflowLibrary/hooks/use
|
||||
import { newWorkflowSaved } from 'features/workflowLibrary/store/actions';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useCreateWorkflowMutation, workflowsApi } from 'services/api/endpoints/workflows';
|
||||
|
||||
type SaveWorkflowAsArg = {
|
||||
@@ -40,7 +37,6 @@ export const useSaveWorkflowAs: UseSaveWorkflowAs = () => {
|
||||
const [createWorkflow, createWorkflowResult] = useCreateWorkflowMutation();
|
||||
const getFormFieldInitialValues = useGetFormFieldInitialValues();
|
||||
|
||||
const thumbnail = useSelector(selectWorkflowThumbnail);
|
||||
const toast = useToast();
|
||||
const toastRef = useRef<ToastId | undefined>();
|
||||
const saveWorkflowAs = useCallback(
|
||||
@@ -59,10 +55,8 @@ export const useSaveWorkflowAs: UseSaveWorkflowAs = () => {
|
||||
workflow.id = undefined;
|
||||
workflow.name = newName;
|
||||
workflow.meta.category = category;
|
||||
const blob = thumbnail ? await convertImageUrlToBlob(thumbnail) : null;
|
||||
const image = blob ? new File([blob], 'thumbnail.png', { type: 'image/png' }) : null;
|
||||
|
||||
const data = await createWorkflow({ workflow, image }).unwrap();
|
||||
const data = await createWorkflow(workflow).unwrap();
|
||||
dispatch(workflowIDChanged(data.workflow.id));
|
||||
dispatch(workflowNameChanged(data.workflow.name));
|
||||
dispatch(workflowCategoryChanged(data.workflow.meta.category));
|
||||
@@ -92,7 +86,7 @@ export const useSaveWorkflowAs: UseSaveWorkflowAs = () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
[toast, t, createWorkflow, dispatch, getFormFieldInitialValues, thumbnail]
|
||||
[toast, t, createWorkflow, dispatch, getFormFieldInitialValues]
|
||||
);
|
||||
return {
|
||||
saveWorkflowAs,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { paths } from 'services/api/schema';
|
||||
|
||||
import { api, buildV1Url, LIST_TAG } from '..';
|
||||
import { Workflow, WorkflowWithoutID } from '../types';
|
||||
|
||||
/**
|
||||
* Builds an endpoint URL for the workflows router
|
||||
@@ -42,22 +41,13 @@ export const workflowsApi = api.injectEndpoints({
|
||||
}),
|
||||
createWorkflow: build.mutation<
|
||||
paths['/api/v1/workflows/']['post']['responses']['200']['content']['application/json'],
|
||||
{ workflow: WorkflowWithoutID; image: File | null }
|
||||
paths['/api/v1/workflows/']['post']['requestBody']['content']['application/json']['workflow']
|
||||
>({
|
||||
query: ({ workflow, image }) => {
|
||||
const formData = new FormData();
|
||||
if (image) {
|
||||
formData.append('image', image);
|
||||
}
|
||||
|
||||
formData.append('workflow', JSON.stringify(workflow));
|
||||
|
||||
return {
|
||||
url: buildWorkflowsUrl(),
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
};
|
||||
},
|
||||
query: (workflow) => ({
|
||||
url: buildWorkflowsUrl(),
|
||||
method: 'POST',
|
||||
body: { workflow },
|
||||
}),
|
||||
invalidatesTags: [
|
||||
{ type: 'Workflow', id: LIST_TAG },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
@@ -65,22 +55,14 @@ export const workflowsApi = api.injectEndpoints({
|
||||
}),
|
||||
updateWorkflow: build.mutation<
|
||||
paths['/api/v1/workflows/i/{workflow_id}']['patch']['responses']['200']['content']['application/json'],
|
||||
{ workflow: Workflow; image: File | null }
|
||||
paths['/api/v1/workflows/i/{workflow_id}']['patch']['requestBody']['content']['application/json']['workflow']
|
||||
>({
|
||||
query: ({ workflow, image }) => {
|
||||
const formData = new FormData();
|
||||
if (image) {
|
||||
formData.append('image', image);
|
||||
}
|
||||
formData.append('workflow', JSON.stringify(workflow));
|
||||
|
||||
return {
|
||||
url: buildWorkflowsUrl(`i/${workflow.id}`),
|
||||
method: 'PATCH',
|
||||
body: formData,
|
||||
};
|
||||
},
|
||||
invalidatesTags: (response, error, { workflow }) => [
|
||||
query: (workflow) => ({
|
||||
url: buildWorkflowsUrl(`i/${workflow.id}`),
|
||||
method: 'PATCH',
|
||||
body: { workflow },
|
||||
}),
|
||||
invalidatesTags: (response, error, workflow) => [
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
{ type: 'Workflow', id: LIST_TAG },
|
||||
{ type: 'Workflow', id: workflow.id },
|
||||
@@ -96,13 +78,41 @@ export const workflowsApi = api.injectEndpoints({
|
||||
}),
|
||||
providesTags: ['FetchOnReconnect', { type: 'Workflow', id: LIST_TAG }],
|
||||
}),
|
||||
setWorkflowThumbnail: build.mutation<void, { workflow_id: string; image: File }>({
|
||||
query: ({ workflow_id, image }) => {
|
||||
const formData = new FormData();
|
||||
formData.append('image', image);
|
||||
return {
|
||||
url: buildWorkflowsUrl(`i/${workflow_id}/thumbnail`),
|
||||
method: 'PUT',
|
||||
body: formData,
|
||||
};
|
||||
},
|
||||
invalidatesTags: (result, error, { workflow_id }) => [
|
||||
{ type: 'Workflow', id: workflow_id },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
deleteWorkflowThumbnail: build.mutation<void, string>({
|
||||
query: (workflow_id) => ({
|
||||
url: buildWorkflowsUrl(`i/${workflow_id}/thumbnail`),
|
||||
method: 'DELETE',
|
||||
}),
|
||||
invalidatesTags: (result, error, workflow_id) => [
|
||||
{ type: 'Workflow', id: workflow_id },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useLazyGetWorkflowQuery,
|
||||
useGetWorkflowQuery,
|
||||
useCreateWorkflowMutation,
|
||||
useDeleteWorkflowMutation,
|
||||
useUpdateWorkflowMutation,
|
||||
useListWorkflowsQuery,
|
||||
useSetWorkflowThumbnailMutation,
|
||||
useDeleteWorkflowThumbnailMutation,
|
||||
} = workflowsApi;
|
||||
|
||||
@@ -1410,7 +1410,7 @@ export type paths = {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/workflows/{workflow_id}/thumbnail": {
|
||||
"/api/v1/workflows/i/{workflow_id}/thumbnail": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
@@ -1418,33 +1418,17 @@ export type paths = {
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Upload Workflow Thumbnail
|
||||
* @description Uploads a thumbnail for a workflow
|
||||
* Set Workflow Thumbnail
|
||||
* @description Sets a workflow's thumbnail image
|
||||
*/
|
||||
post: operations["upload_workflow_thumbnail"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/workflowsi/{workflow_id}/thumbnail": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Get Workflow Thumbnail
|
||||
* @description Gets the thumbnail for a workflow
|
||||
*/
|
||||
get: operations["get_workflow_thumbnail"];
|
||||
put?: never;
|
||||
put: operations["set_workflow_thumbnail"];
|
||||
post?: never;
|
||||
delete?: never;
|
||||
/**
|
||||
* Delete Workflow Thumbnail
|
||||
* @description Removes a workflow's thumbnail image
|
||||
*/
|
||||
delete: operations["delete_workflow_thumbnail"];
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
@@ -2251,16 +2235,8 @@ export type components = {
|
||||
};
|
||||
/** Body_create_workflow */
|
||||
Body_create_workflow: {
|
||||
/**
|
||||
* Workflow
|
||||
* @description The workflow to create
|
||||
*/
|
||||
workflow: string;
|
||||
/**
|
||||
* Image
|
||||
* @description The image file to upload
|
||||
*/
|
||||
image?: Blob | null;
|
||||
/** @description The workflow to create */
|
||||
workflow: components["schemas"]["WorkflowWithoutID"];
|
||||
};
|
||||
/** Body_delete_images_from_list */
|
||||
Body_delete_images_from_list: {
|
||||
@@ -2377,6 +2353,15 @@ export type components = {
|
||||
*/
|
||||
image_names: string[];
|
||||
};
|
||||
/** Body_set_workflow_thumbnail */
|
||||
Body_set_workflow_thumbnail: {
|
||||
/**
|
||||
* Image
|
||||
* Format: binary
|
||||
* @description The image file to upload
|
||||
*/
|
||||
image: Blob;
|
||||
};
|
||||
/** Body_star_images_in_list */
|
||||
Body_star_images_in_list: {
|
||||
/**
|
||||
@@ -2416,16 +2401,8 @@ export type components = {
|
||||
};
|
||||
/** Body_update_workflow */
|
||||
Body_update_workflow: {
|
||||
/**
|
||||
* Workflow
|
||||
* @description The updated workflow
|
||||
*/
|
||||
workflow: string;
|
||||
/**
|
||||
* Image
|
||||
* @description The image file to upload
|
||||
*/
|
||||
image?: Blob | null;
|
||||
/** @description The updated workflow */
|
||||
workflow: components["schemas"]["Workflow"];
|
||||
};
|
||||
/** Body_upload_image */
|
||||
Body_upload_image: {
|
||||
@@ -2437,15 +2414,6 @@ export type components = {
|
||||
/** @description The metadata to associate with the image */
|
||||
metadata?: components["schemas"]["JsonValue"] | null;
|
||||
};
|
||||
/** Body_upload_workflow_thumbnail */
|
||||
Body_upload_workflow_thumbnail: {
|
||||
/**
|
||||
* File
|
||||
* Format: binary
|
||||
* @description The image file to upload
|
||||
*/
|
||||
file: Blob;
|
||||
};
|
||||
/**
|
||||
* Boolean Collection Primitive
|
||||
* @description A collection of boolean primitive values
|
||||
@@ -16367,8 +16335,8 @@ export type components = {
|
||||
/** Ui Order */
|
||||
ui_order: number | null;
|
||||
};
|
||||
/** PaginatedResults[WorkflowRecordListItemDTO] */
|
||||
PaginatedResults_WorkflowRecordListItemDTO_: {
|
||||
/** PaginatedResults[WorkflowRecordListItemWithThumbnailDTO] */
|
||||
PaginatedResults_WorkflowRecordListItemWithThumbnailDTO_: {
|
||||
/**
|
||||
* Page
|
||||
* @description Current Page
|
||||
@@ -16393,7 +16361,7 @@ export type components = {
|
||||
* Items
|
||||
* @description Items
|
||||
*/
|
||||
items: components["schemas"]["WorkflowRecordListItemDTO"][];
|
||||
items: components["schemas"]["WorkflowRecordListItemWithThumbnailDTO"][];
|
||||
};
|
||||
/**
|
||||
* Pair Tile with Image
|
||||
@@ -21152,16 +21120,11 @@ export type components = {
|
||||
* @description The opened timestamp of the workflow.
|
||||
*/
|
||||
opened_at: string;
|
||||
/**
|
||||
* Thumbnail Url
|
||||
* @description The URL of the workflow thumbnail.
|
||||
*/
|
||||
thumbnail_url?: string | null;
|
||||
/** @description The workflow. */
|
||||
workflow: components["schemas"]["Workflow"];
|
||||
};
|
||||
/** WorkflowRecordListItemDTO */
|
||||
WorkflowRecordListItemDTO: {
|
||||
/** WorkflowRecordListItemWithThumbnailDTO */
|
||||
WorkflowRecordListItemWithThumbnailDTO: {
|
||||
/**
|
||||
* Workflow Id
|
||||
* @description The id of the workflow.
|
||||
@@ -21187,11 +21150,6 @@ export type components = {
|
||||
* @description The opened timestamp of the workflow.
|
||||
*/
|
||||
opened_at: string;
|
||||
/**
|
||||
* Thumbnail Url
|
||||
* @description The URL of the workflow thumbnail.
|
||||
*/
|
||||
thumbnail_url?: string | null;
|
||||
/**
|
||||
* Description
|
||||
* @description The description of the workflow.
|
||||
@@ -21199,6 +21157,11 @@ export type components = {
|
||||
description: string;
|
||||
/** @description The description of the workflow. */
|
||||
category: components["schemas"]["WorkflowCategory"];
|
||||
/**
|
||||
* Thumbnail Url
|
||||
* @description The URL of the workflow thumbnail.
|
||||
*/
|
||||
thumbnail_url?: string | null;
|
||||
};
|
||||
/**
|
||||
* WorkflowRecordOrderBy
|
||||
@@ -21206,6 +21169,41 @@ export type components = {
|
||||
* @enum {string}
|
||||
*/
|
||||
WorkflowRecordOrderBy: "created_at" | "updated_at" | "opened_at" | "name";
|
||||
/** WorkflowRecordWithThumbnailDTO */
|
||||
WorkflowRecordWithThumbnailDTO: {
|
||||
/**
|
||||
* Workflow Id
|
||||
* @description The id of the workflow.
|
||||
*/
|
||||
workflow_id: string;
|
||||
/**
|
||||
* Name
|
||||
* @description The name of the workflow.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Created At
|
||||
* @description The created timestamp of the workflow.
|
||||
*/
|
||||
created_at: string;
|
||||
/**
|
||||
* Updated At
|
||||
* @description The updated timestamp of the workflow.
|
||||
*/
|
||||
updated_at: string;
|
||||
/**
|
||||
* Opened At
|
||||
* @description The opened timestamp of the workflow.
|
||||
*/
|
||||
opened_at: string;
|
||||
/** @description The workflow. */
|
||||
workflow: components["schemas"]["Workflow"];
|
||||
/**
|
||||
* Thumbnail Url
|
||||
* @description The URL of the workflow thumbnail.
|
||||
*/
|
||||
thumbnail_url?: string | null;
|
||||
};
|
||||
/** WorkflowWithoutID */
|
||||
WorkflowWithoutID: {
|
||||
/**
|
||||
@@ -24163,7 +24161,7 @@ export interface operations {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["WorkflowRecordDTO"];
|
||||
"application/json": components["schemas"]["WorkflowRecordWithThumbnailDTO"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
@@ -24218,7 +24216,7 @@ export interface operations {
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"multipart/form-data": components["schemas"]["Body_update_workflow"];
|
||||
"application/json": components["schemas"]["Body_update_workflow"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
@@ -24270,7 +24268,7 @@ export interface operations {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["PaginatedResults_WorkflowRecordListItemDTO_"];
|
||||
"application/json": components["schemas"]["PaginatedResults_WorkflowRecordListItemWithThumbnailDTO_"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
@@ -24293,7 +24291,7 @@ export interface operations {
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"multipart/form-data": components["schemas"]["Body_create_workflow"];
|
||||
"application/json": components["schemas"]["Body_create_workflow"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
@@ -24317,37 +24315,31 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
upload_workflow_thumbnail: {
|
||||
set_workflow_thumbnail: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
/** @description The workflow to update */
|
||||
workflow_id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"multipart/form-data": components["schemas"]["Body_upload_workflow_thumbnail"];
|
||||
"multipart/form-data": components["schemas"]["Body_set_workflow_thumbnail"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Thumbnail uploaded successfully */
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
"application/json": components["schemas"]["WorkflowRecordDTO"];
|
||||
};
|
||||
};
|
||||
/** @description Invalid image format */
|
||||
415: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
@@ -24359,33 +24351,27 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
get_workflow_thumbnail: {
|
||||
delete_workflow_thumbnail: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
/** @description The workflow to update */
|
||||
workflow_id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Thumbnail retrieved successfully */
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
"application/json": components["schemas"]["WorkflowRecordDTO"];
|
||||
};
|
||||
};
|
||||
/** @description Thumbnail not found */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
|
||||
@@ -20,9 +20,6 @@ export type UpdateBoardArg = paths['/api/v1/boards/{board_id}']['patch']['parame
|
||||
export type GraphAndWorkflowResponse =
|
||||
paths['/api/v1/images/i/{image_name}/workflow']['get']['responses']['200']['content']['application/json'];
|
||||
|
||||
export type WorkflowWithoutID = S['WorkflowWithoutID'];
|
||||
export type Workflow = S['Workflow'];
|
||||
|
||||
export type BatchConfig =
|
||||
paths['/api/v1/queue/{queue_id}/enqueue_batch']['post']['requestBody']['content']['application/json'];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user