965 flow control arrow menu 1/3 add insert step button (#12519)
Add insert step button to workflow edges https://github.com/user-attachments/assets/7144f722-f1c7-450f-a8eb-c902071986a1 Also fixes `iconButtonGroup` UI component ## Before https://github.com/user-attachments/assets/7b5f0245-d0e8-48af-9aa5-a29388a1caea ## After https://github.com/user-attachments/assets/1820874f-aa99-41ae-8254-c76c275ee3ae
This commit is contained in:
+4
-1
@@ -68,7 +68,10 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
}
|
||||
|
||||
if (isCreateStepNode(selectedNode)) {
|
||||
startNodeCreation(selectedNode.data.parentNodeId);
|
||||
startNodeCreation({
|
||||
parentStepId: selectedNode.data.parentNodeId,
|
||||
nextStepId: undefined,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+23
-8
@@ -1,18 +1,23 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { BaseEdge, EdgeProps, getStraightPath } from '@xyflow/react';
|
||||
import { CREATE_STEP_NODE_WIDTH } from '@/workflow/workflow-diagram/constants/CreateStepNodeWidth';
|
||||
import { WorkflowDiagramEdgeOptions } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeOptions';
|
||||
import { WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
|
||||
type WorkflowDiagramDefaultEdgeProps = EdgeProps;
|
||||
type WorkflowDiagramDefaultEdgeProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
export const WorkflowDiagramDefaultEdge = ({
|
||||
source,
|
||||
target,
|
||||
sourceY,
|
||||
targetY,
|
||||
markerStart,
|
||||
markerEnd,
|
||||
data,
|
||||
}: WorkflowDiagramDefaultEdgeProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const [edgePath] = getStraightPath({
|
||||
const [edgePath, labelX, labelY] = getStraightPath({
|
||||
sourceX: CREATE_STEP_NODE_WIDTH,
|
||||
sourceY,
|
||||
targetX: CREATE_STEP_NODE_WIDTH,
|
||||
@@ -20,11 +25,21 @@ export const WorkflowDiagramDefaultEdge = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<BaseEdge
|
||||
markerStart={markerStart}
|
||||
markerEnd={markerEnd}
|
||||
path={edgePath}
|
||||
style={{ stroke: theme.border.color.strong }}
|
||||
/>
|
||||
<>
|
||||
<BaseEdge
|
||||
markerStart={markerStart}
|
||||
markerEnd={markerEnd}
|
||||
path={edgePath}
|
||||
style={{ stroke: theme.border.color.strong }}
|
||||
/>
|
||||
{data?.shouldDisplayEdgeOptions && (
|
||||
<WorkflowDiagramEdgeOptions
|
||||
labelX={labelX}
|
||||
labelY={labelY}
|
||||
parentStepId={source}
|
||||
nextStepId={target}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
import { EdgeLabelRenderer } from '@xyflow/react';
|
||||
import { STEP_ICON_WIDTH } from '@/workflow/workflow-diagram/constants/CreateStepNodeWidth';
|
||||
import styled from '@emotion/styled';
|
||||
import { IconButtonGroup } from 'twenty-ui/input';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
const EDGE_OPTION_BUTTON_LEFT_MARGIN = 8;
|
||||
|
||||
const StyledIconButtonGroup = styled(IconButtonGroup)`
|
||||
pointer-events: all;
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div<{
|
||||
labelX?: number;
|
||||
labelY?: number;
|
||||
}>`
|
||||
position: absolute;
|
||||
transform: ${({ labelX, labelY }) =>
|
||||
`translate(${labelX || 0}px, ${isDefined(labelY) ? labelY - STEP_ICON_WIDTH / 2 : 0}px) translateX(${EDGE_OPTION_BUTTON_LEFT_MARGIN}px)`};
|
||||
`;
|
||||
|
||||
type WorkflowDiagramEdgeOptionsProps = {
|
||||
labelX?: number;
|
||||
labelY?: number;
|
||||
parentStepId: string;
|
||||
nextStepId: string;
|
||||
};
|
||||
|
||||
export const WorkflowDiagramEdgeOptions = ({
|
||||
labelX,
|
||||
labelY,
|
||||
parentStepId,
|
||||
nextStepId,
|
||||
}: WorkflowDiagramEdgeOptionsProps) => {
|
||||
const { startNodeCreation } = useStartNodeCreation();
|
||||
|
||||
return (
|
||||
<EdgeLabelRenderer>
|
||||
<StyledContainer labelX={labelX} labelY={labelY}>
|
||||
<StyledIconButtonGroup
|
||||
className="nodrag nopan"
|
||||
iconButtons={[
|
||||
{
|
||||
Icon: IconPlus,
|
||||
onClick: () => {
|
||||
startNodeCreation({ parentStepId, nextStepId });
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</StyledContainer>
|
||||
</EdgeLabelRenderer>
|
||||
);
|
||||
};
|
||||
+5
-1
@@ -16,6 +16,7 @@ import { mergeWorkflowDiagrams } from '@/workflow/workflow-diagram/utils/mergeWo
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { addEdgeOptions } from '@/workflow/workflow-diagram/utils/addEdgeOptions';
|
||||
|
||||
export const WorkflowDiagramEffect = ({
|
||||
workflowWithCurrentVersion,
|
||||
@@ -44,10 +45,11 @@ export const WorkflowDiagramEffect = ({
|
||||
);
|
||||
|
||||
const nextWorkflowDiagram = addCreateStepNodes(
|
||||
getWorkflowVersionDiagram(currentVersion),
|
||||
addEdgeOptions(getWorkflowVersionDiagram(currentVersion)),
|
||||
);
|
||||
|
||||
let mergedWorkflowDiagram = nextWorkflowDiagram;
|
||||
|
||||
if (isDefined(previousWorkflowDiagram)) {
|
||||
mergedWorkflowDiagram = mergeWorkflowDiagrams(
|
||||
previousWorkflowDiagram,
|
||||
@@ -59,6 +61,7 @@ export const WorkflowDiagramEffect = ({
|
||||
snapshot,
|
||||
workflowLastCreatedStepIdState,
|
||||
);
|
||||
|
||||
if (isDefined(lastCreatedStepId)) {
|
||||
mergedWorkflowDiagram.nodes = mergedWorkflowDiagram.nodes.map(
|
||||
(node) => {
|
||||
@@ -79,6 +82,7 @@ export const WorkflowDiagramEffect = ({
|
||||
);
|
||||
|
||||
const currentVersion = workflowWithCurrentVersion?.currentVersion;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(currentVersion)) {
|
||||
setFlow(undefined);
|
||||
|
||||
Reference in New Issue
Block a user