Visualize workflow run step input (#10677)
- Compute the context the selected step had access to during its execution and display it with the `<JsonNestedNode />` component - Ensure several steps with the same name can be displayed in order - Prevent access to the input tab in a few cases - Hide the input tab when the trigger node is selected as this node takes no input - Hide the input tab when the selected node has not been executed yet or is currently executed - Fallback to the Node tab when the Input tab can't be accessed ## Successful workflow execution https://github.com/user-attachments/assets/4a2bb5f5-450c-46ed-b2d7-a14d3b1e5c1f ## Failed workflow execution https://github.com/user-attachments/assets/3be2784e-e76c-48ab-aef5-17f63410898e Closes https://github.com/twentyhq/core-team-issues/issues/433
This commit is contained in:
committed by
GitHub
parent
9d78dc322d
commit
cb5f4820d7
@ -2,16 +2,21 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||
import { useTabListStates } from '@/ui/layout/tab/hooks/internal/useTabListStates';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { workflowSelectedNodeState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeState';
|
||||
import {
|
||||
WorkflowDiagramNode,
|
||||
WorkflowDiagramStepNodeData,
|
||||
} from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWorkflowNodeIconKey';
|
||||
import { WORKFLOW_RUN_STEP_SIDE_PANEL_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/constants/WorkflowRunStepSidePanelTabListComponentId';
|
||||
import { WorkflowRunTabId } from '@/workflow/workflow-steps/types/WorkflowRunTabId';
|
||||
import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId';
|
||||
import { OnSelectionChangeParams, useOnSelectionChange } from '@xyflow/react';
|
||||
import { useCallback } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { useIcons } from 'twenty-ui';
|
||||
|
||||
@ -22,6 +27,26 @@ export const WorkflowRunDiagramCanvasEffect = () => {
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const { activeTabIdState: workflowRunRightDrawerListActiveTabIdState } =
|
||||
useTabListStates({
|
||||
tabListScopeId: WORKFLOW_RUN_STEP_SIDE_PANEL_TAB_LIST_COMPONENT_ID,
|
||||
});
|
||||
|
||||
const goBackToFirstWorkflowRunRightDrawerTabIfNeeded = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
const activeWorkflowRunRightDrawerTab = getSnapshotValue(
|
||||
snapshot,
|
||||
workflowRunRightDrawerListActiveTabIdState,
|
||||
) as WorkflowRunTabId | null;
|
||||
|
||||
if (activeWorkflowRunRightDrawerTab === 'input') {
|
||||
set(workflowRunRightDrawerListActiveTabIdState, 'node');
|
||||
}
|
||||
},
|
||||
[workflowRunRightDrawerListActiveTabIdState],
|
||||
);
|
||||
|
||||
const handleSelectionChange = useCallback(
|
||||
({ nodes }: OnSelectionChangeParams) => {
|
||||
const selectedNode = nodes[0] as WorkflowDiagramNode;
|
||||
@ -38,6 +63,14 @@ export const WorkflowRunDiagramCanvasEffect = () => {
|
||||
|
||||
const selectedNodeData = selectedNode.data as WorkflowDiagramStepNodeData;
|
||||
|
||||
if (
|
||||
selectedNode.id === TRIGGER_STEP_ID ||
|
||||
selectedNodeData.runStatus === 'not-executed' ||
|
||||
selectedNodeData.runStatus === 'running'
|
||||
) {
|
||||
goBackToFirstWorkflowRunRightDrawerTabIfNeeded();
|
||||
}
|
||||
|
||||
openRightDrawer(RightDrawerPages.WorkflowRunStepView, {
|
||||
title: selectedNodeData.name,
|
||||
Icon: getIcon(getWorkflowNodeIconKey(selectedNodeData)),
|
||||
@ -47,9 +80,10 @@ export const WorkflowRunDiagramCanvasEffect = () => {
|
||||
setWorkflowSelectedNode,
|
||||
setHotkeyScope,
|
||||
openRightDrawer,
|
||||
getIcon,
|
||||
closeRightDrawer,
|
||||
closeCommandMenu,
|
||||
getIcon,
|
||||
goBackToFirstWorkflowRunRightDrawerTabIfNeeded,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
|
||||
import { flowState } from '@/workflow/states/flowState';
|
||||
import { WorkflowRun } from '@/workflow/types/Workflow';
|
||||
import { workflowRunIdState } from '@/workflow/states/workflowRunIdState';
|
||||
import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState';
|
||||
import { generateWorkflowRunDiagram } from '@/workflow/workflow-diagram/utils/generateWorkflowRunDiagram';
|
||||
import { useEffect } from 'react';
|
||||
@ -7,16 +8,24 @@ import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
export const WorkflowRunVisualizerEffect = ({
|
||||
workflowRun,
|
||||
workflowRunId,
|
||||
}: {
|
||||
workflowRun: WorkflowRun;
|
||||
workflowRunId: string;
|
||||
}) => {
|
||||
const workflowRun = useWorkflowRun({ workflowRunId });
|
||||
|
||||
const setWorkflowRunId = useSetRecoilState(workflowRunIdState);
|
||||
const setFlow = useSetRecoilState(flowState);
|
||||
const setWorkflowDiagram = useSetRecoilState(workflowDiagramState);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(workflowRun.output)) {
|
||||
setWorkflowRunId(workflowRunId);
|
||||
}, [setWorkflowRunId, workflowRunId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(workflowRun?.output)) {
|
||||
setFlow(undefined);
|
||||
setWorkflowDiagram(undefined);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -25,14 +34,6 @@ export const WorkflowRunVisualizerEffect = ({
|
||||
trigger: workflowRun.output.flow.trigger,
|
||||
steps: workflowRun.output.flow.steps,
|
||||
});
|
||||
}, [setFlow, workflowRun.output]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(workflowRun.output)) {
|
||||
setWorkflowDiagram(undefined);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const nextWorkflowDiagram = generateWorkflowRunDiagram({
|
||||
trigger: workflowRun.output.flow.trigger,
|
||||
@ -41,7 +42,7 @@ export const WorkflowRunVisualizerEffect = ({
|
||||
});
|
||||
|
||||
setWorkflowDiagram(nextWorkflowDiagram);
|
||||
}, [setWorkflowDiagram, workflowRun.output]);
|
||||
}, [setFlow, setWorkflowDiagram, workflowRun?.output]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user