From 1e55010e2642afa58f66060e08389a48e78b9740 Mon Sep 17 00:00:00 2001 From: martmull Date: Tue, 19 Nov 2024 14:51:52 +0100 Subject: [PATCH] 8563 workflow workflow node does not open on step click (#8582) - fix multiple node selection - fix console error - fix close right drawer no unselect nodes - fix edges not selectable - fix sometime node not selected when clicking ## After https://github.com/user-attachments/assets/ceec847f-5b7d-4452-9685-81a845bbf21e --- .../right-drawer/components/RightDrawer.tsx | 26 +++++++++---------- .../right-drawer/hooks/useRightDrawer.ts | 2 ++ .../components/WorkflowDiagramCanvasBase.tsx | 23 +++++++++++++++- ...rkflowEditActionFormServerlessFunction.tsx | 8 +++--- .../states/workflowReactFlowRefState.ts | 8 ++++++ .../workflow/utils/generateWorkflowDiagram.ts | 1 + 6 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 packages/twenty-front/src/modules/workflow/states/workflowReactFlowRefState.ts diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx index 7823f8a7c0..437dd28c98 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx @@ -10,12 +10,7 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { motion } from 'framer-motion'; import { useRef } from 'react'; -import { - useRecoilCallback, - useRecoilState, - useRecoilValue, - useSetRecoilState, -} from 'recoil'; +import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil'; import { Key } from 'ts-key-enum'; import { isDefined } from '~/utils/isDefined'; @@ -24,8 +19,8 @@ import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState'; import { rightDrawerPageState } from '../states/rightDrawerPageState'; import { RightDrawerHotkeyScope } from '../types/RightDrawerHotkeyScope'; -import { emitRightDrawerCloseEvent } from '@/ui/layout/right-drawer/utils/emitRightDrawerCloseEvent'; import { RightDrawerRouter } from './RightDrawerRouter'; +import { workflowReactFlowRefState } from '@/workflow/states/workflowReactFlowRefState'; const StyledContainer = styled(motion.div)<{ isRightDrawerMinimized: boolean }>` background: ${({ theme }) => theme.background.primary}; @@ -94,9 +89,7 @@ export const RightDrawer = () => { type RightDrawerAnimationVariant = keyof typeof animationVariants; - const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState( - isRightDrawerOpenState, - ); + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState); @@ -109,13 +102,17 @@ export const RightDrawer = () => { const { closeRightDrawer } = useRightDrawer(); const rightDrawerRef = useRef(null); + const workflowReactFlowRef = useRecoilValue(workflowReactFlowRefState); const { useListenClickOutside } = useClickOutsideListener( RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID, ); useListenClickOutside({ - refs: [rightDrawerRef], + refs: [ + rightDrawerRef, + ...(workflowReactFlowRef ? [workflowReactFlowRef] : []), + ], callback: useRecoilCallback( ({ snapshot, set }) => (event) => { @@ -128,7 +125,6 @@ export const RightDrawer = () => { if (isRightDrawerOpen && !isRightDrawerMinimized) { set(rightDrawerCloseEventState, event); - emitRightDrawerCloseEvent(); closeRightDrawer(); } @@ -141,10 +137,12 @@ export const RightDrawer = () => { useScopedHotkeys( [Key.Escape], () => { - closeRightDrawer(); + if (isRightDrawerOpen && !isRightDrawerMinimized) { + closeRightDrawer(); + } }, RightDrawerHotkeyScope.RightDrawer, - [setIsRightDrawerOpen], + [isRightDrawerOpen, isRightDrawerMinimized], ); const isMobile = useIsMobile(); diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts index 9aeb48bc15..c7a9615280 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts @@ -6,6 +6,7 @@ import { rightDrawerCloseEventState } from '@/ui/layout/right-drawer/states/righ import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState'; import { rightDrawerPageState } from '../states/rightDrawerPageState'; import { RightDrawerPages } from '../types/RightDrawerPages'; +import { emitRightDrawerCloseEvent } from '@/ui/layout/right-drawer/utils/emitRightDrawerCloseEvent'; export const useRightDrawer = () => { const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); @@ -28,6 +29,7 @@ export const useRightDrawer = () => { () => { set(isRightDrawerOpenState, false); set(isRightDrawerMinimizedState, false); + emitRightDrawerCloseEvent(); }, [], ); diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx index 55aab89ae2..803e117235 100644 --- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx +++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx @@ -28,6 +28,8 @@ import '@xyflow/react/dist/style.css'; import React, { useEffect, useMemo, useRef } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { GRAY_SCALE, isDefined, THEME_COMMON } from 'twenty-ui'; +import { useListenRightDrawerClose } from '@/ui/layout/right-drawer/hooks/useListenRightDrawerClose'; +import { workflowReactFlowRefState } from '@/workflow/states/workflowReactFlowRefState'; const StyledResetReactflowStyles = styled.div` height: 100%; @@ -86,6 +88,9 @@ export const WorkflowDiagramCanvasBase = ({ children?: React.ReactNode; }) => { const reactflow = useReactFlow(); + const setWorkflowReactFlowRefState = useSetRecoilState( + workflowReactFlowRefState, + ); const { nodes, edges } = useMemo( () => getOrganizedDiagram(diagram), @@ -144,6 +149,12 @@ export const WorkflowDiagramCanvasBase = ({ }); }; + useListenRightDrawerClose(() => { + reactflow.setNodes((nodes) => + nodes.map((node) => ({ ...node, selected: false })), + ); + }); + const containerRef = useRef(null); useEffect(() => { @@ -176,6 +187,11 @@ export const WorkflowDiagramCanvasBase = ({ return ( { + if (isDefined(node)) { + setWorkflowReactFlowRefState({ current: node }); + } + }} onInit={() => { if (!isDefined(containerRef.current)) { throw new Error('Expect the container ref to be defined'); @@ -192,11 +208,16 @@ export const WorkflowDiagramCanvasBase = ({ minZoom={defaultFitViewOptions.minZoom} maxZoom={defaultFitViewOptions.maxZoom} nodeTypes={nodeTypes} - nodes={nodes.map((node) => ({ ...node, draggable: false }))} + nodes={nodes} edges={edges} onNodesChange={handleNodesChange} onEdgesChange={handleEdgesChange} proOptions={{ hideAttribution: true }} + multiSelectionKeyCode={null} + nodesFocusable={false} + edgesFocusable={false} + nodesDraggable={false} + paneClickDistance={10} // Fix small unwanted user dragging does not select node > diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx index 56a8b9e740..1e2467ed26 100644 --- a/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx +++ b/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx @@ -1,3 +1,5 @@ +import { ReactNode, Fragment } from 'react'; +import styled from '@emotion/styled'; import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions'; import { Select, SelectOption } from '@/ui/input/components/Select'; import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditGenericFormBase'; @@ -8,8 +10,6 @@ import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefa import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/utils/mergeDefaultFunctionInputAndFunctionInput'; import { setNestedValue } from '@/workflow/utils/setNestedValue'; import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { ReactNode } from 'react'; import { HorizontalSeparator, IconCode, isDefined } from 'twenty-ui'; import { useDebouncedCallback } from 'use-debounce'; @@ -165,12 +165,12 @@ export const WorkflowEditActionFormServerlessFunction = ({ if (inputValue !== null && typeof inputValue === 'object') { if (isRoot) { return ( - <> + {displaySeparator(functionInput) && ( )} {renderFields(inputValue, currentPath, false)} - + ); } return ( diff --git a/packages/twenty-front/src/modules/workflow/states/workflowReactFlowRefState.ts b/packages/twenty-front/src/modules/workflow/states/workflowReactFlowRefState.ts new file mode 100644 index 0000000000..7a56abac0b --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/states/workflowReactFlowRefState.ts @@ -0,0 +1,8 @@ +import { createState } from 'twenty-ui'; +import { RefObject } from 'react'; + +export const workflowReactFlowRefState = + createState | null>({ + key: 'workflowReactFlowRefState', + defaultValue: null, + }); diff --git a/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts b/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts index 99f1a49895..24f5c10f48 100644 --- a/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts +++ b/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts @@ -70,6 +70,7 @@ export const generateWorkflowDiagram = ({ type: MarkerType.ArrowClosed, }, deletable: false, + selectable: false, }); return nodeId;