diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/EditWorkflow.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/EditWorkflow.tsx index 05c8266dec..06d21921b2 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/EditWorkflow.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/EditWorkflow.tsx @@ -12,7 +12,7 @@ export const EditWorkflow = ({ workflowId }: { workflowId: string }) => { const handleClickEdit = useCallback( (e: MouseEvent) => { e.stopPropagation(); - loadWorkflow.loadWithDialog(workflowId, 'edit'); + loadWorkflow.loadWithDialog({ type: 'library', workflowId, mode: 'view' }); }, [loadWorkflow, workflowId] ); diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/ViewWorkflow.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/ViewWorkflow.tsx index 8453763551..3e062ae41e 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/ViewWorkflow.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibraryListItemActions/ViewWorkflow.tsx @@ -12,7 +12,7 @@ export const ViewWorkflow = ({ workflowId }: { workflowId: string }) => { const handleClickLoad = useCallback( (e: MouseEvent) => { e.stopPropagation(); - loadWorkflow.loadWithDialog(workflowId, 'view'); + loadWorkflow.loadWithDialog({ type: 'library', workflowId, mode: 'view' }); }, [loadWorkflow, workflowId] ); diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibrarySideNav.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibrarySideNav.tsx index af505a1872..deaa74e3b4 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibrarySideNav.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibrarySideNav.tsx @@ -157,7 +157,7 @@ const useCountForTagCategory = (tagCategory: WorkflowTagCategory) => { const RecentWorkflowButton = memo(({ workflow }: { workflow: S['WorkflowRecordListItemWithThumbnailDTO'] }) => { const loadWorkflow = useLoadWorkflow(); const load = useCallback(() => { - loadWorkflow.loadWithDialog(workflow.workflow_id, 'view'); + loadWorkflow.loadWithDialog({ type: 'library', workflowId: workflow.workflow_id, mode: 'view' }); }, [loadWorkflow, workflow.workflow_id]); return ( diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowListItem.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowListItem.tsx index 0f4f87ee69..979fb08700 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowListItem.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowListItem.tsx @@ -40,7 +40,7 @@ export const WorkflowListItem = memo(({ workflow }: { workflow: WorkflowRecordLi }, [workflowId, workflow.workflow_id]); const handleClickLoad = useCallback(() => { - loadWorkflow.loadWithDialog(workflow.workflow_id, 'view'); + loadWorkflow.loadWithDialog({ type: 'library', workflowId: workflow.workflow_id, mode: 'view' }); }, [loadWorkflow, workflow.workflow_id]); return ( diff --git a/invokeai/frontend/web/src/features/workflowLibrary/components/LoadWorkflowConfirmationAlertDialog.tsx b/invokeai/frontend/web/src/features/workflowLibrary/components/LoadWorkflowConfirmationAlertDialog.tsx index 7761adf767..16ba52111c 100644 --- a/invokeai/frontend/web/src/features/workflowLibrary/components/LoadWorkflowConfirmationAlertDialog.tsx +++ b/invokeai/frontend/web/src/features/workflowLibrary/components/LoadWorkflowConfirmationAlertDialog.tsx @@ -4,51 +4,66 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAssertSingleton } from 'common/hooks/useAssertSingleton'; import { useWorkflowLibraryModal } from 'features/nodes/store/workflowLibraryModal'; import { selectWorkflowIsTouched, workflowModeChanged } from 'features/nodes/store/workflowSlice'; +import type { WorkflowV3 } from 'features/nodes/types/workflow'; import { useLoadWorkflowFromLibrary } from 'features/workflowLibrary/hooks/useLoadWorkflowFromLibrary'; +import { useValidateAndLoadWorkflow } from 'features/workflowLibrary/hooks/useValidateAndLoadWorkflow'; import { atom } from 'nanostores'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -const $workflowToLoad = atom<{ workflowId: string; mode: 'view' | 'edit'; isOpen: boolean } | null>(null); +type LoadLibraryWorkflowData = { + type: 'library'; + workflowId: string; + mode: 'view' | 'edit'; +}; + +type LoadDirectWorkflowData = { + type: 'direct'; + workflow: WorkflowV3; + mode: 'view' | 'edit'; +}; + +const $workflowToLoad = atom< + (LoadLibraryWorkflowData & { isOpen: boolean }) | (LoadDirectWorkflowData & { isOpen: boolean }) | null +>(null); const cleanup = () => $workflowToLoad.set(null); export const useLoadWorkflow = () => { const dispatch = useAppDispatch(); const workflowLibraryModal = useWorkflowLibraryModal(); const loadWorkflowFromLibrary = useLoadWorkflowFromLibrary(); + const validatedAndLoadWorkflow = useValidateAndLoadWorkflow(); const isTouched = useAppSelector(selectWorkflowIsTouched); const loadImmediate = useCallback(async () => { - const workflow = $workflowToLoad.get(); - if (!workflow) { + const data = $workflowToLoad.get(); + if (!data) { return; } - const { workflowId, mode } = workflow; - await loadWorkflowFromLibrary(workflowId, { - onSuccess: () => { - dispatch(workflowModeChanged(mode)); - }, - }); + if (data.type === 'direct') { + const validatedWorkflow = await validatedAndLoadWorkflow(data.workflow); + if (validatedWorkflow) { + dispatch(workflowModeChanged(data.mode)); + } + } else { + await loadWorkflowFromLibrary(data.workflowId, { + onSuccess: () => { + dispatch(workflowModeChanged(data.mode)); + }, + }); + } cleanup(); workflowLibraryModal.close(); - }, [dispatch, loadWorkflowFromLibrary, workflowLibraryModal]); + }, [dispatch, loadWorkflowFromLibrary, validatedAndLoadWorkflow, workflowLibraryModal]); const loadWithDialog = useCallback( - (workflowId: string, mode: 'view' | 'edit') => { + (data: LoadLibraryWorkflowData | LoadDirectWorkflowData) => { if (!isTouched) { - $workflowToLoad.set({ - workflowId, - mode, - isOpen: false, - }); + $workflowToLoad.set({ ...data, isOpen: false }); loadImmediate(); } else { - $workflowToLoad.set({ - workflowId, - mode, - isOpen: true, - }); + $workflowToLoad.set({ ...data, isOpen: true }); } }, [loadImmediate, isTouched]