mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-22 03:17:40 +03: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:
parent
86c2e9f0e4
commit
1e55010e26
@ -10,12 +10,7 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import {
|
import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
useRecoilCallback,
|
|
||||||
useRecoilState,
|
|
||||||
useRecoilValue,
|
|
||||||
useSetRecoilState,
|
|
||||||
} from 'recoil';
|
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
@ -24,8 +19,8 @@ import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState';
|
|||||||
import { rightDrawerPageState } from '../states/rightDrawerPageState';
|
import { rightDrawerPageState } from '../states/rightDrawerPageState';
|
||||||
import { RightDrawerHotkeyScope } from '../types/RightDrawerHotkeyScope';
|
import { RightDrawerHotkeyScope } from '../types/RightDrawerHotkeyScope';
|
||||||
|
|
||||||
import { emitRightDrawerCloseEvent } from '@/ui/layout/right-drawer/utils/emitRightDrawerCloseEvent';
|
|
||||||
import { RightDrawerRouter } from './RightDrawerRouter';
|
import { RightDrawerRouter } from './RightDrawerRouter';
|
||||||
|
import { workflowReactFlowRefState } from '@/workflow/states/workflowReactFlowRefState';
|
||||||
|
|
||||||
const StyledContainer = styled(motion.div)<{ isRightDrawerMinimized: boolean }>`
|
const StyledContainer = styled(motion.div)<{ isRightDrawerMinimized: boolean }>`
|
||||||
background: ${({ theme }) => theme.background.primary};
|
background: ${({ theme }) => theme.background.primary};
|
||||||
@ -94,9 +89,7 @@ export const RightDrawer = () => {
|
|||||||
|
|
||||||
type RightDrawerAnimationVariant = keyof typeof animationVariants;
|
type RightDrawerAnimationVariant = keyof typeof animationVariants;
|
||||||
|
|
||||||
const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState(
|
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
|
||||||
isRightDrawerOpenState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState);
|
const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState);
|
||||||
|
|
||||||
@ -109,13 +102,17 @@ export const RightDrawer = () => {
|
|||||||
const { closeRightDrawer } = useRightDrawer();
|
const { closeRightDrawer } = useRightDrawer();
|
||||||
|
|
||||||
const rightDrawerRef = useRef<HTMLDivElement>(null);
|
const rightDrawerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const workflowReactFlowRef = useRecoilValue(workflowReactFlowRefState);
|
||||||
|
|
||||||
const { useListenClickOutside } = useClickOutsideListener(
|
const { useListenClickOutside } = useClickOutsideListener(
|
||||||
RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID,
|
RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID,
|
||||||
);
|
);
|
||||||
|
|
||||||
useListenClickOutside({
|
useListenClickOutside({
|
||||||
refs: [rightDrawerRef],
|
refs: [
|
||||||
|
rightDrawerRef,
|
||||||
|
...(workflowReactFlowRef ? [workflowReactFlowRef] : []),
|
||||||
|
],
|
||||||
callback: useRecoilCallback(
|
callback: useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
(event) => {
|
(event) => {
|
||||||
@ -128,7 +125,6 @@ export const RightDrawer = () => {
|
|||||||
|
|
||||||
if (isRightDrawerOpen && !isRightDrawerMinimized) {
|
if (isRightDrawerOpen && !isRightDrawerMinimized) {
|
||||||
set(rightDrawerCloseEventState, event);
|
set(rightDrawerCloseEventState, event);
|
||||||
emitRightDrawerCloseEvent();
|
|
||||||
|
|
||||||
closeRightDrawer();
|
closeRightDrawer();
|
||||||
}
|
}
|
||||||
@ -141,10 +137,12 @@ export const RightDrawer = () => {
|
|||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
() => {
|
() => {
|
||||||
closeRightDrawer();
|
if (isRightDrawerOpen && !isRightDrawerMinimized) {
|
||||||
|
closeRightDrawer();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
RightDrawerHotkeyScope.RightDrawer,
|
RightDrawerHotkeyScope.RightDrawer,
|
||||||
[setIsRightDrawerOpen],
|
[isRightDrawerOpen, isRightDrawerMinimized],
|
||||||
);
|
);
|
||||||
|
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
@ -6,6 +6,7 @@ import { rightDrawerCloseEventState } from '@/ui/layout/right-drawer/states/righ
|
|||||||
import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState';
|
import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState';
|
||||||
import { rightDrawerPageState } from '../states/rightDrawerPageState';
|
import { rightDrawerPageState } from '../states/rightDrawerPageState';
|
||||||
import { RightDrawerPages } from '../types/RightDrawerPages';
|
import { RightDrawerPages } from '../types/RightDrawerPages';
|
||||||
|
import { emitRightDrawerCloseEvent } from '@/ui/layout/right-drawer/utils/emitRightDrawerCloseEvent';
|
||||||
|
|
||||||
export const useRightDrawer = () => {
|
export const useRightDrawer = () => {
|
||||||
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
|
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
|
||||||
@ -28,6 +29,7 @@ export const useRightDrawer = () => {
|
|||||||
() => {
|
() => {
|
||||||
set(isRightDrawerOpenState, false);
|
set(isRightDrawerOpenState, false);
|
||||||
set(isRightDrawerMinimizedState, false);
|
set(isRightDrawerMinimizedState, false);
|
||||||
|
emitRightDrawerCloseEvent();
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
@ -28,6 +28,8 @@ import '@xyflow/react/dist/style.css';
|
|||||||
import React, { useEffect, useMemo, useRef } from 'react';
|
import React, { useEffect, useMemo, useRef } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { GRAY_SCALE, isDefined, THEME_COMMON } from 'twenty-ui';
|
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`
|
const StyledResetReactflowStyles = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -86,6 +88,9 @@ export const WorkflowDiagramCanvasBase = ({
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const reactflow = useReactFlow();
|
const reactflow = useReactFlow();
|
||||||
|
const setWorkflowReactFlowRefState = useSetRecoilState(
|
||||||
|
workflowReactFlowRefState,
|
||||||
|
);
|
||||||
|
|
||||||
const { nodes, edges } = useMemo(
|
const { nodes, edges } = useMemo(
|
||||||
() => getOrganizedDiagram(diagram),
|
() => getOrganizedDiagram(diagram),
|
||||||
@ -144,6 +149,12 @@ export const WorkflowDiagramCanvasBase = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useListenRightDrawerClose(() => {
|
||||||
|
reactflow.setNodes((nodes) =>
|
||||||
|
nodes.map((node) => ({ ...node, selected: false })),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -176,6 +187,11 @@ export const WorkflowDiagramCanvasBase = ({
|
|||||||
return (
|
return (
|
||||||
<StyledResetReactflowStyles ref={containerRef}>
|
<StyledResetReactflowStyles ref={containerRef}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
|
ref={(node) => {
|
||||||
|
if (isDefined(node)) {
|
||||||
|
setWorkflowReactFlowRefState({ current: node });
|
||||||
|
}
|
||||||
|
}}
|
||||||
onInit={() => {
|
onInit={() => {
|
||||||
if (!isDefined(containerRef.current)) {
|
if (!isDefined(containerRef.current)) {
|
||||||
throw new Error('Expect the container ref to be defined');
|
throw new Error('Expect the container ref to be defined');
|
||||||
@ -192,11 +208,16 @@ export const WorkflowDiagramCanvasBase = ({
|
|||||||
minZoom={defaultFitViewOptions.minZoom}
|
minZoom={defaultFitViewOptions.minZoom}
|
||||||
maxZoom={defaultFitViewOptions.maxZoom}
|
maxZoom={defaultFitViewOptions.maxZoom}
|
||||||
nodeTypes={nodeTypes}
|
nodeTypes={nodeTypes}
|
||||||
nodes={nodes.map((node) => ({ ...node, draggable: false }))}
|
nodes={nodes}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
onNodesChange={handleNodesChange}
|
onNodesChange={handleNodesChange}
|
||||||
onEdgesChange={handleEdgesChange}
|
onEdgesChange={handleEdgesChange}
|
||||||
proOptions={{ hideAttribution: true }}
|
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} />
|
<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 { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions';
|
||||||
import { Select, SelectOption } from '@/ui/input/components/Select';
|
import { Select, SelectOption } from '@/ui/input/components/Select';
|
||||||
import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditGenericFormBase';
|
import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditGenericFormBase';
|
||||||
@ -8,8 +10,6 @@ import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefa
|
|||||||
import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/utils/mergeDefaultFunctionInputAndFunctionInput';
|
import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/utils/mergeDefaultFunctionInputAndFunctionInput';
|
||||||
import { setNestedValue } from '@/workflow/utils/setNestedValue';
|
import { setNestedValue } from '@/workflow/utils/setNestedValue';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
|
||||||
import { ReactNode } from 'react';
|
|
||||||
import { HorizontalSeparator, IconCode, isDefined } from 'twenty-ui';
|
import { HorizontalSeparator, IconCode, isDefined } from 'twenty-ui';
|
||||||
import { useDebouncedCallback } from 'use-debounce';
|
import { useDebouncedCallback } from 'use-debounce';
|
||||||
|
|
||||||
@ -165,12 +165,12 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
if (inputValue !== null && typeof inputValue === 'object') {
|
if (inputValue !== null && typeof inputValue === 'object') {
|
||||||
if (isRoot) {
|
if (isRoot) {
|
||||||
return (
|
return (
|
||||||
<>
|
<Fragment key={pathKey}>
|
||||||
{displaySeparator(functionInput) && (
|
{displaySeparator(functionInput) && (
|
||||||
<HorizontalSeparator noMargin />
|
<HorizontalSeparator noMargin />
|
||||||
)}
|
)}
|
||||||
{renderFields(inputValue, currentPath, false)}
|
{renderFields(inputValue, currentPath, false)}
|
||||||
</>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
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,
|
type: MarkerType.ArrowClosed,
|
||||||
},
|
},
|
||||||
deletable: false,
|
deletable: false,
|
||||||
|
selectable: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return nodeId;
|
return nodeId;
|
||||||
|
Loading…
Reference in New Issue
Block a user