mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-31 04:37:56 +00:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -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<HTMLDivElement>(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(); | ||||
|   | ||||
| @@ -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(); | ||||
|       }, | ||||
|     [], | ||||
|   ); | ||||
|   | ||||
| @@ -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<HTMLDivElement>(null); | ||||
|  | ||||
|   useEffect(() => { | ||||
| @@ -176,6 +187,11 @@ export const WorkflowDiagramCanvasBase = ({ | ||||
|   return ( | ||||
|     <StyledResetReactflowStyles ref={containerRef}> | ||||
|       <ReactFlow | ||||
|         ref={(node) => { | ||||
|           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 | ||||
|       > | ||||
|         <Background color={GRAY_SCALE.gray25} size={2} /> | ||||
|  | ||||
|   | ||||
| @@ -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 ( | ||||
|             <> | ||||
|             <Fragment key={pathKey}> | ||||
|               {displaySeparator(functionInput) && ( | ||||
|                 <HorizontalSeparator noMargin /> | ||||
|               )} | ||||
|               {renderFields(inputValue, currentPath, false)} | ||||
|             </> | ||||
|             </Fragment> | ||||
|           ); | ||||
|         } | ||||
|         return ( | ||||
|   | ||||
| @@ -0,0 +1,8 @@ | ||||
| import { createState } from 'twenty-ui'; | ||||
| import { RefObject } from 'react'; | ||||
|  | ||||
| export const workflowReactFlowRefState = | ||||
|   createState<RefObject<HTMLDivElement> | null>({ | ||||
|     key: 'workflowReactFlowRefState', | ||||
|     defaultValue: null, | ||||
|   }); | ||||
| @@ -70,6 +70,7 @@ export const generateWorkflowDiagram = ({ | ||||
|         type: MarkerType.ArrowClosed, | ||||
|       }, | ||||
|       deletable: false, | ||||
|       selectable: false, | ||||
|     }); | ||||
|  | ||||
|     return nodeId; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 martmull
					martmull