9426 migrate workflow pages to command menu (#9515)
Closes twentyhq/core-team-issues#53 - Removes command menu top bar text input when the user is not on root page - Fixes bug when resetting command menu context - Added animations on command menu open and close - Refactored workflow visualizer code to remove unnecessary rerenders and props drilling https://github.com/user-attachments/assets/1da3adb8-220b-407b-9279-30354d3100d3
This commit is contained in:
@ -1,12 +1,14 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { useOpenEmailThreadRightDrawer } from '@/activities/emails/right-drawer/hooks/useOpenEmailThreadRightDrawer';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState';
|
||||
|
||||
export const useEmailThread = () => {
|
||||
const { closeRightDrawer } = useRightDrawer();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
const openEmailThreadRightDrawer = useOpenEmailThreadRightDrawer();
|
||||
|
||||
const openEmailThread = useRecoilCallback(
|
||||
@ -23,13 +25,14 @@ export const useEmailThread = () => {
|
||||
if (isRightDrawerOpen && viewableEmailThreadId === threadId) {
|
||||
set(viewableRecordIdState, null);
|
||||
closeRightDrawer();
|
||||
closeCommandMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
openEmailThreadRightDrawer();
|
||||
set(viewableRecordIdState, threadId);
|
||||
},
|
||||
[closeRightDrawer, openEmailThreadRightDrawer],
|
||||
[closeRightDrawer, closeCommandMenu, openEmailThreadRightDrawer],
|
||||
);
|
||||
|
||||
return { openEmailThread };
|
||||
|
||||
@ -3,20 +3,25 @@ import { RecordAgnosticActionsSetterEffect } from '@/action-menu/actions/record-
|
||||
import { ActionMenuConfirmationModals } from '@/action-menu/components/ActionMenuConfirmationModals';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
|
||||
import { COMMAND_MENU_ANIMATION_VARIANTS } from '@/command-menu/constants/CommandMenuAnimationVariants';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useCommandMenuHotKeys } from '@/command-menu/hooks/useCommandMenuHotKeys';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { CommandMenuAnimationVariant } from '@/command-menu/types/CommandMenuAnimationVariant';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { workflowReactFlowRefState } from '@/workflow/workflow-diagram/states/workflowReactFlowRefState';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useIsMobile } from 'twenty-ui';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
const StyledCommandMenu = styled.div`
|
||||
const StyledCommandMenu = styled(motion.div)`
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border-left: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.strong};
|
||||
@ -27,8 +32,9 @@ const StyledCommandMenu = styled.div`
|
||||
position: fixed;
|
||||
right: 0%;
|
||||
top: 0%;
|
||||
width: ${() => (useIsMobile() ? '100%' : '500px')};
|
||||
z-index: 30;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
export const CommandMenuContainer = ({
|
||||
@ -45,15 +51,28 @@ export const CommandMenuContainer = ({
|
||||
|
||||
const commandMenuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const workflowReactFlowRef = useRecoilValue(workflowReactFlowRefState);
|
||||
|
||||
useCommandMenuHotKeys();
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [commandMenuRef],
|
||||
refs: [
|
||||
commandMenuRef,
|
||||
...(workflowReactFlowRef ? [workflowReactFlowRef] : []),
|
||||
],
|
||||
callback: closeCommandMenu,
|
||||
listenerId: 'COMMAND_MENU_LISTENER_ID',
|
||||
hotkeyScope: AppHotkeyScope.CommandMenuOpen,
|
||||
});
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const targetVariantForAnimation: CommandMenuAnimationVariant = isMobile
|
||||
? 'fullScreen'
|
||||
: 'normal';
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<ContextStoreComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'command-menu' }}
|
||||
@ -71,7 +90,17 @@ export const CommandMenuContainer = ({
|
||||
{isWorkflowEnabled && <RecordAgnosticActionsSetterEffect />}
|
||||
<ActionMenuConfirmationModals />
|
||||
{isCommandMenuOpened && (
|
||||
<StyledCommandMenu ref={commandMenuRef} className="command-menu">
|
||||
<StyledCommandMenu
|
||||
ref={commandMenuRef}
|
||||
className="command-menu"
|
||||
animate={targetVariantForAnimation}
|
||||
initial="closed"
|
||||
exit="closed"
|
||||
variants={COMMAND_MENU_ANIMATION_VARIANTS}
|
||||
transition={{
|
||||
duration: theme.animation.duration.normal,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</StyledCommandMenu>
|
||||
)}
|
||||
|
||||
@ -3,4 +3,8 @@ export enum CommandMenuPages {
|
||||
ViewRecord = 'view-record',
|
||||
ViewEmailThread = 'view-email-thread',
|
||||
ViewCalendarEvent = 'view-calendar-event',
|
||||
WorkflowStepSelectTriggerType = 'workflow-step-select-trigger-type',
|
||||
WorkflowStepSelectAction = 'workflow-step-select-action',
|
||||
WorkflowStepView = 'workflow-step-view',
|
||||
WorkflowStepEdit = 'workflow-step-edit',
|
||||
}
|
||||
|
||||
@ -2,9 +2,15 @@ import { CommandMenuContainer } from '@/command-menu/components/CommandMenuConta
|
||||
import { CommandMenuTopBar } from '@/command-menu/components/CommandMenuTopBar';
|
||||
import { COMMAND_MENU_PAGES_CONFIG } from '@/command-menu/constants/CommandMenuPagesConfig';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
const StyledCommandMenuContent = styled.div`
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
`;
|
||||
|
||||
export const CommandMenuRouter = () => {
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
|
||||
@ -17,7 +23,9 @@ export const CommandMenuRouter = () => {
|
||||
return (
|
||||
<CommandMenuContainer>
|
||||
<CommandMenuTopBar />
|
||||
{commandMenuPageComponent}
|
||||
<StyledCommandMenuContent>
|
||||
{commandMenuPageComponent}
|
||||
</StyledCommandMenuContent>
|
||||
</CommandMenuContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import { CommandMenuContextRecordChip } from '@/command-menu/components/CommandMenuContextRecordChip';
|
||||
import { CommandMenuPages } from '@/command-menu/components/CommandMenuPages';
|
||||
import { COMMAND_MENU_SEARCH_BAR_HEIGHT } from '@/command-menu/constants/CommandMenuSearchBarHeight';
|
||||
import { COMMAND_MENU_SEARCH_BAR_PADDING } from '@/command-menu/constants/CommandMenuSearchBarPadding';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { IconX, LightIconButton, isDefined, useIsMobile } from 'twenty-ui';
|
||||
|
||||
const StyledInputContainer = styled.div`
|
||||
@ -17,6 +19,7 @@ const StyledInputContainer = styled.div`
|
||||
border-radius: 0;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: ${({ theme }) => theme.font.size.lg};
|
||||
height: ${COMMAND_MENU_SEARCH_BAR_HEIGHT}px;
|
||||
margin: 0;
|
||||
@ -25,6 +28,7 @@ const StyledInputContainer = styled.div`
|
||||
|
||||
padding: 0 ${({ theme }) => theme.spacing(COMMAND_MENU_SEARCH_BAR_PADDING)};
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const StyledInput = styled.input`
|
||||
@ -45,6 +49,13 @@ const StyledInput = styled.input`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const StyledCloseButtonContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
@ -69,19 +80,25 @@ export const CommandMenuTopBar = () => {
|
||||
contextStoreCurrentObjectMetadataIdComponentState,
|
||||
);
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
|
||||
return (
|
||||
<StyledInputContainer>
|
||||
{isDefined(contextStoreCurrentObjectMetadataId) && (
|
||||
<CommandMenuContextRecordChip
|
||||
objectMetadataItemId={contextStoreCurrentObjectMetadataId}
|
||||
/>
|
||||
)}
|
||||
<StyledInput
|
||||
autoFocus
|
||||
value={commandMenuSearch}
|
||||
placeholder="Type anything"
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
<StyledContentContainer>
|
||||
{isDefined(contextStoreCurrentObjectMetadataId) && (
|
||||
<CommandMenuContextRecordChip
|
||||
objectMetadataItemId={contextStoreCurrentObjectMetadataId}
|
||||
/>
|
||||
)}
|
||||
{commandMenuPage === CommandMenuPages.Root && (
|
||||
<StyledInput
|
||||
autoFocus
|
||||
value={commandMenuSearch}
|
||||
placeholder="Type anything"
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
)}
|
||||
</StyledContentContainer>
|
||||
{!isMobile && (
|
||||
<StyledCloseButtonContainer>
|
||||
<LightIconButton
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import { THEME_COMMON } from 'twenty-ui';
|
||||
|
||||
export const COMMAND_MENU_ANIMATION_VARIANTS = {
|
||||
fullScreen: {
|
||||
x: '0%',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
bottom: '0',
|
||||
top: '0',
|
||||
},
|
||||
normal: {
|
||||
x: '0%',
|
||||
width: THEME_COMMON.rightDrawerWidth,
|
||||
height: '100%',
|
||||
bottom: '0',
|
||||
top: '0',
|
||||
},
|
||||
closed: {
|
||||
x: '100%',
|
||||
width: THEME_COMMON.rightDrawerWidth,
|
||||
height: '100%',
|
||||
bottom: '0',
|
||||
top: 'auto',
|
||||
},
|
||||
};
|
||||
@ -3,6 +3,10 @@ import { RightDrawerEmailThread } from '@/activities/emails/right-drawer/compone
|
||||
import { CommandMenu } from '@/command-menu/components/CommandMenu';
|
||||
import { CommandMenuPages } from '@/command-menu/components/CommandMenuPages';
|
||||
import { RightDrawerRecord } from '@/object-record/record-right-drawer/components/RightDrawerRecord';
|
||||
import { RightDrawerWorkflowEditStep } from '@/workflow/workflow-steps/components/RightDrawerWorkflowEditStep';
|
||||
import { RightDrawerWorkflowViewStep } from '@/workflow/workflow-steps/components/RightDrawerWorkflowViewStep';
|
||||
import { RightDrawerWorkflowSelectAction } from '@/workflow/workflow-steps/workflow-actions/components/RightDrawerWorkflowSelectAction';
|
||||
import { RightDrawerWorkflowSelectTriggerType } from '@/workflow/workflow-trigger/components/RightDrawerWorkflowSelectTriggerType';
|
||||
|
||||
export const COMMAND_MENU_PAGES_CONFIG = new Map<
|
||||
CommandMenuPages,
|
||||
@ -12,4 +16,14 @@ export const COMMAND_MENU_PAGES_CONFIG = new Map<
|
||||
[CommandMenuPages.ViewRecord, <RightDrawerRecord />],
|
||||
[CommandMenuPages.ViewEmailThread, <RightDrawerEmailThread />],
|
||||
[CommandMenuPages.ViewCalendarEvent, <RightDrawerCalendarEvent />],
|
||||
[
|
||||
CommandMenuPages.WorkflowStepSelectTriggerType,
|
||||
<RightDrawerWorkflowSelectTriggerType />,
|
||||
],
|
||||
[
|
||||
CommandMenuPages.WorkflowStepSelectAction,
|
||||
<RightDrawerWorkflowSelectAction />,
|
||||
],
|
||||
[CommandMenuPages.WorkflowStepEdit, <RightDrawerWorkflowEditStep />],
|
||||
[CommandMenuPages.WorkflowStepView, <RightDrawerWorkflowViewStep />],
|
||||
]);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
@ -17,10 +17,10 @@ import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-sto
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { mainContextStoreComponentInstanceIdState } from '@/context-store/states/mainContextStoreComponentInstanceId';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import { emitRightDrawerCloseEvent } from '@/ui/layout/right-drawer/utils/emitRightDrawerCloseEvent';
|
||||
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
|
||||
|
||||
export const useCommandMenu = () => {
|
||||
const setIsCommandMenuOpened = useSetRecoilState(isCommandMenuOpenedState);
|
||||
const { resetSelectedItem } = useSelectableList('command-menu-list');
|
||||
const {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
@ -141,13 +141,12 @@ export const useCommandMenu = () => {
|
||||
actionMenuEntries,
|
||||
);
|
||||
|
||||
setIsCommandMenuOpened(true);
|
||||
set(isCommandMenuOpenedState, true);
|
||||
setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenuOpen);
|
||||
},
|
||||
[
|
||||
mainContextStoreComponentInstanceId,
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
setIsCommandMenuOpened,
|
||||
],
|
||||
);
|
||||
|
||||
@ -158,67 +157,69 @@ export const useCommandMenu = () => {
|
||||
.getLoadable(isCommandMenuOpenedState)
|
||||
.getValue();
|
||||
|
||||
set(
|
||||
contextStoreCurrentObjectMetadataIdComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
0,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
|
||||
set(
|
||||
actionMenuEntriesComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
new Map(),
|
||||
);
|
||||
|
||||
if (isCommandMenuOpened) {
|
||||
set(
|
||||
contextStoreCurrentObjectMetadataIdComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
0,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
|
||||
set(
|
||||
actionMenuEntriesComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
new Map(),
|
||||
);
|
||||
|
||||
set(viewableRecordIdState, null);
|
||||
set(commandMenuPageState, CommandMenuPages.Root);
|
||||
setIsCommandMenuOpened(false);
|
||||
set(isCommandMenuOpenedState, false);
|
||||
resetSelectedItem();
|
||||
goBackToPreviousHotkeyScope();
|
||||
|
||||
emitRightDrawerCloseEvent();
|
||||
}
|
||||
},
|
||||
[goBackToPreviousHotkeyScope, resetSelectedItem, setIsCommandMenuOpened],
|
||||
[goBackToPreviousHotkeyScope, resetSelectedItem],
|
||||
);
|
||||
|
||||
const toggleCommandMenu = useRecoilCallback(
|
||||
@ -250,10 +251,39 @@ export const useCommandMenu = () => {
|
||||
[openCommandMenu],
|
||||
);
|
||||
|
||||
const setGlobalCommandMenuContext = useRecoilCallback(({ set }) => {
|
||||
return () => {
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
0,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: 'command-menu',
|
||||
}),
|
||||
null,
|
||||
);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return {
|
||||
openCommandMenu,
|
||||
closeCommandMenu,
|
||||
openRecordInCommandMenu,
|
||||
toggleCommandMenu,
|
||||
resetCommandMenuContext: setGlobalCommandMenuContext,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,32 +1,24 @@
|
||||
import { CommandMenuPages } from '@/command-menu/components/CommandMenuPages';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
export const useCommandMenuHotKeys = () => {
|
||||
const { closeCommandMenu, toggleCommandMenu } = useCommandMenu();
|
||||
const { closeCommandMenu, toggleCommandMenu, resetCommandMenuContext } =
|
||||
useCommandMenu();
|
||||
|
||||
const commandMenuSearch = useRecoilValue(commandMenuSearchState);
|
||||
|
||||
const setContextStoreTargetedRecordsRule = useSetRecoilComponentStateV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
'command-menu',
|
||||
);
|
||||
|
||||
const setContextStoreNumberOfSelectedRecords = useSetRecoilComponentStateV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
'command-menu',
|
||||
);
|
||||
|
||||
const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
|
||||
useScopedHotkeys(
|
||||
'ctrl+k,meta+k',
|
||||
() => {
|
||||
@ -49,13 +41,11 @@ export const useCommandMenuHotKeys = () => {
|
||||
useScopedHotkeys(
|
||||
[Key.Backspace, Key.Delete],
|
||||
() => {
|
||||
if (!isNonEmptyString(commandMenuSearch)) {
|
||||
setContextStoreTargetedRecordsRule({
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
});
|
||||
|
||||
setContextStoreNumberOfSelectedRecords(0);
|
||||
if (
|
||||
commandMenuPage === CommandMenuPages.Root &&
|
||||
!isNonEmptyString(commandMenuSearch)
|
||||
) {
|
||||
resetCommandMenuContext();
|
||||
}
|
||||
},
|
||||
AppHotkeyScope.CommandMenuOpen,
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
import { COMMAND_MENU_ANIMATION_VARIANTS } from '@/command-menu/constants/CommandMenuAnimationVariants';
|
||||
|
||||
export type CommandMenuAnimationVariant =
|
||||
keyof typeof COMMAND_MENU_ANIMATION_VARIANTS;
|
||||
@ -11,6 +11,14 @@ export const mapRightDrawerPageToCommandMenuPage = (
|
||||
return CommandMenuPages.ViewEmailThread;
|
||||
case RightDrawerPages.ViewCalendarEvent:
|
||||
return CommandMenuPages.ViewCalendarEvent;
|
||||
case RightDrawerPages.WorkflowStepSelectTriggerType:
|
||||
return CommandMenuPages.WorkflowStepSelectTriggerType;
|
||||
case RightDrawerPages.WorkflowStepSelectAction:
|
||||
return CommandMenuPages.WorkflowStepSelectAction;
|
||||
case RightDrawerPages.WorkflowStepView:
|
||||
return CommandMenuPages.WorkflowStepView;
|
||||
case RightDrawerPages.WorkflowStepEdit:
|
||||
return CommandMenuPages.WorkflowStepEdit;
|
||||
default:
|
||||
return CommandMenuPages.Root;
|
||||
}
|
||||
|
||||
@ -34,13 +34,18 @@ export const useSelectableList = (selectableListId?: string) => {
|
||||
);
|
||||
|
||||
const setSelectedItemId = useRecoilCallback(
|
||||
({ set }) =>
|
||||
({ set, snapshot }) =>
|
||||
(itemId: string) => {
|
||||
resetSelectedItem();
|
||||
const selectedItemId = getSnapshotValue(snapshot, selectedItemIdState);
|
||||
|
||||
if (isDefined(selectedItemId)) {
|
||||
set(isSelectedItemIdSelector(selectedItemId), false);
|
||||
}
|
||||
|
||||
set(selectedItemIdState, itemId);
|
||||
set(isSelectedItemIdSelector(itemId), true);
|
||||
},
|
||||
[resetSelectedItem, selectedItemIdState, isSelectedItemIdSelector],
|
||||
[selectedItemIdState, isSelectedItemIdSelector],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useListenRightDrawerClose } from '@/ui/layout/right-drawer/hooks/useListenRightDrawerClose';
|
||||
import { isRightDrawerMinimizedState } from '@/ui/layout/right-drawer/states/isRightDrawerMinimizedState';
|
||||
import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { WorkflowVersionStatus } from '@/workflow/types/Workflow';
|
||||
import { WorkflowVersionStatusTag } from '@/workflow/workflow-diagram/components/WorkflowVersionStatusTag';
|
||||
import { useRightDrawerState } from '@/workflow/workflow-diagram/hooks/useRightDrawerState';
|
||||
import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState';
|
||||
import { workflowReactFlowRefState } from '@/workflow/workflow-diagram/states/workflowReactFlowRefState';
|
||||
import {
|
||||
WorkflowDiagram,
|
||||
WorkflowDiagramEdge,
|
||||
WorkflowDiagramNode,
|
||||
WorkflowDiagramNodeType,
|
||||
@ -16,21 +14,21 @@ import { getOrganizedDiagram } from '@/workflow/workflow-diagram/utils/getOrgani
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
applyEdgeChanges,
|
||||
applyNodeChanges,
|
||||
Background,
|
||||
EdgeChange,
|
||||
FitViewOptions,
|
||||
getNodesBounds,
|
||||
NodeChange,
|
||||
NodeProps,
|
||||
ReactFlow,
|
||||
applyEdgeChanges,
|
||||
applyNodeChanges,
|
||||
getNodesBounds,
|
||||
useReactFlow,
|
||||
} from '@xyflow/react';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
import React, { useEffect, useMemo, useRef } from 'react';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { isDefined, THEME_COMMON } from 'twenty-ui';
|
||||
import { THEME_COMMON, isDefined } from 'twenty-ui';
|
||||
|
||||
const StyledResetReactflowStyles = styled.div`
|
||||
height: 100%;
|
||||
@ -68,12 +66,10 @@ const defaultFitViewOptions = {
|
||||
} satisfies FitViewOptions;
|
||||
|
||||
export const WorkflowDiagramCanvasBase = ({
|
||||
diagram,
|
||||
status,
|
||||
nodeTypes,
|
||||
children,
|
||||
}: {
|
||||
diagram: WorkflowDiagram;
|
||||
status: WorkflowVersionStatus;
|
||||
nodeTypes: Partial<
|
||||
Record<
|
||||
@ -95,22 +91,17 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
workflowReactFlowRefState,
|
||||
);
|
||||
|
||||
const workflowDiagram = useRecoilValue(workflowDiagramState);
|
||||
|
||||
const { nodes, edges } = useMemo(
|
||||
() => getOrganizedDiagram(diagram),
|
||||
[diagram],
|
||||
() =>
|
||||
isDefined(workflowDiagram)
|
||||
? getOrganizedDiagram(workflowDiagram)
|
||||
: { nodes: [], edges: [] },
|
||||
[workflowDiagram],
|
||||
);
|
||||
|
||||
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
|
||||
const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const rightDrawerState = !isRightDrawerOpen
|
||||
? 'closed'
|
||||
: isRightDrawerMinimized
|
||||
? 'minimized'
|
||||
: isMobile
|
||||
? 'fullScreen'
|
||||
: 'normal';
|
||||
const { rightDrawerState } = useRightDrawerState();
|
||||
|
||||
const rightDrawerWidth = Number(
|
||||
THEME_COMMON.rightDrawerWidth.replace('px', ''),
|
||||
@ -187,6 +178,8 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
);
|
||||
}, [reactflow, rightDrawerState, rightDrawerWidth]);
|
||||
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
return (
|
||||
<StyledResetReactflowStyles ref={containerRef}>
|
||||
<ReactFlow
|
||||
@ -220,6 +213,7 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
nodesFocusable={false}
|
||||
edgesFocusable={false}
|
||||
nodesDraggable={false}
|
||||
onPaneClick={closeCommandMenu}
|
||||
paneClickDistance={10} // Fix small unwanted user dragging does not select node
|
||||
>
|
||||
<Background color={theme.border.color.medium} size={2} />
|
||||
|
||||
@ -4,29 +4,24 @@ import { WorkflowDiagramCanvasEditableEffect } from '@/workflow/workflow-diagram
|
||||
import { WorkflowDiagramCreateStepNode } from '@/workflow/workflow-diagram/components/WorkflowDiagramCreateStepNode';
|
||||
import { WorkflowDiagramEmptyTrigger } from '@/workflow/workflow-diagram/components/WorkflowDiagramEmptyTrigger';
|
||||
import { WorkflowDiagramStepNodeEditable } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditable';
|
||||
import { WorkflowDiagram } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { ReactFlowProvider } from '@xyflow/react';
|
||||
|
||||
export const WorkflowDiagramCanvasEditable = ({
|
||||
diagram,
|
||||
workflowWithCurrentVersion,
|
||||
}: {
|
||||
diagram: WorkflowDiagram;
|
||||
workflowWithCurrentVersion: WorkflowWithCurrentVersion;
|
||||
}) => {
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<WorkflowDiagramCanvasBase
|
||||
diagram={diagram}
|
||||
status={workflowWithCurrentVersion.currentVersion.status}
|
||||
nodeTypes={{
|
||||
default: WorkflowDiagramStepNodeEditable,
|
||||
'create-step': WorkflowDiagramCreateStepNode,
|
||||
'empty-trigger': WorkflowDiagramEmptyTrigger,
|
||||
}}
|
||||
>
|
||||
<WorkflowDiagramCanvasEditableEffect />
|
||||
</WorkflowDiagramCanvasBase>
|
||||
/>
|
||||
<WorkflowDiagramCanvasEditableEffect />
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||
@ -17,6 +18,8 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
const { startNodeCreation } = useStartNodeCreation();
|
||||
|
||||
const { openRightDrawer, closeRightDrawer } = useRightDrawer();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const setWorkflowSelectedNode = useSetRecoilState(workflowSelectedNodeState);
|
||||
@ -28,7 +31,7 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
|
||||
if (isClosingStep) {
|
||||
closeRightDrawer();
|
||||
|
||||
closeCommandMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -55,10 +58,11 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
openRightDrawer(RightDrawerPages.WorkflowStepEdit);
|
||||
},
|
||||
[
|
||||
setHotkeyScope,
|
||||
closeRightDrawer,
|
||||
openRightDrawer,
|
||||
setWorkflowSelectedNode,
|
||||
setHotkeyScope,
|
||||
openRightDrawer,
|
||||
closeRightDrawer,
|
||||
closeCommandMenu,
|
||||
startNodeCreation,
|
||||
],
|
||||
);
|
||||
|
||||
@ -3,28 +3,23 @@ import { WorkflowDiagramCanvasBase } from '@/workflow/workflow-diagram/component
|
||||
import { WorkflowDiagramCanvasReadonlyEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasReadonlyEffect';
|
||||
import { WorkflowDiagramEmptyTrigger } from '@/workflow/workflow-diagram/components/WorkflowDiagramEmptyTrigger';
|
||||
import { WorkflowDiagramStepNodeReadonly } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeReadonly';
|
||||
import { WorkflowDiagram } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { ReactFlowProvider } from '@xyflow/react';
|
||||
|
||||
export const WorkflowDiagramCanvasReadonly = ({
|
||||
diagram,
|
||||
workflowVersion,
|
||||
}: {
|
||||
diagram: WorkflowDiagram;
|
||||
workflowVersion: WorkflowVersion;
|
||||
}) => {
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<WorkflowDiagramCanvasBase
|
||||
diagram={diagram}
|
||||
status={workflowVersion.status}
|
||||
nodeTypes={{
|
||||
default: WorkflowDiagramStepNodeReadonly,
|
||||
'empty-trigger': WorkflowDiagramEmptyTrigger,
|
||||
}}
|
||||
>
|
||||
<WorkflowDiagramCanvasReadonlyEffect />
|
||||
</WorkflowDiagramCanvasBase>
|
||||
/>
|
||||
<WorkflowDiagramCanvasReadonlyEffect />
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||
@ -14,6 +15,7 @@ export const WorkflowDiagramCanvasReadonlyEffect = () => {
|
||||
const { openRightDrawer, closeRightDrawer } = useRightDrawer();
|
||||
const setWorkflowSelectedNode = useSetRecoilState(workflowSelectedNodeState);
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const handleSelectionChange = useCallback(
|
||||
({ nodes }: OnSelectionChangeParams) => {
|
||||
@ -22,7 +24,7 @@ export const WorkflowDiagramCanvasReadonlyEffect = () => {
|
||||
|
||||
if (isClosingStep) {
|
||||
closeRightDrawer();
|
||||
|
||||
closeCommandMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -31,10 +33,11 @@ export const WorkflowDiagramCanvasReadonlyEffect = () => {
|
||||
openRightDrawer(RightDrawerPages.WorkflowStepView);
|
||||
},
|
||||
[
|
||||
closeRightDrawer,
|
||||
openRightDrawer,
|
||||
setWorkflowSelectedNode,
|
||||
setHotkeyScope,
|
||||
openRightDrawer,
|
||||
closeRightDrawer,
|
||||
closeCommandMenu,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion';
|
||||
import { WorkflowDiagramCanvasReadonly } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasReadonly';
|
||||
import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
export const WorkflowVersionVisualizer = ({
|
||||
@ -12,12 +10,7 @@ export const WorkflowVersionVisualizer = ({
|
||||
}) => {
|
||||
const workflowVersion = useWorkflowVersion(workflowVersionId);
|
||||
|
||||
const workflowDiagram = useRecoilValue(workflowDiagramState);
|
||||
|
||||
return isDefined(workflowDiagram) && isDefined(workflowVersion) ? (
|
||||
<WorkflowDiagramCanvasReadonly
|
||||
diagram={workflowDiagram}
|
||||
workflowVersion={workflowVersion}
|
||||
/>
|
||||
return isDefined(workflowVersion) ? (
|
||||
<WorkflowDiagramCanvasReadonly workflowVersion={workflowVersion} />
|
||||
) : null;
|
||||
};
|
||||
|
||||
@ -2,9 +2,7 @@ import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableE
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { WorkflowDiagramCanvasEditable } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable';
|
||||
import { WorkflowDiagramEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramEffect';
|
||||
import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
export const WorkflowVisualizer = ({
|
||||
@ -15,7 +13,6 @@ export const WorkflowVisualizer = ({
|
||||
const workflowId = targetableObject.id;
|
||||
|
||||
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(workflowId);
|
||||
const workflowDiagram = useRecoilValue(workflowDiagramState);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -23,9 +20,8 @@ export const WorkflowVisualizer = ({
|
||||
workflowWithCurrentVersion={workflowWithCurrentVersion}
|
||||
/>
|
||||
|
||||
{isDefined(workflowDiagram) && isDefined(workflowWithCurrentVersion) ? (
|
||||
{isDefined(workflowWithCurrentVersion) ? (
|
||||
<WorkflowDiagramCanvasEditable
|
||||
diagram={workflowDiagram}
|
||||
workflowWithCurrentVersion={workflowWithCurrentVersion}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { CommandMenuAnimationVariant } from '@/command-menu/types/CommandMenuAnimationVariant';
|
||||
import { isRightDrawerMinimizedState } from '@/ui/layout/right-drawer/states/isRightDrawerMinimizedState';
|
||||
import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState';
|
||||
import { RightDrawerAnimationVariant } from '@/ui/layout/right-drawer/types/RightDrawerAnimationVariant';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useIsMobile } from 'twenty-ui';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const useRightDrawerState = (): {
|
||||
rightDrawerState: RightDrawerAnimationVariant | CommandMenuAnimationVariant;
|
||||
} => {
|
||||
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
|
||||
const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const isCommandMenuV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IsCommandMenuV2Enabled,
|
||||
);
|
||||
|
||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||
|
||||
if (isMobile) {
|
||||
return {
|
||||
rightDrawerState: 'fullScreen',
|
||||
};
|
||||
}
|
||||
|
||||
if (isCommandMenuV2Enabled) {
|
||||
return {
|
||||
rightDrawerState: isCommandMenuOpened ? 'normal' : 'closed',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
rightDrawerState: !isRightDrawerOpen
|
||||
? 'closed'
|
||||
: isRightDrawerMinimized
|
||||
? 'minimized'
|
||||
: 'normal',
|
||||
};
|
||||
};
|
||||
@ -1,6 +1,7 @@
|
||||
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||
import { useDeleteStep } from '@/workflow/workflow-steps/hooks/useDeleteStep';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
const mockCloseRightDrawer = jest.fn();
|
||||
const mockCreateNewWorkflowVersion = jest.fn();
|
||||
@ -13,12 +14,6 @@ jest.mock('@/object-record/hooks/useUpdateOneRecord', () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('recoil', () => ({
|
||||
useRecoilValue: () => 'parent-step-id',
|
||||
useSetRecoilState: () => jest.fn(),
|
||||
atom: (params: any) => params,
|
||||
}));
|
||||
|
||||
jest.mock('@/ui/layout/right-drawer/hooks/useRightDrawer', () => ({
|
||||
useRightDrawer: () => ({
|
||||
closeRightDrawer: mockCloseRightDrawer,
|
||||
@ -50,10 +45,12 @@ describe('useDeleteStep', () => {
|
||||
};
|
||||
|
||||
it('should delete step in draft version', async () => {
|
||||
const { result } = renderHook(() =>
|
||||
useDeleteStep({
|
||||
workflow: mockWorkflow as unknown as WorkflowWithCurrentVersion,
|
||||
}),
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useDeleteStep({
|
||||
workflow: mockWorkflow as unknown as WorkflowWithCurrentVersion,
|
||||
}),
|
||||
{ wrapper: RecoilRoot },
|
||||
);
|
||||
await result.current.deleteStep('1');
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
@ -22,9 +23,11 @@ export const useDeleteStep = ({
|
||||
|
||||
const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
|
||||
const { closeRightDrawer } = useRightDrawer();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const deleteStep = async (stepId: string) => {
|
||||
closeRightDrawer();
|
||||
closeCommandMenu();
|
||||
const workflowVersion = await getUpdatableWorkflowVersion(workflow);
|
||||
if (stepId === TRIGGER_STEP_ID) {
|
||||
await updateOneWorkflowVersion({
|
||||
|
||||
Reference in New Issue
Block a user