Display tag for workflow version status (#6972)

- Move where we fetch workflow data. We now fetch them in the `Workflow`
component directly. That's useful to access it in the
`WorkflowShowPageEffect` and `WorkflowDiagramCanvas` components.

![CleanShot 2024-09-10 at 16 27
53@2x](https://github.com/user-attachments/assets/7d30f407-31ab-472c-a096-c525042c0f35)
This commit is contained in:
Baptiste Devessier
2024-09-13 11:25:07 +02:00
committed by GitHub
parent 31c02202bd
commit e9f8e6e718
6 changed files with 121 additions and 24 deletions

View File

@ -1,14 +1,17 @@
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { WorkflowDiagramCanvas } from '@/workflow/components/WorkflowDiagramCanvas';
import { WorkflowEffect } from '@/workflow/components/WorkflowEffect';
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowDiagramState } from '@/workflow/states/workflowDiagramState';
import styled from '@emotion/styled';
import '@xyflow/react/dist/style.css';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-ui';
const StyledFlowContainer = styled.div`
height: 100%;
width: 100%;
position: relative;
/* Below we reset the default styling of Reactflow */
.react-flow__node-input,
@ -32,16 +35,23 @@ export const Workflow = ({
}) => {
const workflowId = targetableObject.id;
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(workflowId);
const workflowDiagram = useRecoilValue(workflowDiagramState);
return (
<>
<WorkflowEffect workflowId={workflowId} />
<WorkflowEffect
workflowId={workflowId}
workflowWithCurrentVersion={workflowWithCurrentVersion}
/>
<StyledFlowContainer>
{workflowDiagram === undefined ? null : (
<WorkflowDiagramCanvas diagram={workflowDiagram} />
)}
{isDefined(workflowDiagram) && isDefined(workflowWithCurrentVersion) ? (
<WorkflowDiagramCanvas
diagram={workflowDiagram}
workflowWithCurrentVersion={workflowWithCurrentVersion}
/>
) : null}
</StyledFlowContainer>
</>
);

View File

@ -2,13 +2,16 @@ import { WorkflowDiagramCanvasEffect } from '@/workflow/components/WorkflowDiagr
import { WorkflowDiagramCreateStepNode } from '@/workflow/components/WorkflowDiagramCreateStepNode';
import { WorkflowDiagramEmptyTrigger } from '@/workflow/components/WorkflowDiagramEmptyTrigger';
import { WorkflowDiagramStepNode } from '@/workflow/components/WorkflowDiagramStepNode';
import { WorkflowVersionStatusTag } from '@/workflow/components/WorkflowVersionStatusTag';
import { workflowDiagramState } from '@/workflow/states/workflowDiagramState';
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import {
WorkflowDiagram,
WorkflowDiagramEdge,
WorkflowDiagramNode,
} from '@/workflow/types/WorkflowDiagram';
import { getOrganizedDiagram } from '@/workflow/utils/getOrganizedDiagram';
import styled from '@emotion/styled';
import {
applyEdgeChanges,
applyNodeChanges,
@ -22,10 +25,19 @@ import { useMemo } from 'react';
import { useSetRecoilState } from 'recoil';
import { GRAY_SCALE, isDefined } from 'twenty-ui';
const StyledStatusTagContainer = styled.div`
left: 0;
top: 0;
position: absolute;
padding: ${({ theme }) => theme.spacing(2)};
`;
export const WorkflowDiagramCanvas = ({
diagram,
workflowWithCurrentVersion,
}: {
diagram: WorkflowDiagram;
workflowWithCurrentVersion: WorkflowWithCurrentVersion;
}) => {
const { nodes, edges } = useMemo(
() => getOrganizedDiagram(diagram),
@ -69,21 +81,29 @@ export const WorkflowDiagramCanvas = ({
};
return (
<ReactFlow
nodeTypes={{
default: WorkflowDiagramStepNode,
'create-step': WorkflowDiagramCreateStepNode,
'empty-trigger': WorkflowDiagramEmptyTrigger,
}}
fitView
nodes={nodes.map((node) => ({ ...node, draggable: false }))}
edges={edges}
onNodesChange={handleNodesChange}
onEdgesChange={handleEdgesChange}
>
<WorkflowDiagramCanvasEffect />
<>
<ReactFlow
nodeTypes={{
default: WorkflowDiagramStepNode,
'create-step': WorkflowDiagramCreateStepNode,
'empty-trigger': WorkflowDiagramEmptyTrigger,
}}
fitView
nodes={nodes.map((node) => ({ ...node, draggable: false }))}
edges={edges}
onNodesChange={handleNodesChange}
onEdgesChange={handleEdgesChange}
>
<WorkflowDiagramCanvasEffect />
<Background color={GRAY_SCALE.gray25} size={2} />
</ReactFlow>
<Background color={GRAY_SCALE.gray25} size={2} />
</ReactFlow>
<StyledStatusTagContainer>
<WorkflowVersionStatusTag
versionStatus={workflowWithCurrentVersion.currentVersion.status}
/>
</StyledStatusTagContainer>
</>
);
};

View File

@ -1,6 +1,6 @@
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowDiagramState } from '@/workflow/states/workflowDiagramState';
import { workflowIdState } from '@/workflow/states/workflowIdState';
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import { addCreateStepNodes } from '@/workflow/utils/addCreateStepNodes';
import { getWorkflowVersionDiagram } from '@/workflow/utils/getWorkflowVersionDiagram';
import { useEffect } from 'react';
@ -9,11 +9,13 @@ import { isDefined } from 'twenty-ui';
type WorkflowEffectProps = {
workflowId: string;
workflowWithCurrentVersion: WorkflowWithCurrentVersion | undefined;
};
export const WorkflowEffect = ({ workflowId }: WorkflowEffectProps) => {
const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(workflowId);
export const WorkflowEffect = ({
workflowId,
workflowWithCurrentVersion,
}: WorkflowEffectProps) => {
const setWorkflowId = useSetRecoilState(workflowIdState);
const setWorkflowDiagram = useSetRecoilState(workflowDiagramState);

View File

@ -0,0 +1,22 @@
import { WorkflowVersionStatus } from '@/workflow/types/Workflow';
import { Tag } from 'twenty-ui';
export const WorkflowVersionStatusTag = ({
versionStatus,
}: {
versionStatus: WorkflowVersionStatus;
}) => {
if (versionStatus === 'ACTIVE') {
return <Tag color="green" text="Active" />;
}
if (versionStatus === 'DRAFT') {
return <Tag color="yellow" text="Draft" />;
}
if (versionStatus === 'ARCHIVED') {
return <Tag color="gray" text="Archived" />;
}
return <Tag color="gray" text="Deactivated" />;
};

View File

@ -0,0 +1,43 @@
import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator, CatalogStory, ComponentDecorator } from 'twenty-ui';
import { WorkflowVersionStatus } from '@/workflow/types/Workflow';
import { WorkflowVersionStatusTag } from '../WorkflowVersionStatusTag';
const meta: Meta<typeof WorkflowVersionStatusTag> = {
title: 'Modules/Workflow/WorkflowVersionStatusTag',
component: WorkflowVersionStatusTag,
};
export default meta;
type Story = StoryObj<typeof WorkflowVersionStatusTag>;
export const Default: Story = {
args: {
versionStatus: 'DRAFT',
},
decorators: [ComponentDecorator],
};
export const Catalog: CatalogStory<Story, typeof WorkflowVersionStatusTag> = {
argTypes: {
versionStatus: { table: { disable: true } },
},
parameters: {
catalog: {
dimensions: [
{
name: 'version status',
values: [
'DRAFT',
'ACTIVE',
'DEACTIVATED',
'ARCHIVED',
] satisfies WorkflowVersionStatus[],
props: (versionStatus: WorkflowVersionStatus) => ({ versionStatus }),
},
],
},
},
decorators: [CatalogDecorator],
};

View File

@ -78,5 +78,5 @@ export type Workflow = {
};
export type WorkflowWithCurrentVersion = Workflow & {
currentVersion: WorkflowVersion | undefined;
currentVersion: WorkflowVersion;
};