Add workflow run visualizer (#10146)
- Remove the tabs from the workflowRun show page; now, we only show the visualizer with the nodes highlighted based on the run's output - Create the `generateWorkflowRunDiagram` function to go other each step and assign a `runStatus` to it based on the workflow run's output Remaining to do: - Show the output of each step in the right drawer when selecting one - The labels (e.g. "1 item") are not set on the edges; we might implement that later https://github.com/user-attachments/assets/bcf22f4c-db8c-4b02-9a1a-62d688b4c28e Closes https://github.com/twentyhq/core-team-issues/issues/338 Closes https://github.com/twentyhq/core-team-issues/issues/336
This commit is contained in:
committed by
GitHub
parent
1863ef7d10
commit
81b2d5bc89
+4
-4
@@ -1,4 +1,4 @@
|
||||
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||
import { WorkflowVersionStatus } from '@/workflow/types/Workflow';
|
||||
import { WorkflowDiagramCanvasBase } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase';
|
||||
import { WorkflowDiagramCanvasEditableEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditableEffect';
|
||||
import { WorkflowDiagramCreateStepNode } from '@/workflow/workflow-diagram/components/WorkflowDiagramCreateStepNode';
|
||||
@@ -8,14 +8,14 @@ import { WorkflowDiagramStepNodeEditable } from '@/workflow/workflow-diagram/com
|
||||
import { ReactFlowProvider } from '@xyflow/react';
|
||||
|
||||
export const WorkflowDiagramCanvasEditable = ({
|
||||
workflowWithCurrentVersion,
|
||||
versionStatus,
|
||||
}: {
|
||||
workflowWithCurrentVersion: WorkflowWithCurrentVersion;
|
||||
versionStatus: WorkflowVersionStatus;
|
||||
}) => {
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<WorkflowDiagramCanvasBase
|
||||
status={workflowWithCurrentVersion.currentVersion.status}
|
||||
status={versionStatus}
|
||||
nodeTypes={{
|
||||
default: WorkflowDiagramStepNodeEditable,
|
||||
'create-step': WorkflowDiagramCreateStepNode,
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
import { WorkflowVersion } from '@/workflow/types/Workflow';
|
||||
import { WorkflowVersionStatus } from '@/workflow/types/Workflow';
|
||||
import { WorkflowDiagramCanvasBase } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase';
|
||||
import { WorkflowDiagramCanvasReadonlyEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasReadonlyEffect';
|
||||
import { WorkflowDiagramDefaultEdge } from '@/workflow/workflow-diagram/components/WorkflowDiagramDefaultEdge';
|
||||
@@ -8,14 +8,14 @@ import { WorkflowDiagramSuccessEdge } from '@/workflow/workflow-diagram/componen
|
||||
import { ReactFlowProvider } from '@xyflow/react';
|
||||
|
||||
export const WorkflowDiagramCanvasReadonly = ({
|
||||
workflowVersion,
|
||||
versionStatus,
|
||||
}: {
|
||||
workflowVersion: WorkflowVersion;
|
||||
versionStatus: WorkflowVersionStatus;
|
||||
}) => {
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<WorkflowDiagramCanvasBase
|
||||
status={workflowVersion.status}
|
||||
status={versionStatus}
|
||||
nodeTypes={{
|
||||
default: WorkflowDiagramStepNodeReadonly,
|
||||
'empty-trigger': WorkflowDiagramEmptyTrigger,
|
||||
|
||||
+22
-2
@@ -1,6 +1,26 @@
|
||||
import { WorkflowDiagramStepNodeBase } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeBase';
|
||||
import { WorkflowDiagramStepNodeIcon } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeIcon';
|
||||
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import {
|
||||
WorkflowDiagramRunStatus,
|
||||
WorkflowDiagramStepNodeData,
|
||||
} from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
|
||||
const getNodeVariantFromRunStatus = (
|
||||
runStatus: WorkflowDiagramRunStatus | undefined,
|
||||
) => {
|
||||
switch (runStatus) {
|
||||
case 'success':
|
||||
return 'success';
|
||||
case 'failure':
|
||||
return 'failure';
|
||||
case 'running':
|
||||
return 'default';
|
||||
case 'not-executed':
|
||||
return 'not-executed';
|
||||
default:
|
||||
return 'default';
|
||||
}
|
||||
};
|
||||
|
||||
export const WorkflowDiagramStepNodeReadonly = ({
|
||||
data,
|
||||
@@ -10,7 +30,7 @@ export const WorkflowDiagramStepNodeReadonly = ({
|
||||
return (
|
||||
<WorkflowDiagramStepNodeBase
|
||||
name={data.name}
|
||||
variant="default"
|
||||
variant={getNodeVariantFromRunStatus(data.runStatus)}
|
||||
nodeType={data.nodeType}
|
||||
Icon={<WorkflowDiagramStepNodeIcon data={data} />}
|
||||
isLeafNode={data.isLeafNode}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion';
|
||||
import { workflowVersionIdState } from '@/workflow/states/workflowVersionIdState';
|
||||
import { WorkflowRun } from '@/workflow/types/Workflow';
|
||||
import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState';
|
||||
import { generateWorkflowRunDiagram } from '@/workflow/workflow-diagram/utils/generateWorkflowRunDiagram';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
export const WorkflowRunVisualizerEffect = ({
|
||||
workflowVersionId,
|
||||
workflowRun,
|
||||
}: {
|
||||
workflowVersionId: string;
|
||||
workflowRun: WorkflowRun;
|
||||
}) => {
|
||||
const workflowVersion = useWorkflowVersion(workflowVersionId);
|
||||
|
||||
const setWorkflowVersionId = useSetRecoilState(workflowVersionIdState);
|
||||
const setWorkflowDiagram = useSetRecoilState(workflowDiagramState);
|
||||
|
||||
useEffect(() => {
|
||||
setWorkflowVersionId(workflowVersionId);
|
||||
}, [setWorkflowVersionId, workflowVersionId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!(
|
||||
isDefined(workflowVersion) &&
|
||||
isDefined(workflowVersion.trigger) &&
|
||||
isDefined(workflowVersion.steps)
|
||||
)
|
||||
) {
|
||||
setWorkflowDiagram(undefined);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const nextWorkflowDiagram = generateWorkflowRunDiagram({
|
||||
trigger: workflowVersion.trigger,
|
||||
steps: workflowVersion.steps,
|
||||
output: workflowRun.output,
|
||||
});
|
||||
|
||||
setWorkflowDiagram(nextWorkflowDiagram);
|
||||
}, [setWorkflowDiagram, workflowRun.output, workflowVersion]);
|
||||
|
||||
return null;
|
||||
};
|
||||
+1
-1
@@ -11,6 +11,6 @@ export const WorkflowVersionVisualizer = ({
|
||||
const workflowVersion = useWorkflowVersion(workflowVersionId);
|
||||
|
||||
return isDefined(workflowVersion) ? (
|
||||
<WorkflowDiagramCanvasReadonly workflowVersion={workflowVersion} />
|
||||
<WorkflowDiagramCanvasReadonly versionStatus={workflowVersion.status} />
|
||||
) : null;
|
||||
};
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ export const WorkflowVisualizer = ({ workflowId }: { workflowId: string }) => {
|
||||
|
||||
{isDefined(workflowWithCurrentVersion) ? (
|
||||
<WorkflowDiagramCanvasEditable
|
||||
workflowWithCurrentVersion={workflowWithCurrentVersion}
|
||||
versionStatus={workflowWithCurrentVersion.currentVersion.status}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user