diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramBaseStepNode.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramBaseStepNode.tsx
index 9d8c6b39b303..0318f61a6bf4 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramBaseStepNode.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramBaseStepNode.tsx
@@ -21,13 +21,12 @@ const StyledStepNodeType = styled.div`
${({ theme }) => theme.border.radius.sm} 0 0;
color: ${({ theme }) => theme.color.gray50};
- font-size: ${({ theme }) => theme.font.size.xs};
+ font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
+ margin-left: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
- position: absolute;
- top: 0;
- transform: translateY(-100%);
+ align-self: flex-start;
.selectable.selected &,
.selectable:focus &,
@@ -62,9 +61,9 @@ const StyledStepNodeInnerContainer = styled.div<{ variant?: Variant }>`
const StyledStepNodeLabel = styled.div<{ variant?: Variant }>`
align-items: center;
display: flex;
- font-size: ${({ theme }) => theme.font.size.md};
+ font-size: ${({ theme }) => theme.font.size.lg};
font-weight: ${({ theme }) => theme.font.weight.medium};
- column-gap: ${({ theme }) => theme.spacing(2)};
+ column-gap: ${({ theme }) => theme.spacing(3)};
color: ${({ variant, theme }) =>
variant === 'placeholder'
? theme.font.color.extraLight
@@ -80,9 +79,13 @@ export const StyledTargetHandle = styled(Handle)`
`;
const StyledRightFloatingElementContainer = styled.div`
+ display: flex;
+ align-items: center;
position: absolute;
+ right: ${({ theme }) => theme.spacing(-3)};
+ bottom: 0;
+ top: 0;
transform: translateX(100%);
- right: ${({ theme }) => theme.spacing(-2)};
`;
export const WorkflowDiagramBaseStepNode = ({
@@ -104,9 +107,9 @@ export const WorkflowDiagramBaseStepNode = ({
) : null}
-
- {capitalize(nodeType)}
+ {capitalize(nodeType)}
+
{Icon}
diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx
index 79273d062aa6..55aab89ae27d 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasBase.tsx
@@ -1,3 +1,6 @@
+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 { WorkflowVersionStatusTag } from '@/workflow/components/WorkflowVersionStatusTag';
import { workflowDiagramState } from '@/workflow/states/workflowDiagramState';
import { WorkflowVersionStatus } from '@/workflow/types/Workflow';
@@ -15,14 +18,16 @@ import {
Background,
EdgeChange,
FitViewOptions,
+ getNodesBounds,
NodeChange,
NodeProps,
ReactFlow,
+ useReactFlow,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
-import React, { useMemo } from 'react';
-import { useSetRecoilState } from 'recoil';
-import { GRAY_SCALE, isDefined } from 'twenty-ui';
+import React, { useEffect, useMemo, useRef } from 'react';
+import { useRecoilValue, useSetRecoilState } from 'recoil';
+import { GRAY_SCALE, isDefined, THEME_COMMON } from 'twenty-ui';
const StyledResetReactflowStyles = styled.div`
height: 100%;
@@ -35,6 +40,9 @@ const StyledResetReactflowStyles = styled.div`
.react-flow__node-output,
.react-flow__node-group {
padding: 0;
+ width: auto;
+ text-align: start;
+ white-space: nowrap;
}
--xy-node-border-radius: none;
@@ -51,10 +59,10 @@ const StyledStatusTagContainer = styled.div`
padding: ${({ theme }) => theme.spacing(2)};
`;
-const defaultFitViewOptions: FitViewOptions = {
- minZoom: 1.3,
- maxZoom: 1.3,
-};
+const defaultFitViewOptions = {
+ minZoom: 1,
+ maxZoom: 1,
+} satisfies FitViewOptions;
export const WorkflowDiagramCanvasBase = ({
diagram,
@@ -77,11 +85,29 @@ export const WorkflowDiagramCanvasBase = ({
>;
children?: React.ReactNode;
}) => {
+ const reactflow = useReactFlow();
+
const { nodes, edges } = useMemo(
() => getOrganizedDiagram(diagram),
[diagram],
);
+ const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
+ const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState);
+ const isMobile = useIsMobile();
+
+ const rightDrawerState = !isRightDrawerOpen
+ ? 'closed'
+ : isRightDrawerMinimized
+ ? 'minimized'
+ : isMobile
+ ? 'fullScreen'
+ : 'normal';
+
+ const rightDrawerWidth = Number(
+ THEME_COMMON.rightDrawerWidth.replace('px', ''),
+ );
+
const setWorkflowDiagram = useSetRecoilState(workflowDiagramState);
const handleNodesChange = (
@@ -118,27 +144,68 @@ export const WorkflowDiagramCanvasBase = ({
});
};
+ const containerRef = useRef(null);
+
+ useEffect(() => {
+ if (!isDefined(containerRef.current) || !reactflow.viewportInitialized) {
+ return;
+ }
+
+ const currentViewport = reactflow.getViewport();
+
+ const flowBounds = getNodesBounds(reactflow.getNodes());
+
+ let visibleRightDrawerWidth = 0;
+ if (rightDrawerState === 'normal') {
+ visibleRightDrawerWidth = rightDrawerWidth;
+ }
+
+ const viewportX =
+ (containerRef.current.offsetWidth + visibleRightDrawerWidth) / 2 -
+ flowBounds.width / 2;
+
+ reactflow.setViewport(
+ {
+ ...currentViewport,
+ x: viewportX - visibleRightDrawerWidth,
+ },
+ { duration: 300 },
+ );
+ }, [reactflow, rightDrawerState, rightDrawerWidth]);
+
return (
-
+
{
- fitView(defaultFitViewOptions);
+ onInit={() => {
+ if (!isDefined(containerRef.current)) {
+ throw new Error('Expect the container ref to be defined');
+ }
+
+ const flowBounds = getNodesBounds(reactflow.getNodes());
+
+ reactflow.setViewport({
+ x: containerRef.current.offsetWidth / 2 - flowBounds.width / 2,
+ y: 150,
+ zoom: defaultFitViewOptions.maxZoom,
+ });
}}
+ minZoom={defaultFitViewOptions.minZoom}
+ maxZoom={defaultFitViewOptions.maxZoom}
nodeTypes={nodeTypes}
- fitView
nodes={nodes.map((node) => ({ ...node, draggable: false }))}
edges={edges}
onNodesChange={handleNodesChange}
onEdgesChange={handleEdgesChange}
+ proOptions={{ hideAttribution: true }}
>
{children}
-
-
-
-
+
+
+
+
);
};
diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasEditable.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasEditable.tsx
index ed953f511fa3..fe866fa72697 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasEditable.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasEditable.tsx
@@ -5,6 +5,7 @@ import { WorkflowDiagramEmptyTrigger } from '@/workflow/components/WorkflowDiagr
import { WorkflowDiagramStepNodeEditable } from '@/workflow/components/WorkflowDiagramStepNodeEditable';
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import { WorkflowDiagram } from '@/workflow/types/WorkflowDiagram';
+import { ReactFlowProvider } from '@xyflow/react';
export const WorkflowDiagramCanvasEditable = ({
diagram,
@@ -14,17 +15,19 @@ export const WorkflowDiagramCanvasEditable = ({
workflowWithCurrentVersion: WorkflowWithCurrentVersion;
}) => {
return (
-
-
-
+
+
+
+
+
);
};
diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasReadonly.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasReadonly.tsx
index d6c50fa9034e..5302046f22f9 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasReadonly.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCanvasReadonly.tsx
@@ -4,6 +4,7 @@ import { WorkflowDiagramEmptyTrigger } from '@/workflow/components/WorkflowDiagr
import { WorkflowDiagramStepNodeReadonly } from '@/workflow/components/WorkflowDiagramStepNodeReadonly';
import { WorkflowVersion } from '@/workflow/types/Workflow';
import { WorkflowDiagram } from '@/workflow/types/WorkflowDiagram';
+import { ReactFlowProvider } from '@xyflow/react';
export const WorkflowDiagramCanvasReadonly = ({
diagram,
@@ -13,16 +14,18 @@ export const WorkflowDiagramCanvasReadonly = ({
workflowVersion: WorkflowVersion;
}) => {
return (
-
-
-
+
+
+
+
+
);
};
diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCreateStepNode.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCreateStepNode.tsx
index ec0614037889..98b93c689ada 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCreateStepNode.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramCreateStepNode.tsx
@@ -11,7 +11,7 @@ export const WorkflowDiagramCreateStepNode = () => {
<>
-
+
>
);
};
diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeBase.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeBase.tsx
index 9cef1fbb47bd..04c6a62be931 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeBase.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeBase.tsx
@@ -31,7 +31,7 @@ export const WorkflowDiagramStepNodeBase = ({
return (
@@ -41,7 +41,7 @@ export const WorkflowDiagramStepNodeBase = ({
return (
@@ -57,7 +57,7 @@ export const WorkflowDiagramStepNodeBase = ({
return (
@@ -66,7 +66,7 @@ export const WorkflowDiagramStepNodeBase = ({
case 'SEND_EMAIL': {
return (
-
+
);
}
diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeEditable.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeEditable.tsx
index 579e3c923491..9df7f0bbc42f 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeEditable.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowDiagramStepNodeEditable.tsx
@@ -32,6 +32,7 @@ export const WorkflowDiagramStepNodeEditable = ({
RightFloatingElement={
selected ? (
{
return deleteOneStep();
diff --git a/packages/twenty-front/src/modules/workflow/utils/addCreateStepNodes.ts b/packages/twenty-front/src/modules/workflow/utils/addCreateStepNodes.ts
index ffde2d1d88aa..1e76140993f4 100644
--- a/packages/twenty-front/src/modules/workflow/utils/addCreateStepNodes.ts
+++ b/packages/twenty-front/src/modules/workflow/utils/addCreateStepNodes.ts
@@ -36,6 +36,7 @@ export const addCreateStepNodes = ({ nodes, edges }: WorkflowDiagram) => {
markerEnd: {
type: MarkerType.ArrowClosed,
},
+ deletable: false,
});
}
diff --git a/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts b/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts
index 971e996684f3..93fdaae51b0b 100644
--- a/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts
+++ b/packages/twenty-front/src/modules/workflow/utils/generateWorkflowDiagram.ts
@@ -51,6 +51,7 @@ export const generateWorkflowDiagram = ({
markerEnd: {
type: MarkerType.ArrowClosed,
},
+ deletable: false,
});
return nodeId;