From c494e0642aa78c2b7bc074fefdc730a9705ecb75 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Thu, 10 Oct 2024 12:10:20 +1000
Subject: [PATCH] feat(ui): split out new workflow dialog logic, use it in list
menu, restore new workflow dialog
---
.../frontend/web/src/app/components/App.tsx | 2 +
.../WorkflowListMenu/ActiveWorkflow.tsx | 40 ++++++------
.../NewWorkflowConfirmationAlertDialog.tsx | 64 ++++++++++---------
.../NewWorkflowMenuItem.tsx | 18 ++----
4 files changed, 62 insertions(+), 62 deletions(-)
diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx
index b18fe8c20e..d2d37108f5 100644
--- a/invokeai/frontend/web/src/app/components/App.tsx
+++ b/invokeai/frontend/web/src/app/components/App.tsx
@@ -27,6 +27,7 @@ import RefreshAfterResetModal from 'features/system/components/SettingsModal/Ref
import { configChanged } from 'features/system/store/configSlice';
import { selectLanguage } from 'features/system/store/systemSelectors';
import { AppContent } from 'features/ui/components/AppContent';
+import { NewWorkflowConfirmationAlertDialog } from 'features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog';
import { AnimatePresence } from 'framer-motion';
import i18n from 'i18n';
import { size } from 'lodash-es';
@@ -107,6 +108,7 @@ const App = ({ config = DEFAULT_CONFIG, studioInitAction }: Props) => {
+
diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/ActiveWorkflow.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/ActiveWorkflow.tsx
index 01e258cd05..e6e7a4c0a4 100644
--- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/ActiveWorkflow.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/ActiveWorkflow.tsx
@@ -1,13 +1,12 @@
import { Flex, IconButton, Spacer, Text, Tooltip } from '@invoke-ai/ui-library';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
+import { useAppSelector } from 'app/store/storeHooks';
import { ModeToggle } from 'features/nodes/components/sidePanel/ModeToggle';
-import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
-import { useWorkflowListMenu } from 'features/nodes/store/workflowListMenu';
import { selectWorkflowDescription, selectWorkflowMode, selectWorkflowName } from 'features/nodes/store/workflowSlice';
-import type { MouseEventHandler } from 'react';
+import { useNewWorkflow } from 'features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog';
+import type { MouseEvent } from 'react';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
-import { PiXBold } from 'react-icons/pi';
+import { PiFilePlusBold } from 'react-icons/pi';
import SaveWorkflowButton from './SaveWorkflowButton';
@@ -15,18 +14,17 @@ export const ActiveWorkflow = () => {
const activeWorkflowName = useAppSelector(selectWorkflowName);
const activeWorkflowDescription = useAppSelector(selectWorkflowDescription);
const mode = useAppSelector(selectWorkflowMode);
- const workflowListMenu = useWorkflowListMenu();
+ const newWorkflow = useNewWorkflow();
- const dispatch = useAppDispatch();
const { t } = useTranslation();
- const handleNewWorkflow = useCallback>(
- (e) => {
+ const onClickNewWorkflow = useCallback(
+ (e: MouseEvent) => {
+ // We need to stop the event from propagating to the parent element, else the click will open the list menu
e.stopPropagation();
- dispatch(nodeEditorReset());
- workflowListMenu.close();
+ newWorkflow.createWithDialog();
},
- [dispatch, workflowListMenu]
+ [newWorkflow]
);
return (
@@ -45,16 +43,14 @@ export const ActiveWorkflow = () => {
{mode === 'edit' && }
-
- }
- colorScheme="error"
- />
-
+ }
+ />
);
};
diff --git a/invokeai/frontend/web/src/features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog.tsx b/invokeai/frontend/web/src/features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog.tsx
index c0b5fee85b..a9a1033169 100644
--- a/invokeai/frontend/web/src/features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog.tsx
+++ b/invokeai/frontend/web/src/features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog.tsx
@@ -1,22 +1,21 @@
-import { ConfirmationAlertDialog, Flex, Text, useDisclosure } from '@invoke-ai/ui-library';
+import { ConfirmationAlertDialog, Flex, Text } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
+import { buildUseDisclosure } from 'common/hooks/useBoolean';
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
import { selectWorkflowIsTouched, workflowModeChanged } from 'features/nodes/store/workflowSlice';
import { toast } from 'features/toast/toast';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
-type Props = {
- renderButton: (onClick: () => void) => JSX.Element;
-};
+const [useDialogState] = buildUseDisclosure(false);
-export const NewWorkflowConfirmationAlertDialog = memo((props: Props) => {
+export const useNewWorkflow = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
- const { isOpen, onOpen, onClose } = useDisclosure();
+ const dialog = useDialogState();
const isTouched = useAppSelector(selectWorkflowIsTouched);
- const handleNewWorkflow = useCallback(() => {
+ const createImmediate = useCallback(() => {
dispatch(nodeEditorReset());
dispatch(workflowModeChanged('edit'));
@@ -26,34 +25,41 @@ export const NewWorkflowConfirmationAlertDialog = memo((props: Props) => {
status: 'success',
});
- onClose();
- }, [dispatch, onClose, t]);
+ dialog.close();
+ }, [dialog, dispatch, t]);
- const onClick = useCallback(() => {
+ const createWithDialog = useCallback(() => {
if (!isTouched) {
- handleNewWorkflow();
+ createImmediate();
return;
}
- onOpen();
- }, [handleNewWorkflow, isTouched, onOpen]);
+ dialog.open();
+ }, [dialog, createImmediate, isTouched]);
+
+ return {
+ createImmediate,
+ createWithDialog,
+ } as const;
+};
+
+export const NewWorkflowConfirmationAlertDialog = memo(() => {
+ const { t } = useTranslation();
+ const dialog = useDialogState();
+ const newWorkflow = useNewWorkflow();
return (
- <>
- {props.renderButton(onClick)}
-
-
-
- {t('nodes.newWorkflowDesc')}
- {t('nodes.newWorkflowDesc2')}
-
-
- >
+
+
+ {t('nodes.newWorkflowDesc')}
+ {t('nodes.newWorkflowDesc2')}
+
+
);
});
diff --git a/invokeai/frontend/web/src/features/workflowLibrary/components/WorkflowLibraryMenu/NewWorkflowMenuItem.tsx b/invokeai/frontend/web/src/features/workflowLibrary/components/WorkflowLibraryMenu/NewWorkflowMenuItem.tsx
index 6c5baa584f..2225b8c302 100644
--- a/invokeai/frontend/web/src/features/workflowLibrary/components/WorkflowLibraryMenu/NewWorkflowMenuItem.tsx
+++ b/invokeai/frontend/web/src/features/workflowLibrary/components/WorkflowLibraryMenu/NewWorkflowMenuItem.tsx
@@ -1,22 +1,18 @@
import { MenuItem } from '@invoke-ai/ui-library';
-import { NewWorkflowConfirmationAlertDialog } from 'features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog';
-import { memo, useCallback } from 'react';
+import { useNewWorkflow } from 'features/workflowLibrary/components/NewWorkflowConfirmationAlertDialog';
+import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiFilePlusBold } from 'react-icons/pi';
export const NewWorkflowMenuItem = memo(() => {
const { t } = useTranslation();
+ const newWorkflow = useNewWorkflow();
- const renderButton = useCallback(
- (onClick: () => void) => (
- } onClick={onClick}>
- {t('nodes.newWorkflow')}
-
- ),
- [t]
+ return (
+ } onClick={newWorkflow.createWithDialog}>
+ {t('nodes.newWorkflow')}
+
);
-
- return ;
});
NewWorkflowMenuItem.displayName = 'NewWorkflowMenuItem';