Skip to content

Commit

Permalink
Add the new workflow not executed node type (#10030)
Browse files Browse the repository at this point in the history
- Added the new workflow `not executed` node type
- Fixed minor style issues
- Created one big catalog for all node variants


![image](https://github.com/user-attachments/assets/5e510d49-c6a2-42a9-9641-057cff481dd9)
  • Loading branch information
Devessier authored Feb 5, 2025
1 parent 5528577 commit 700eb2d
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,16 @@ const StyledStepNodeType = styled.div<{
margin-left: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
.selectable.selected &,
.selectable:focus &,
.selectable:focus-visible & {
.selectable:is(.selected, :focus, :focus-visible) & {
${({ nodeVariant, theme }) => {
switch (nodeVariant) {
case 'empty':
case 'default': {
case 'default':
case 'not-executed':
return css`
background-color: ${theme.color.blue};
color: ${theme.font.color.inverted};
`;
}
}
}}
}
Expand All @@ -70,7 +68,7 @@ const StyledStepNodeType = styled.div<{
const StyledStepNodeInnerContainer = styled.div<{
variant: WorkflowDiagramNodeVariant;
}>`
background-color: ${({ theme }) => theme.background.secondary};
background: ${({ theme }) => theme.background.secondary};
border-color: ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.md};
Expand All @@ -84,26 +82,41 @@ const StyledStepNodeInnerContainer = styled.div<{
position: relative;
.selectable.selected &,
.selectable:focus &,
.selectable:focus-visible & {
transition: background ${({ theme }) => theme.animation.duration.fast} ease;
.workflow-node-container:hover & {
${({ theme }) => {
return css`
background: linear-gradient(
0deg,
${theme.background.transparent.lighter} 0%,
${theme.background.transparent.lighter} 100%
),
${theme.background.secondary};
`;
}}
}
.selectable:is(.selected, :focus, :focus-visible)
:is(.workflow-node-container, .workflow-node-container:hover)
& {
${({ theme, variant }) => {
switch (variant) {
case 'success': {
return css`
background-color: ${theme.adaptiveColors.turquoise1};
background: ${theme.adaptiveColors.turquoise1};
border-color: ${theme.adaptiveColors.turquoise4};
`;
}
case 'failure': {
return css`
background-color: ${theme.background.danger};
background: ${theme.background.danger};
border-color: ${theme.color.red};
`;
}
default: {
return css`
background-color: ${theme.accent.quaternary};
background: ${theme.adaptiveColors.blue1};
border-color: ${theme.color.blue};
`;
}
Expand All @@ -120,11 +133,20 @@ const StyledStepNodeLabel = styled.div<{
font-size: 13px;
font-weight: ${({ theme }) => theme.font.weight.medium};
column-gap: ${({ theme }) => theme.spacing(2)};
color: ${({ variant, theme }) =>
variant === 'empty'
? theme.font.color.extraLight
: theme.font.color.primary};
color: ${({ variant, theme }) => {
switch (variant) {
case 'empty':
case 'not-executed':
return theme.font.color.light;
default:
return theme.font.color.primary;
}
}};
max-width: 200px;
.selectable:is(.selected, :focus, :focus-visible) & {
color: ${({ theme }) => theme.font.color.primary};
}
`;

export const StyledHandle = styled(Handle)`
Expand Down Expand Up @@ -168,7 +190,7 @@ export const WorkflowDiagramBaseStepNode = ({
RightFloatingElement?: React.ReactNode;
}) => {
return (
<StyledStepNodeContainer>
<StyledStepNodeContainer className="workflow-node-container">
{nodeType !== 'trigger' ? (
<StyledTargetHandle type="target" position={Position.Top} />
) : null}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import { Meta, StoryObj } from '@storybook/react';

import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
import { WorkflowDiagramNodeVariant } from '@/workflow/workflow-diagram/types/WorkflowDiagramNodeVariant';
import { fn } from '@storybook/test';
import '@xyflow/react/dist/style.css';
import { ComponentProps } from 'react';
import { CatalogDecorator, CatalogStory } from 'twenty-ui';
import { ReactflowDecorator } from '~/testing/decorators/ReactflowDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { WorkflowDiagramStepNodeEditableContent } from '../WorkflowDiagramStepNodeEditableContent';

const meta: Meta<typeof WorkflowDiagramStepNodeEditableContent> = {
type ComponentState = 'default' | 'hover' | 'selected';

type WrapperProps = ComponentProps<
typeof WorkflowDiagramStepNodeEditableContent
> & { state: ComponentState };

const Wrapper = (_props: WrapperProps) => {
return <div></div>;
};

const meta: Meta<WrapperProps> = {
title: 'Modules/Workflow/WorkflowDiagramStepNodeEditableContent',
component: WorkflowDiagramStepNodeEditableContent,
};

export default meta;

type Story = StoryObj<typeof WorkflowDiagramStepNodeEditableContent>;
type Story = StoryObj<typeof Wrapper>;

const ALL_STEPS = [
{
Expand Down Expand Up @@ -47,17 +59,13 @@ const ALL_STEPS = [
{ nodeType: 'action', actionType: 'CODE', name: 'Code' },
] satisfies WorkflowDiagramStepNodeData[];

export const All: CatalogStory<
Story,
typeof WorkflowDiagramStepNodeEditableContent
> = {
export const Catalog: CatalogStory<Story, typeof Wrapper> = {
args: {
onDelete: fn(),
variant: 'default',
selected: false,
},
parameters: {
msw: graphqlMocks,
pseudo: { hover: ['.hover'] },
catalog: {
options: {
elementContainer: {
Expand All @@ -71,159 +79,36 @@ export const All: CatalogStory<
values: ALL_STEPS,
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
},
],
},
},
decorators: [CatalogDecorator, ReactflowDecorator],
};

export const AllSelected: CatalogStory<
Story,
typeof WorkflowDiagramStepNodeEditableContent
> = {
args: {
onDelete: fn(),
variant: 'default',
selected: true,
},
parameters: {
msw: graphqlMocks,
catalog: {
options: {
elementContainer: {
width: 250,
style: { position: 'relative' },
className: 'selectable selected',
},
},
dimensions: [
{
name: 'step type',
values: ALL_STEPS,
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
name: 'variant',
values: [
'empty',
'default',
'success',
'failure',
'not-executed',
] satisfies WorkflowDiagramNodeVariant[],
props: (variant: WorkflowDiagramNodeVariant) => ({ variant }),
},
],
},
},
decorators: [CatalogDecorator, ReactflowDecorator],
};

export const AllSuccess: CatalogStory<
Story,
typeof WorkflowDiagramStepNodeEditableContent
> = {
args: {
onDelete: fn(),
variant: 'success',
},
parameters: {
msw: graphqlMocks,
catalog: {
options: {
elementContainer: {
width: 250,
style: { position: 'relative' },
},
},
dimensions: [
{
name: 'step type',
values: ALL_STEPS,
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
name: 'state',
values: ['default', 'hover', 'selected'] satisfies ComponentState[],
props: (state: ComponentState) => ({ state }),
},
],
},
},
decorators: [CatalogDecorator, ReactflowDecorator],
};

export const AllSuccessSelected: CatalogStory<
Story,
typeof WorkflowDiagramStepNodeEditableContent
> = {
args: {
onDelete: fn(),
variant: 'success',
selected: true,
},
parameters: {
msw: graphqlMocks,
catalog: {
options: {
elementContainer: {
width: 250,
style: { position: 'relative' },
className: 'selectable selected',
},
},
dimensions: [
{
name: 'step type',
values: ALL_STEPS,
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
},
],
},
},
decorators: [CatalogDecorator, ReactflowDecorator],
};

export const AllFailure: CatalogStory<
Story,
typeof WorkflowDiagramStepNodeEditableContent
> = {
args: {
onDelete: fn(),
variant: 'failure',
},
parameters: {
msw: graphqlMocks,
catalog: {
options: {
elementContainer: {
width: 250,
style: { position: 'relative' },
},
},
dimensions: [
{
name: 'step type',
values: ALL_STEPS,
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
},
],
},
},
decorators: [CatalogDecorator, ReactflowDecorator],
};

export const AllFailureSelected: CatalogStory<
Story,
typeof WorkflowDiagramStepNodeEditableContent
> = {
args: {
onDelete: fn(),
variant: 'failure',
selected: true,
},
parameters: {
msw: graphqlMocks,
catalog: {
options: {
elementContainer: {
width: 250,
style: { position: 'relative' },
className: 'selectable selected',
},
},
dimensions: [
{
name: 'step type',
values: ALL_STEPS,
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
},
],
decorators: [
(Story, { args }) => {
return (
<div
className={`selectable ${args.state === 'selected' ? 'selected' : args.state === 'hover' ? 'workflow-node-container hover' : ''}`}
>
<Story />
</div>
);
},
},
decorators: [CatalogDecorator, ReactflowDecorator],
CatalogDecorator,
ReactflowDecorator,
],
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export type WorkflowDiagramNodeVariant =
| 'default'
| 'success'
| 'failure'
| 'empty';
| 'empty'
| 'not-executed';
4 changes: 4 additions & 0 deletions packages/twenty-ui/src/theme/constants/AdaptiveColorsDark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ export const ADAPTIVE_COLORS_DARK = {
turquoise2: THEME_COMMON.color.turquoise70,
turquoise3: THEME_COMMON.color.turquoise60,
turquoise4: THEME_COMMON.color.turquoise50,
blue1: THEME_COMMON.color.blue80,
blue2: THEME_COMMON.color.blue70,
blue3: THEME_COMMON.color.blue60,
blue4: THEME_COMMON.color.blue50,
};
4 changes: 4 additions & 0 deletions packages/twenty-ui/src/theme/constants/AdaptiveColorsLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ export const ADAPTIVE_COLORS_LIGHT = {
turquoise2: THEME_COMMON.color.turquoise20,
turquoise3: THEME_COMMON.color.turquoise30,
turquoise4: THEME_COMMON.color.turquoise40,
blue1: THEME_COMMON.color.blue10,
blue2: THEME_COMMON.color.blue20,
blue3: THEME_COMMON.color.blue30,
blue4: THEME_COMMON.color.blue40,
};

0 comments on commit 700eb2d

Please sign in to comment.