Add the new workflow not executed node type (#10030)
- Added the new workflow `not executed` node type - Fixed minor style issues - Created one big catalog for all node variants 
This commit is contained in:
committed by
GitHub
parent
5528577707
commit
700eb2d473
@ -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};
|
||||
`;
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
@ -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};
|
||||
@ -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};
|
||||
`;
|
||||
}
|
||||
@ -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)`
|
||||
@ -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}
|
||||
|
||||
@ -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 = [
|
||||
{
|
||||
@ -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: {
|
||||
@ -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: [
|
||||
(Story, { args }) => {
|
||||
return (
|
||||
<div
|
||||
className={`selectable ${args.state === 'selected' ? 'selected' : args.state === 'hover' ? 'workflow-node-container hover' : ''}`}
|
||||
>
|
||||
<Story />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
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: [CatalogDecorator, ReactflowDecorator],
|
||||
CatalogDecorator,
|
||||
ReactflowDecorator,
|
||||
],
|
||||
};
|
||||
|
||||
@ -2,4 +2,5 @@ export type WorkflowDiagramNodeVariant =
|
||||
| 'default'
|
||||
| 'success'
|
||||
| 'failure'
|
||||
| 'empty';
|
||||
| 'empty'
|
||||
| 'not-executed';
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user