@@ -1012,7 +1012,6 @@ export enum FeatureFlagKey {
|
||||
IS_RELATION_CONNECT_ENABLED = 'IS_RELATION_CONNECT_ENABLED',
|
||||
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
|
||||
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
|
||||
IS_WORKFLOW_BRANCH_ENABLED = 'IS_WORKFLOW_BRANCH_ENABLED',
|
||||
IS_WORKFLOW_ITERATOR_ENABLED = 'IS_WORKFLOW_ITERATOR_ENABLED',
|
||||
IS_WORKSPACE_MIGRATION_V2_ENABLED = 'IS_WORKSPACE_MIGRATION_V2_ENABLED'
|
||||
}
|
||||
|
||||
@@ -976,7 +976,6 @@ export enum FeatureFlagKey {
|
||||
IS_RELATION_CONNECT_ENABLED = 'IS_RELATION_CONNECT_ENABLED',
|
||||
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
|
||||
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
|
||||
IS_WORKFLOW_BRANCH_ENABLED = 'IS_WORKFLOW_BRANCH_ENABLED',
|
||||
IS_WORKFLOW_ITERATOR_ENABLED = 'IS_WORKFLOW_ITERATOR_ENABLED',
|
||||
IS_WORKSPACE_MIGRATION_V2_ENABLED = 'IS_WORKSPACE_MIGRATION_V2_ENABLED'
|
||||
}
|
||||
|
||||
-7
@@ -12,12 +12,10 @@ import { DATABASE_TRIGGER_TYPES } from '@/workflow/workflow-trigger/constants/Da
|
||||
import { OTHER_TRIGGER_TYPES } from '@/workflow/workflow-trigger/constants/OtherTriggerTypes';
|
||||
import { useUpdateWorkflowVersionTrigger } from '@/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger';
|
||||
import { getTriggerDefaultDefinition } from '@/workflow/workflow-trigger/utils/getTriggerDefaultDefinition';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { MenuItemCommand } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const CommandMenuWorkflowSelectTriggerTypeContent = ({
|
||||
workflow,
|
||||
@@ -35,10 +33,6 @@ export const CommandMenuWorkflowSelectTriggerTypeContent = ({
|
||||
);
|
||||
const { openWorkflowEditStepInCommandMenu } = useWorkflowCommandMenu();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const handleTriggerTypeClick = ({
|
||||
type,
|
||||
defaultLabel,
|
||||
@@ -54,7 +48,6 @@ export const CommandMenuWorkflowSelectTriggerTypeContent = ({
|
||||
defaultLabel,
|
||||
type,
|
||||
activeNonSystemObjectMetadataItems,
|
||||
steps: !isWorkflowBranchEnabled ? workflow.currentVersion.steps : [],
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
-8
@@ -14,11 +14,9 @@ import { workflowRunDiagramAutomaticallyOpenedStepsComponentState } from '@/work
|
||||
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
|
||||
import { generateWorkflowRunDiagram } from '@/workflow/workflow-diagram/utils/generateWorkflowRunDiagram';
|
||||
import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWorkflowNodeIconKey';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => {
|
||||
const apolloCoreClient = useApolloCoreClient();
|
||||
@@ -27,10 +25,6 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => {
|
||||
|
||||
const { objectPermissionsByObjectMetadataId } = useObjectPermissions();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const runWorkflowRunOpeningInCommandMenuSideEffects = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({
|
||||
@@ -62,7 +56,6 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => {
|
||||
steps: workflowRunRecord.state.flow.steps,
|
||||
stepInfos: workflowRunRecord.state.stepInfos,
|
||||
trigger: workflowRunRecord.state.flow.trigger,
|
||||
isWorkflowBranchEnabled,
|
||||
});
|
||||
|
||||
if (!isDefined(stepToOpenByDefault)) {
|
||||
@@ -132,7 +125,6 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => {
|
||||
[
|
||||
apolloCoreClient.cache,
|
||||
objectPermissionsByObjectMetadataId,
|
||||
isWorkflowBranchEnabled,
|
||||
openWorkflowRunViewStepInCommandMenu,
|
||||
getIcon,
|
||||
],
|
||||
|
||||
+13
-32
@@ -5,7 +5,6 @@ import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { WorkflowDiagramCustomMarkers } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramCustomMarkers';
|
||||
import { WorkflowDiagramRightClickCommandMenu } from '@/workflow/workflow-diagram/components/WorkflowDiagramRightClickCommandMenu';
|
||||
import { useRightDrawerState } from '@/workflow/workflow-diagram/hooks/useRightDrawerState';
|
||||
import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramComponentState';
|
||||
@@ -19,9 +18,10 @@ import {
|
||||
type WorkflowDiagramNode,
|
||||
type WorkflowDiagramNodeType,
|
||||
} from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { getOrganizedDiagram } from '@/workflow/workflow-diagram/utils/getOrganizedDiagram';
|
||||
import { WorkflowDiagramConnection } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramConnection';
|
||||
import { WorkflowDiagramCustomMarkers } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramCustomMarkers';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/workflow-edges/hooks/useEdgeState';
|
||||
import { workflowInsertStepIdsComponentState } from '@/workflow/workflow-steps/states/workflowInsertStepIdsComponentState';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
@@ -53,9 +53,6 @@ import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Tag, type TagColor } from 'twenty-ui/components';
|
||||
import { THEME_COMMON } from 'twenty-ui/theme';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/workflow-edges/hooks/useEdgeState';
|
||||
import { WorkflowDiagramConnection } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramConnection';
|
||||
|
||||
const StyledResetReactflowStyles = styled.div`
|
||||
height: 100%;
|
||||
@@ -181,23 +178,15 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
|
||||
const { setEdgeHovered, clearEdgeHover } = useEdgeState();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const [workflowDiagramFlowInitialized, setWorkflowDiagramFlowInitialized] =
|
||||
useState<boolean>(false);
|
||||
|
||||
const { nodes, edges } = useMemo(() => {
|
||||
if (isDefined(workflowDiagram)) {
|
||||
if (isWorkflowBranchEnabled) {
|
||||
return workflowDiagram;
|
||||
}
|
||||
|
||||
return getOrganizedDiagram(workflowDiagram);
|
||||
return workflowDiagram;
|
||||
}
|
||||
return { nodes: [], edges: [] };
|
||||
}, [workflowDiagram, isWorkflowBranchEnabled]);
|
||||
}, [workflowDiagram]);
|
||||
|
||||
const { rightDrawerState } = useRightDrawerState();
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
@@ -407,10 +396,6 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
WorkflowDiagramNode,
|
||||
WorkflowDiagramEdge
|
||||
> = async ({ nodes, edges }) => {
|
||||
if (!isWorkflowBranchEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nodes.length === 0 && edges.length > 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -421,7 +406,7 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
const onDelete: OnDelete<WorkflowDiagramNode, WorkflowDiagramEdge> = async ({
|
||||
edges,
|
||||
}) => {
|
||||
if (!isWorkflowBranchEnabled || !isDefined(onDeleteEdge)) {
|
||||
if (!isDefined(onDeleteEdge)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -479,23 +464,19 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
onEdgeMouseLeave={onEdgeMouseLeave}
|
||||
onNodesChange={handleNodesChanges}
|
||||
onEdgesChange={handleEdgesChange}
|
||||
onConnect={isWorkflowBranchEnabled ? onConnect : undefined}
|
||||
onNodeDragStop={isWorkflowBranchEnabled ? onNodeDragStop : undefined}
|
||||
onConnect={onConnect}
|
||||
onNodeDragStop={onNodeDragStop}
|
||||
onBeforeDelete={onBeforeDelete}
|
||||
onDelete={onDelete}
|
||||
selectNodesOnDrag={false}
|
||||
proOptions={{ hideAttribution: true }}
|
||||
multiSelectionKeyCode={null}
|
||||
nodesFocusable={false}
|
||||
nodesDraggable={isWorkflowBranchEnabled ? nodesDraggable : false}
|
||||
edgesFocusable={
|
||||
isWorkflowBranchEnabled ? isDefined(onDeleteEdge) : false
|
||||
}
|
||||
nodesDraggable={nodesDraggable}
|
||||
edgesFocusable={isDefined(onDeleteEdge)}
|
||||
panOnDrag={workflowDiagramPanOnDrag}
|
||||
onPaneContextMenu={
|
||||
isWorkflowBranchEnabled ? onPaneContextMenu : undefined
|
||||
}
|
||||
nodesConnectable={isWorkflowBranchEnabled ? nodesConnectable : false}
|
||||
onPaneContextMenu={onPaneContextMenu}
|
||||
nodesConnectable={nodesConnectable}
|
||||
paneClickDistance={10} // Fix small unwanted user dragging does not select node
|
||||
preventScrolling={false}
|
||||
connectionLineComponent={WorkflowDiagramConnection}
|
||||
@@ -506,7 +487,7 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
{children}
|
||||
</ReactFlow>
|
||||
|
||||
{isDefined(handlePaneContextMenu) && isWorkflowBranchEnabled && (
|
||||
{isDefined(handlePaneContextMenu) && (
|
||||
<WorkflowDiagramRightClickCommandMenu />
|
||||
)}
|
||||
|
||||
|
||||
+1
-11
@@ -1,26 +1,16 @@
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/workflow-edges/hooks/useEdgeState';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import {
|
||||
type OnSelectionChangeParams,
|
||||
useOnSelectionChange,
|
||||
} from '@xyflow/react';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
const { setEdgeSelected, clearEdgeSelected } = useEdgeState();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const handleSelectedEdges = useCallback(
|
||||
({ edges }: OnSelectionChangeParams) => {
|
||||
if (!isWorkflowBranchEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedEdge = edges?.[0];
|
||||
|
||||
if (!isDefined(selectedEdge)) {
|
||||
@@ -34,7 +24,7 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
target: selectedEdge.target,
|
||||
});
|
||||
},
|
||||
[isWorkflowBranchEnabled, setEdgeSelected, clearEdgeSelected],
|
||||
[setEdgeSelected, clearEdgeSelected],
|
||||
);
|
||||
|
||||
useOnSelectionChange({
|
||||
|
||||
+1
-12
@@ -12,11 +12,9 @@ import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/state
|
||||
|
||||
import { getWorkflowVersionDiagram } from '@/workflow/workflow-diagram/utils/getWorkflowVersionDiagram';
|
||||
import { mergeWorkflowDiagrams } from '@/workflow/workflow-diagram/utils/mergeWorkflowDiagrams';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const WorkflowDiagramEffect = () => {
|
||||
const workflowVisualizerWorkflowId = useRecoilComponentValue(
|
||||
@@ -40,10 +38,6 @@ export const WorkflowDiagramEffect = () => {
|
||||
workflowLastCreatedStepIdComponentState,
|
||||
);
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const computeAndMergeNewWorkflowDiagram = useRecoilCallback(
|
||||
({ snapshot, set }) => {
|
||||
return (currentVersion: WorkflowVersion) => {
|
||||
@@ -54,7 +48,6 @@ export const WorkflowDiagramEffect = () => {
|
||||
|
||||
const nextWorkflowDiagram = getWorkflowVersionDiagram({
|
||||
workflowVersion: currentVersion,
|
||||
isWorkflowBranchEnabled,
|
||||
isEditable: true,
|
||||
});
|
||||
|
||||
@@ -88,11 +81,7 @@ export const WorkflowDiagramEffect = () => {
|
||||
set(workflowDiagramState, mergedWorkflowDiagram);
|
||||
};
|
||||
},
|
||||
[
|
||||
workflowDiagramState,
|
||||
isWorkflowBranchEnabled,
|
||||
workflowLastCreatedStepIdState,
|
||||
],
|
||||
[workflowDiagramState, workflowLastCreatedStepIdState],
|
||||
);
|
||||
|
||||
const currentVersion = workflowWithCurrentVersion?.currentVersion;
|
||||
|
||||
-8
@@ -18,12 +18,10 @@ import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/
|
||||
import { generateWorkflowRunDiagram } from '@/workflow/workflow-diagram/utils/generateWorkflowRunDiagram';
|
||||
import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWorkflowNodeIconKey';
|
||||
import { selectWorkflowDiagramNode } from '@/workflow/workflow-diagram/utils/selectWorkflowDiagramNode';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const WorkflowRunVisualizerEffect = ({
|
||||
workflowRunId,
|
||||
@@ -71,10 +69,6 @@ export const WorkflowRunVisualizerEffect = ({
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setWorkflowRunId(workflowRunId);
|
||||
}, [setWorkflowRunId, workflowRunId]);
|
||||
@@ -133,7 +127,6 @@ export const WorkflowRunVisualizerEffect = ({
|
||||
trigger: workflowRunState.flow.trigger,
|
||||
steps: workflowRunState.flow.steps,
|
||||
stepInfos: workflowRunState.stepInfos,
|
||||
isWorkflowBranchEnabled,
|
||||
});
|
||||
|
||||
if (workflowDiagramStatus !== 'done') {
|
||||
@@ -204,7 +197,6 @@ export const WorkflowRunVisualizerEffect = ({
|
||||
[
|
||||
flowState,
|
||||
getIcon,
|
||||
isWorkflowBranchEnabled,
|
||||
openWorkflowRunViewStepInCommandMenu,
|
||||
workflowDiagramState,
|
||||
workflowDiagramStatusState,
|
||||
|
||||
+1
-8
@@ -6,10 +6,8 @@ import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/wo
|
||||
import { workflowVisualizerWorkflowVersionIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowVersionIdComponentState';
|
||||
import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramComponentState';
|
||||
import { getWorkflowVersionDiagram } from '@/workflow/workflow-diagram/utils/getWorkflowVersionDiagram';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useEffect } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const WorkflowVersionVisualizerEffect = ({
|
||||
workflowVersionId,
|
||||
@@ -31,10 +29,6 @@ export const WorkflowVersionVisualizerEffect = ({
|
||||
|
||||
const { populateStepsOutputSchema } = useStepsOutputSchema();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(workflowVersion)) {
|
||||
setFlow(undefined);
|
||||
@@ -66,12 +60,11 @@ export const WorkflowVersionVisualizerEffect = ({
|
||||
|
||||
const nextWorkflowDiagram = getWorkflowVersionDiagram({
|
||||
workflowVersion,
|
||||
isWorkflowBranchEnabled,
|
||||
isEditable: false,
|
||||
});
|
||||
|
||||
setWorkflowDiagram(nextWorkflowDiagram);
|
||||
}, [isWorkflowBranchEnabled, setWorkflowDiagram, workflowVersion]);
|
||||
}, [setWorkflowDiagram, workflowVersion]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(workflowVersion)) {
|
||||
|
||||
-10
@@ -104,8 +104,6 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
trigger,
|
||||
steps,
|
||||
stepInfos,
|
||||
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
@@ -337,8 +335,6 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
trigger,
|
||||
steps,
|
||||
stepInfos,
|
||||
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
@@ -570,8 +566,6 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
trigger,
|
||||
steps,
|
||||
stepInfos,
|
||||
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
@@ -822,8 +816,6 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
trigger,
|
||||
steps,
|
||||
stepInfos,
|
||||
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
@@ -1055,8 +1047,6 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
trigger,
|
||||
steps,
|
||||
stepInfos,
|
||||
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
|
||||
-87
@@ -46,7 +46,6 @@ describe('transformFilterNodesAsEdges', () => {
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: 'filter--editable',
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
expect(result.nodes).toEqual(diagram.nodes);
|
||||
@@ -113,7 +112,6 @@ describe('transformFilterNodesAsEdges', () => {
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: 'filter--editable',
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
// Should only have nodes A and C
|
||||
@@ -259,7 +257,6 @@ describe('transformFilterNodesAsEdges', () => {
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: 'filter--editable',
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
// Should only have nodes A, C, and D
|
||||
@@ -352,7 +349,6 @@ describe('transformFilterNodesAsEdges', () => {
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: 'filter--editable',
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
// Should only have node A (filter node B is removed)
|
||||
@@ -435,7 +431,6 @@ describe('transformFilterNodesAsEdges', () => {
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: 'filter--editable',
|
||||
isWorkflowBranchEnabled: true,
|
||||
});
|
||||
|
||||
// Should have trigger and C nodes
|
||||
@@ -485,86 +480,4 @@ describe('transformFilterNodesAsEdges', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should set selectable and deletable to false when isWorkflowBranchEnabled is false', () => {
|
||||
const diagram: WorkflowDiagram = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'A',
|
||||
data: {
|
||||
nodeType: 'action',
|
||||
actionType: 'CODE',
|
||||
name: 'Step A',
|
||||
hasNextStepIds: true,
|
||||
position: { x: 0, y: 0 },
|
||||
stepId: 'A',
|
||||
},
|
||||
position: { x: 0, y: 0 },
|
||||
},
|
||||
{
|
||||
id: 'B',
|
||||
data: {
|
||||
nodeType: 'action',
|
||||
actionType: 'FILTER',
|
||||
name: 'Filter B',
|
||||
hasNextStepIds: true,
|
||||
position: { x: 0, y: 150 },
|
||||
stepId: 'B',
|
||||
},
|
||||
position: { x: 0, y: 150 },
|
||||
},
|
||||
{
|
||||
id: 'C',
|
||||
data: {
|
||||
nodeType: 'action',
|
||||
actionType: 'SEND_EMAIL',
|
||||
name: 'Step C',
|
||||
hasNextStepIds: false,
|
||||
position: { x: 0, y: 300 },
|
||||
stepId: 'C',
|
||||
},
|
||||
position: { x: 0, y: 300 },
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: 'A-B',
|
||||
source: 'A',
|
||||
target: 'B',
|
||||
data: { edgeType: 'default' },
|
||||
},
|
||||
{
|
||||
id: 'B-C',
|
||||
source: 'B',
|
||||
target: 'C',
|
||||
data: { edgeType: 'default' },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = transformFilterNodesAsEdges({
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: 'filter--editable',
|
||||
isWorkflowBranchEnabled: false,
|
||||
});
|
||||
|
||||
// Should have one edge with filter data
|
||||
expect(result.edges).toHaveLength(1);
|
||||
expect(result.edges[0]).toEqual({
|
||||
id: 'A-C-filter-B',
|
||||
type: 'filter--editable',
|
||||
source: 'A',
|
||||
target: 'C',
|
||||
selectable: false,
|
||||
deletable: false,
|
||||
data: {
|
||||
edgeType: 'filter',
|
||||
stepId: 'B',
|
||||
name: 'Filter B',
|
||||
runStatus: undefined,
|
||||
filterSettings: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+1
-17
@@ -4,7 +4,6 @@ import {
|
||||
} from '@/workflow/types/Workflow';
|
||||
import { FIRST_NODE_POSITION } from '@/workflow/workflow-diagram/constants/FirstNodePosition';
|
||||
import { VERTICAL_DISTANCE_BETWEEN_TWO_NODES } from '@/workflow/workflow-diagram/constants/VerticalDistanceBetweenTwoNodes';
|
||||
import { WORKFLOW_VISUALIZER_EDGE_DEFAULT_CONFIGURATION } from '@/workflow/workflow-diagram/workflow-edges/constants/WorkflowVisualizerEdgeDefaultConfiguration';
|
||||
import {
|
||||
type WorkflowDiagram,
|
||||
type WorkflowDiagramEdge,
|
||||
@@ -13,9 +12,9 @@ import {
|
||||
type WorkflowDiagramStepNodeData,
|
||||
} from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { getWorkflowDiagramTriggerNode } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramTriggerNode';
|
||||
import { WORKFLOW_VISUALIZER_EDGE_DEFAULT_CONFIGURATION } from '@/workflow/workflow-diagram/workflow-edges/constants/WorkflowVisualizerEdgeDefaultConfiguration';
|
||||
|
||||
import { WORKFLOW_DIAGRAM_EMPTY_TRIGGER_NODE_DEFINITION } from '@/workflow/workflow-diagram/constants/WorkflowDiagramEmptyTriggerNodeDefinition';
|
||||
import { getRootStepIds } from '@/workflow/workflow-trigger/utils/getRootStepIds';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -24,12 +23,10 @@ export const generateWorkflowDiagram = ({
|
||||
trigger,
|
||||
steps,
|
||||
defaultEdgeType,
|
||||
isWorkflowBranchEnabled = false,
|
||||
}: {
|
||||
trigger: WorkflowTrigger | undefined;
|
||||
steps: Array<WorkflowStep>;
|
||||
defaultEdgeType: WorkflowDiagramEdgeType;
|
||||
isWorkflowBranchEnabled?: boolean;
|
||||
}): WorkflowDiagram => {
|
||||
const nodes: Array<WorkflowDiagramNode> = [];
|
||||
const edges: Array<WorkflowDiagramEdge> = [];
|
||||
@@ -38,19 +35,6 @@ export const generateWorkflowDiagram = ({
|
||||
nodes.push(getWorkflowDiagramTriggerNode({ trigger }));
|
||||
} else {
|
||||
nodes.push(WORKFLOW_DIAGRAM_EMPTY_TRIGGER_NODE_DEFINITION);
|
||||
|
||||
const triggerNextStepIds =
|
||||
isDefined(steps) && !isWorkflowBranchEnabled ? getRootStepIds(steps) : [];
|
||||
|
||||
triggerNextStepIds.forEach((stepId) => {
|
||||
edges.push({
|
||||
...WORKFLOW_VISUALIZER_EDGE_DEFAULT_CONFIGURATION,
|
||||
type: 'blank',
|
||||
id: v4(),
|
||||
source: 'trigger',
|
||||
target: stepId,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let levelYPos = FIRST_NODE_POSITION.y;
|
||||
|
||||
-3
@@ -19,12 +19,10 @@ export const generateWorkflowRunDiagram = ({
|
||||
trigger,
|
||||
steps,
|
||||
stepInfos,
|
||||
isWorkflowBranchEnabled,
|
||||
}: {
|
||||
trigger: WorkflowTrigger;
|
||||
steps: Array<WorkflowStep>;
|
||||
stepInfos: WorkflowRunStepInfos | undefined;
|
||||
isWorkflowBranchEnabled: boolean;
|
||||
}): {
|
||||
diagram: WorkflowRunDiagram;
|
||||
stepToOpenByDefault:
|
||||
@@ -107,7 +105,6 @@ export const generateWorkflowRunDiagram = ({
|
||||
nodes: workflowRunDiagramNodes,
|
||||
edges: workflowRunDiagramEdges,
|
||||
defaultFilterEdgeType: 'filter--run',
|
||||
isWorkflowBranchEnabled,
|
||||
}),
|
||||
stepToOpenByDefault,
|
||||
};
|
||||
|
||||
-4
@@ -22,11 +22,9 @@ const getEdgeTypeToCreateByDefault = ({
|
||||
|
||||
export const getWorkflowVersionDiagram = ({
|
||||
workflowVersion,
|
||||
isWorkflowBranchEnabled,
|
||||
isEditable,
|
||||
}: {
|
||||
workflowVersion: WorkflowVersion | undefined;
|
||||
isWorkflowBranchEnabled?: boolean;
|
||||
isEditable: boolean;
|
||||
}): WorkflowDiagram => {
|
||||
if (!isDefined(workflowVersion)) {
|
||||
@@ -39,13 +37,11 @@ export const getWorkflowVersionDiagram = ({
|
||||
defaultEdgeType: getEdgeTypeToCreateByDefault({
|
||||
isEditable,
|
||||
}),
|
||||
isWorkflowBranchEnabled,
|
||||
});
|
||||
|
||||
return transformFilterNodesAsEdges({
|
||||
nodes: diagram.nodes,
|
||||
edges: diagram.edges,
|
||||
defaultFilterEdgeType: isEditable ? 'filter--editable' : 'filter--readonly',
|
||||
isWorkflowBranchEnabled: isWorkflowBranchEnabled === true,
|
||||
});
|
||||
};
|
||||
|
||||
+2
-4
@@ -12,12 +12,10 @@ export const transformFilterNodesAsEdges = <
|
||||
nodes,
|
||||
edges,
|
||||
defaultFilterEdgeType,
|
||||
isWorkflowBranchEnabled,
|
||||
}: {
|
||||
nodes: T[];
|
||||
edges: U[];
|
||||
defaultFilterEdgeType: WorkflowDiagramEdgeType;
|
||||
isWorkflowBranchEnabled: boolean;
|
||||
}): { nodes: T[]; edges: U[] } => {
|
||||
const filterNodes = nodes.filter(
|
||||
(node) =>
|
||||
@@ -55,8 +53,8 @@ export const transformFilterNodesAsEdges = <
|
||||
type: defaultFilterEdgeType,
|
||||
id: `${incomingEdge.source}-${outgoingEdge.target}-filter-${filterNode.id}`,
|
||||
target: outgoingEdge.target,
|
||||
selectable: isWorkflowBranchEnabled === true,
|
||||
deletable: isWorkflowBranchEnabled === true,
|
||||
selectable: true,
|
||||
deletable: true,
|
||||
data: {
|
||||
...incomingEdge.data,
|
||||
edgeType: 'filter',
|
||||
|
||||
+8
-18
@@ -3,17 +3,17 @@ import { commandMenuNavigationStackState } from '@/command-menu/states/commandMe
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
|
||||
import { useOpenWorkflowEditFilterInCommandMenu } from '@/workflow/workflow-diagram/hooks/useOpenWorkflowEditFilterInCommandMenu';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { WorkflowDiagramBaseEdge } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramBaseEdge';
|
||||
import { WorkflowDiagramEdgeButtonGroup } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramEdgeButtonGroup';
|
||||
import { WorkflowDiagramEdgeV2Container } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramEdgeV2Container';
|
||||
import { WorkflowDiagramEdgeV2VisibilityContainer } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramEdgeV2VisibilityContainer';
|
||||
import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/workflow-edges/constants/WorkflowDiagramEdgeOptionsClickOutsideId';
|
||||
import { useOpenWorkflowEditFilterInCommandMenu } from '@/workflow/workflow-diagram/hooks/useOpenWorkflowEditFilterInCommandMenu';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/workflow-edges/hooks/useEdgeState';
|
||||
import { useCreateStep } from '@/workflow/workflow-steps/hooks/useCreateStep';
|
||||
import { useDeleteEdge } from '@/workflow/workflow-steps/hooks/useDeleteEdge';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import {
|
||||
EdgeLabelRenderer,
|
||||
type EdgeProps,
|
||||
@@ -23,8 +23,6 @@ import { type MouseEvent, useContext } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconFilter, IconPlus, IconTrash } from 'twenty-ui/display';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/workflow-edges/hooks/useEdgeState';
|
||||
|
||||
type WorkflowDiagramDefaultEdgeEditableProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
@@ -38,10 +36,6 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
markerStart,
|
||||
markerEnd,
|
||||
}: WorkflowDiagramDefaultEdgeEditableProps) => {
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const { isEdgeHovered } = useEdgeState();
|
||||
@@ -142,14 +136,10 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
Icon: IconPlus,
|
||||
onClick: handleNodeButtonClick,
|
||||
},
|
||||
...(isWorkflowBranchEnabled
|
||||
? [
|
||||
{
|
||||
Icon: IconTrash,
|
||||
onClick: handleDeleteBranch,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
Icon: IconTrash,
|
||||
onClick: handleDeleteBranch,
|
||||
},
|
||||
]}
|
||||
selected={nodeCreationStarted}
|
||||
/>
|
||||
|
||||
+5
-12
@@ -28,7 +28,6 @@ import { useDeleteEdge } from '@/workflow/workflow-steps/hooks/useDeleteEdge';
|
||||
import { useDeleteStep } from '@/workflow/workflow-steps/hooks/useDeleteStep';
|
||||
import { WorkflowStepFilterCounter } from '@/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterCounter';
|
||||
import { useFilterCounter } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useFilterCounter';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { css, useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
@@ -50,7 +49,6 @@ import {
|
||||
} from 'twenty-ui/display';
|
||||
import { IconButtonGroup } from 'twenty-ui/input';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
type WorkflowDiagramFilterEdgeEditableProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
@@ -98,9 +96,6 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
const [edgePath, labelX, labelY] = getBezierPath({
|
||||
sourceX,
|
||||
@@ -274,13 +269,11 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
LeftIcon={IconPlus}
|
||||
onClick={handleAddNodeButtonClick}
|
||||
/>
|
||||
{isWorkflowBranchEnabled && (
|
||||
<MenuItem
|
||||
text={t`Delete branch`}
|
||||
LeftIcon={IconTrash}
|
||||
onClick={handleDeleteBranchClick}
|
||||
/>
|
||||
)}
|
||||
<MenuItem
|
||||
text={t`Delete branch`}
|
||||
LeftIcon={IconTrash}
|
||||
onClick={handleDeleteBranchClick}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
|
||||
+1
-7
@@ -2,11 +2,9 @@ import type { WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { NODE_HANDLE_HEIGHT_PX } from '@/workflow/workflow-diagram/constants/NodeHandleHeightPx';
|
||||
import { NODE_HANDLE_WIDTH_PX } from '@/workflow/workflow-diagram/constants/NodeHandleWidthPx';
|
||||
import { getWorkflowDiagramColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramColors';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Handle, Position, type HandleProps } from '@xyflow/react';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
type WorkflowDiagramHandleSourceProps = {
|
||||
selected: boolean;
|
||||
@@ -89,15 +87,11 @@ export const WorkflowDiagramHandleSource = ({
|
||||
readOnly = false,
|
||||
runStatus,
|
||||
}: WorkflowDiagramHandleSourceProps) => {
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledHandle
|
||||
type="source"
|
||||
position={Position.Bottom}
|
||||
disableHoverEffect={!isWorkflowBranchEnabled || readOnly}
|
||||
disableHoverEffect={readOnly}
|
||||
selected={selected}
|
||||
hovered={hovered}
|
||||
runStatus={runStatus}
|
||||
|
||||
-7
@@ -28,7 +28,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
eventName: `${generatedMockObjectMetadataItems[0].nameSingular}.created`,
|
||||
outputSchema: {},
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -50,7 +49,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
eventName: `${generatedMockObjectMetadataItems[0].nameSingular}.updated`,
|
||||
outputSchema: {},
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -72,7 +70,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
eventName: `${generatedMockObjectMetadataItems[0].nameSingular}.deleted`,
|
||||
outputSchema: {},
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -94,7 +91,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
eventName: `${generatedMockObjectMetadataItems[0].nameSingular}.created`,
|
||||
outputSchema: {},
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -118,7 +114,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
icon: COMMAND_MENU_DEFAULT_ICON,
|
||||
isPinned: false,
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -141,7 +136,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
schedule: { day: 1, hour: 0, minute: 0 },
|
||||
outputSchema: {},
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -164,7 +158,6 @@ describe('getTriggerDefaultDefinition', () => {
|
||||
httpMethod: 'GET',
|
||||
authentication: null,
|
||||
},
|
||||
nextStepIds: [],
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
|
||||
+1
-8
@@ -1,25 +1,21 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import {
|
||||
type WorkflowAction,
|
||||
type WorkflowTrigger,
|
||||
type WorkflowTriggerType,
|
||||
} from '@/workflow/types/Workflow';
|
||||
import { DATABASE_TRIGGER_TYPES } from '@/workflow/workflow-trigger/constants/DatabaseTriggerTypes';
|
||||
import { getManualTriggerDefaultSettings } from '@/workflow/workflow-trigger/utils/getManualTriggerDefaultSettings';
|
||||
import { getRootStepIds } from '@/workflow/workflow-trigger/utils/getRootStepIds';
|
||||
import { assertUnreachable, isDefined } from 'twenty-shared/utils';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
// TODO: This needs to be migrated to the server
|
||||
export const getTriggerDefaultDefinition = ({
|
||||
defaultLabel,
|
||||
type,
|
||||
activeNonSystemObjectMetadataItems,
|
||||
steps,
|
||||
}: {
|
||||
defaultLabel: string;
|
||||
type: WorkflowTriggerType;
|
||||
activeNonSystemObjectMetadataItems: ObjectMetadataItem[];
|
||||
steps?: WorkflowAction[] | null;
|
||||
}): WorkflowTrigger => {
|
||||
if (activeNonSystemObjectMetadataItems.length === 0) {
|
||||
throw new Error(
|
||||
@@ -27,12 +23,9 @@ export const getTriggerDefaultDefinition = ({
|
||||
);
|
||||
}
|
||||
|
||||
const nextStepIds = isDefined(steps) ? getRootStepIds(steps) : [];
|
||||
|
||||
const baseTriggerDefinition = {
|
||||
name: defaultLabel,
|
||||
position: { x: 0, y: 0 },
|
||||
nextStepIds,
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
|
||||
-8
@@ -22,14 +22,6 @@ export const PUBLIC_FEATURE_FLAGS: PublicFeatureFlag[] = [
|
||||
'https://twenty.com/images/lab/is-imap-smtp-caldav-enabled.png',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
metadata: {
|
||||
label: 'Workflow Branches',
|
||||
description: 'Create multiple branches on your workflows',
|
||||
imagePath: 'https://twenty.com/images/lab/is-workflow-branch-enabled.png',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: FeatureFlagKey.IS_MESSAGE_FOLDER_CONTROL_ENABLED,
|
||||
metadata: {
|
||||
|
||||
-1
@@ -7,7 +7,6 @@ export enum FeatureFlagKey {
|
||||
IS_AI_ENABLED = 'IS_AI_ENABLED',
|
||||
IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED',
|
||||
IS_MORPH_RELATION_ENABLED = 'IS_MORPH_RELATION_ENABLED',
|
||||
IS_WORKFLOW_BRANCH_ENABLED = 'IS_WORKFLOW_BRANCH_ENABLED',
|
||||
IS_RELATION_CONNECT_ENABLED = 'IS_RELATION_CONNECT_ENABLED',
|
||||
IS_CORE_VIEW_SYNCING_ENABLED = 'IS_CORE_VIEW_SYNCING_ENABLED',
|
||||
IS_CORE_VIEW_ENABLED = 'IS_CORE_VIEW_ENABLED',
|
||||
|
||||
-2
@@ -130,7 +130,6 @@ describe('WorkspaceEntityManager', () => {
|
||||
IS_AI_ENABLED: false,
|
||||
IS_IMAP_SMTP_CALDAV_ENABLED: false,
|
||||
IS_MORPH_RELATION_ENABLED: false,
|
||||
IS_WORKFLOW_BRANCH_ENABLED: false,
|
||||
IS_RELATION_CONNECT_ENABLED: false,
|
||||
IS_CORE_VIEW_SYNCING_ENABLED: false,
|
||||
IS_CORE_VIEW_ENABLED: false,
|
||||
@@ -158,7 +157,6 @@ describe('WorkspaceEntityManager', () => {
|
||||
IS_AI_ENABLED: false,
|
||||
IS_IMAP_SMTP_CALDAV_ENABLED: false,
|
||||
IS_MORPH_RELATION_ENABLED: false,
|
||||
IS_WORKFLOW_BRANCH_ENABLED: false,
|
||||
IS_RELATION_CONNECT_ENABLED: false,
|
||||
IS_CORE_VIEW_SYNCING_ENABLED: false,
|
||||
IS_CORE_VIEW_ENABLED: false,
|
||||
|
||||
-5
@@ -40,11 +40,6 @@ export const seedFeatureFlags = async (
|
||||
workspaceId: workspaceId,
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
key: FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
workspaceId: workspaceId,
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
key: FeatureFlagKey.IS_IMAP_SMTP_CALDAV_ENABLED,
|
||||
workspaceId: workspaceId,
|
||||
|
||||
+1
-13
@@ -2,7 +2,6 @@ import { Scope } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator';
|
||||
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
||||
@@ -18,7 +17,6 @@ import {
|
||||
WorkflowRunException,
|
||||
WorkflowRunExceptionCode,
|
||||
} from 'src/modules/workflow/workflow-runner/exceptions/workflow-run.exception';
|
||||
import { getRootSteps } from 'src/modules/workflow/workflow-runner/utils/get-root-steps.utils';
|
||||
import { WorkflowRunQueueWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run-queue/workspace-services/workflow-run-queue.workspace-service';
|
||||
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service';
|
||||
import { WorkflowTriggerType } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
|
||||
@@ -113,17 +111,7 @@ export class RunWorkflowJob {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const rootSteps = getRootSteps(workflowVersion.steps);
|
||||
|
||||
const isWorkflowBranchEnabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const stepIds = isWorkflowBranchEnabled
|
||||
? (workflowVersion.trigger.nextStepIds ?? [])
|
||||
: (rootSteps.map((step) => step.id) ?? []);
|
||||
const stepIds = workflowVersion.trigger.nextStepIds ?? [];
|
||||
|
||||
await this.workflowExecutorWorkspaceService.executeFromSteps({
|
||||
stepIds,
|
||||
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||
import { getRootSteps } from 'src/modules/workflow/workflow-runner/utils/get-root-steps.utils';
|
||||
|
||||
describe('getRootSteps', () => {
|
||||
it('should return the root steps', () => {
|
||||
const steps = [
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step2'],
|
||||
},
|
||||
{ id: 'step2', nextStepIds: undefined },
|
||||
] as WorkflowAction[];
|
||||
|
||||
const expectedRootSteps = [
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step2'],
|
||||
},
|
||||
] as WorkflowAction[];
|
||||
|
||||
expect(getRootSteps(steps)).toEqual(expectedRootSteps);
|
||||
});
|
||||
|
||||
it('should not consider step order', () => {
|
||||
const steps = [
|
||||
{ id: 'step2', nextStepIds: undefined },
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step2'],
|
||||
},
|
||||
] as WorkflowAction[];
|
||||
|
||||
const expectedRootSteps = [
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step2'],
|
||||
},
|
||||
] as WorkflowAction[];
|
||||
|
||||
expect(getRootSteps(steps)).toEqual(expectedRootSteps);
|
||||
});
|
||||
|
||||
it('should handle multiple root steps', () => {
|
||||
const steps = [
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step3'],
|
||||
},
|
||||
{
|
||||
id: 'step2',
|
||||
nextStepIds: ['step3'],
|
||||
},
|
||||
{ id: 'step3', nextStepIds: ['step4'] },
|
||||
{ id: 'step4', nextStepIds: undefined },
|
||||
] as WorkflowAction[];
|
||||
|
||||
const expectedRootSteps = [
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step3'],
|
||||
},
|
||||
{
|
||||
id: 'step2',
|
||||
nextStepIds: ['step3'],
|
||||
},
|
||||
] as WorkflowAction[];
|
||||
|
||||
expect(getRootSteps(steps)).toEqual(expectedRootSteps);
|
||||
});
|
||||
|
||||
it('should throw if buggy steps provided', () => {
|
||||
const steps = [
|
||||
{
|
||||
id: 'step1',
|
||||
nextStepIds: ['step2'],
|
||||
},
|
||||
{
|
||||
id: 'step2',
|
||||
nextStepIds: ['step1'],
|
||||
},
|
||||
] as WorkflowAction[];
|
||||
|
||||
expect(() => getRootSteps(steps)).toThrow('No root step found');
|
||||
});
|
||||
});
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||
import {
|
||||
WorkflowRunException,
|
||||
WorkflowRunExceptionCode,
|
||||
} from 'src/modules/workflow/workflow-runner/exceptions/workflow-run.exception';
|
||||
|
||||
export const getRootSteps = (steps: WorkflowAction[]): WorkflowAction[] => {
|
||||
const childIds = new Set<string>();
|
||||
|
||||
for (const step of steps) {
|
||||
step.nextStepIds?.forEach((id) => childIds.add(id));
|
||||
}
|
||||
|
||||
const rootSteps = steps.filter((step) => !childIds.has(step.id));
|
||||
|
||||
if (rootSteps.length === 0) {
|
||||
throw new WorkflowRunException(
|
||||
'No root step found',
|
||||
WorkflowRunExceptionCode.WORKFLOW_ROOT_STEP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return rootSteps;
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 244 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 365 KiB |
Reference in New Issue
Block a user