From 800c481515ec2df950a5cbcd85ee789d80a915f2 Mon Sep 17 00:00:00 2001 From: Mary Hipp Rogers Date: Wed, 7 Feb 2024 09:14:54 -0500 Subject: [PATCH] add actions for workflow library (#5669) Co-authored-by: Mary Hipp --- .../web/src/common/hooks/useDownloadImage.ts | 6 +++- .../web/src/features/gallery/store/actions.ts | 2 ++ .../hooks/useDownloadWorkflow.ts | 34 +++++++++++-------- .../hooks/useLoadWorkflowFromFile.tsx | 2 ++ .../workflowLibrary/hooks/useSaveWorkflow.ts | 2 ++ .../hooks/useSaveWorkflowAs.ts | 2 ++ .../features/workflowLibrary/store/actions.ts | 10 ++++++ 7 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 invokeai/frontend/web/src/features/workflowLibrary/store/actions.ts diff --git a/invokeai/frontend/web/src/common/hooks/useDownloadImage.ts b/invokeai/frontend/web/src/common/hooks/useDownloadImage.ts index 5c75549eac..3195426da3 100644 --- a/invokeai/frontend/web/src/common/hooks/useDownloadImage.ts +++ b/invokeai/frontend/web/src/common/hooks/useDownloadImage.ts @@ -1,4 +1,6 @@ import { useAppToaster } from 'app/components/Toaster'; +import { useAppDispatch } from 'app/store/storeHooks'; +import { imageDownloaded } from 'features/gallery/store/actions'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -8,6 +10,7 @@ export const useDownloadImage = () => { const toaster = useAppToaster(); const { t } = useTranslation(); const imageUrlToBlob = useImageUrlToBlob(); + const dispatch = useAppDispatch(); const downloadImage = useCallback( async (image_url: string, image_name: string) => { @@ -26,6 +29,7 @@ export const useDownloadImage = () => { document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); + dispatch(imageDownloaded()); } catch (err) { toaster({ title: t('toast.problemDownloadingImage'), @@ -36,7 +40,7 @@ export const useDownloadImage = () => { }); } }, - [t, toaster, imageUrlToBlob] + [t, toaster, imageUrlToBlob, dispatch] ); return { downloadImage }; diff --git a/invokeai/frontend/web/src/features/gallery/store/actions.ts b/invokeai/frontend/web/src/features/gallery/store/actions.ts index 4ebf4e021d..e62a350756 100644 --- a/invokeai/frontend/web/src/features/gallery/store/actions.ts +++ b/invokeai/frontend/web/src/features/gallery/store/actions.ts @@ -14,3 +14,5 @@ export const requestedBoardImagesDeletion = createAction { - const workflow = $builtWorkflow.get(); - if (!workflow) { - return; - } - const blob = new Blob([JSON.stringify(workflow, null, 2)]); - const a = document.createElement('a'); - a.href = URL.createObjectURL(blob); - a.download = `${workflow.name || 'My Workflow'}.json`; - document.body.appendChild(a); - a.click(); - a.remove(); -}; +import { workflowDownloaded } from 'features/workflowLibrary/store/actions'; +import { useCallback } from 'react'; export const useDownloadWorkflow = () => { + const dispatch = useAppDispatch(); + + const downloadWorkflow = useCallback(() => { + const workflow = $builtWorkflow.get(); + if (!workflow) { + return; + } + const blob = new Blob([JSON.stringify(workflow, null, 2)]); + const a = document.createElement('a'); + a.href = URL.createObjectURL(blob); + a.download = `${workflow.name || 'My Workflow'}.json`; + document.body.appendChild(a); + a.click(); + a.remove(); + dispatch(workflowDownloaded()); + }, [dispatch]); + return downloadWorkflow; }; diff --git a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useLoadWorkflowFromFile.tsx b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useLoadWorkflowFromFile.tsx index a6f5f16497..0b284ee7db 100644 --- a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useLoadWorkflowFromFile.tsx +++ b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useLoadWorkflowFromFile.tsx @@ -3,6 +3,7 @@ import { useAppDispatch } from 'app/store/storeHooks'; import { workflowLoadRequested } from 'features/nodes/store/actions'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; +import { workflowLoadedFromFile } from 'features/workflowLibrary/store/actions'; import type { RefObject } from 'react'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -29,6 +30,7 @@ export const useLoadWorkflowFromFile: UseLoadWorkflowFromFile = ({ resetRef }) = try { const parsedJSON = JSON.parse(String(rawJSON)); dispatch(workflowLoadRequested({ workflow: parsedJSON, asCopy: true })); + dispatch(workflowLoadedFromFile()); } catch (e) { // There was a problem reading the file logger.error(t('nodes.unableToLoadWorkflow')); diff --git a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflow.ts b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflow.ts index 78d7071c20..5d484b6897 100644 --- a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflow.ts +++ b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflow.ts @@ -4,6 +4,7 @@ import { useAppDispatch } from 'app/store/storeHooks'; import { $builtWorkflow } from 'features/nodes/hooks/useWorkflowWatcher'; import { workflowIDChanged, workflowSaved } from 'features/nodes/store/workflowSlice'; import type { WorkflowV2 } from 'features/nodes/types/workflow'; +import { workflowUpdated } from 'features/workflowLibrary/store/actions'; import { useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { useCreateWorkflowMutation, useUpdateWorkflowMutation, workflowsApi } from 'services/api/endpoints/workflows'; @@ -41,6 +42,7 @@ export const useSaveLibraryWorkflow: UseSaveLibraryWorkflow = () => { try { if (isWorkflowWithID(workflow)) { await updateWorkflow(workflow).unwrap(); + dispatch(workflowUpdated()); } else { const data = await createWorkflow(workflow).unwrap(); dispatch(workflowIDChanged(data.workflow.id)); diff --git a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflowAs.ts b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflowAs.ts index edf87e81ab..33fd5545e6 100644 --- a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflowAs.ts +++ b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useSaveWorkflowAs.ts @@ -9,6 +9,7 @@ import { workflowSaved, } from 'features/nodes/store/workflowSlice'; import type { WorkflowCategory } from 'features/nodes/types/workflow'; +import { newWorkflowSaved } from 'features/workflowLibrary/store/actions'; import { useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { useCreateWorkflowMutation, workflowsApi } from 'services/api/endpoints/workflows'; @@ -56,6 +57,7 @@ export const useSaveWorkflowAs: UseSaveWorkflowAs = () => { dispatch(workflowNameChanged(data.workflow.name)); dispatch(workflowCategoryChanged(data.workflow.meta.category)); dispatch(workflowSaved()); + dispatch(newWorkflowSaved({ category })); onSuccess && onSuccess(); toast.update(toastRef.current, { diff --git a/invokeai/frontend/web/src/features/workflowLibrary/store/actions.ts b/invokeai/frontend/web/src/features/workflowLibrary/store/actions.ts new file mode 100644 index 0000000000..33100a9c9d --- /dev/null +++ b/invokeai/frontend/web/src/features/workflowLibrary/store/actions.ts @@ -0,0 +1,10 @@ +import { createAction } from '@reduxjs/toolkit'; +import type { WorkflowCategory } from 'features/nodes/types/workflow'; + +export const workflowDownloaded = createAction('workflowLibrary/workflowDownloaded'); + +export const workflowLoadedFromFile = createAction('workflowLibrary/workflowLoadedFromFile'); + +export const newWorkflowSaved = createAction<{ category: WorkflowCategory }>('workflowLibrary/newWorkflowSaved'); + +export const workflowUpdated = createAction('workflowLibrary/workflowUpdated');