Add Delete branch buttons (#13826)
Deleting branches containing a filter isn't yet supported by the backend, but I set up the button in the frontend. https://github.com/user-attachments/assets/f27234c4-ff9c-4f5c-930c-64d824981454
This commit is contained in:
+15
-2
@@ -13,15 +13,16 @@ import { useOpenWorkflowEditFilterInCommandMenu } from '@/workflow/workflow-diag
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { useCreateStep } from '@/workflow/workflow-steps/hooks/useCreateStep';
|
||||
import { useDeleteEdge } from '@/workflow/workflow-steps/hooks/useDeleteEdge';
|
||||
import {
|
||||
EdgeLabelRenderer,
|
||||
type EdgeProps,
|
||||
getBezierPath,
|
||||
} from '@xyflow/react';
|
||||
import { useContext } from 'react';
|
||||
import { type MouseEvent, useContext } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconFilter, IconPlus } from 'twenty-ui/display';
|
||||
import { IconFilter, IconPlus, IconTrash } from 'twenty-ui/display';
|
||||
|
||||
type WorkflowDiagramDefaultEdgeEditableProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
@@ -54,6 +55,8 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
|
||||
const { createStep } = useCreateStep({ workflow });
|
||||
|
||||
const { deleteEdge } = useDeleteEdge({ workflow });
|
||||
|
||||
const { startNodeCreation, isNodeCreationStarted } = useStartNodeCreation();
|
||||
|
||||
const nodeCreationStarted = isNodeCreationStarted({
|
||||
@@ -97,6 +100,12 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteBranch = async (event: MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
|
||||
await deleteEdge({ source, target });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<WorkflowDiagramBaseEdge
|
||||
@@ -126,6 +135,10 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
Icon: IconPlus,
|
||||
onClick: handleNodeButtonClick,
|
||||
},
|
||||
{
|
||||
Icon: IconTrash,
|
||||
onClick: handleDeleteBranch,
|
||||
},
|
||||
]}
|
||||
selected={nodeCreationStarted}
|
||||
/>
|
||||
|
||||
+27
-14
@@ -26,9 +26,11 @@ import {
|
||||
type WorkflowDiagramEdgeData,
|
||||
} from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { getWorkflowDiagramNodeSelectedColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramNodeSelectedColors';
|
||||
import { useDeleteEdge } from '@/workflow/workflow-steps/hooks/useDeleteEdge';
|
||||
import { useDeleteStep } from '@/workflow/workflow-steps/hooks/useDeleteStep';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import {
|
||||
EdgeLabelRenderer,
|
||||
@@ -37,12 +39,12 @@ import {
|
||||
} from '@xyflow/react';
|
||||
import { useContext } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconDotsVertical,
|
||||
IconFilter,
|
||||
IconFilterX,
|
||||
IconPlus,
|
||||
IconTrash,
|
||||
} from 'twenty-ui/display';
|
||||
import { IconButtonGroup } from 'twenty-ui/input';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
@@ -91,6 +93,8 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
}: WorkflowDiagramFilterEdgeEditableProps) => {
|
||||
assertFilterEdgeDataOrThrow(data);
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const [edgePath, labelX, labelY] = getBezierPath({
|
||||
sourceX,
|
||||
sourceY,
|
||||
@@ -102,9 +106,11 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
workflowVisualizerWorkflowIdComponentState,
|
||||
);
|
||||
const workflow = useWorkflowWithCurrentVersion(workflowVisualizerWorkflowId);
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const { deleteStep } = useDeleteStep({ workflow });
|
||||
const { deleteEdge } = useDeleteEdge({ workflow });
|
||||
const { startNodeCreation, isNodeCreationStarted } = useStartNodeCreation();
|
||||
|
||||
const setCommandMenuNavigationStack = useSetRecoilState(
|
||||
@@ -153,6 +159,12 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleRemoveFilterButtonClick = async () => {
|
||||
closeDropdown(dropdownId);
|
||||
|
||||
await deleteStep(data.stepId);
|
||||
};
|
||||
|
||||
const handleAddNodeButtonClick = () => {
|
||||
closeDropdown(dropdownId);
|
||||
|
||||
@@ -163,6 +175,12 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteBranchClick = async () => {
|
||||
closeDropdown(dropdownId);
|
||||
|
||||
await deleteEdge({ source, target });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<WorkflowDiagramBaseEdge
|
||||
@@ -244,25 +262,20 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
}}
|
||||
/>
|
||||
<MenuItem
|
||||
text="Remove Filter"
|
||||
text={t`Remove filter`}
|
||||
LeftIcon={IconFilterX}
|
||||
onClick={() => {
|
||||
closeDropdown(dropdownId);
|
||||
|
||||
if (!isDefined(data.stepId)) {
|
||||
throw new Error(
|
||||
'Step ID must be configured for the edge when rendering a filter',
|
||||
);
|
||||
}
|
||||
|
||||
return deleteStep(data.stepId);
|
||||
}}
|
||||
onClick={handleRemoveFilterButtonClick}
|
||||
/>
|
||||
<MenuItem
|
||||
text="Add Node"
|
||||
text={t`Add Node`}
|
||||
LeftIcon={IconPlus}
|
||||
onClick={handleAddNodeButtonClick}
|
||||
/>
|
||||
<MenuItem
|
||||
text={t`Delete branch`}
|
||||
LeftIcon={IconTrash}
|
||||
onClick={handleDeleteBranchClick}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
|
||||
import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||
import { assertWorkflowWithCurrentVersionIsDefined } from '@/workflow/utils/assertWorkflowWithCurrentVersionIsDefined';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
|
||||
import { useDeleteWorkflowVersionEdge } from '@/workflow/workflow-steps/hooks/useDeleteWorkflowVersionEdge';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
|
||||
|
||||
export const useDeleteEdge = ({
|
||||
workflow,
|
||||
}: {
|
||||
workflow: WorkflowWithCurrentVersion;
|
||||
workflow: WorkflowWithCurrentVersion | undefined;
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@@ -17,6 +18,8 @@ export const useDeleteEdge = ({
|
||||
const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
|
||||
|
||||
const deleteEdge = async ({ source, target }: WorkflowDiagramEdge) => {
|
||||
assertWorkflowWithCurrentVersionIsDefined(workflow);
|
||||
|
||||
if (isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user