Create variants for workflow visualizer nodes (#10006)
Closes https://github.com/twentyhq/core-team-issues/issues/332 - Create the success and failed variants - Introduce the first responsive color - Creating stories for the new variants These components are not yet in use in the source code. If you want to see them, launch Storybook. | Success | Failure | |--------|--------| |  |  | |  |  |
This commit is contained in:
committed by
GitHub
parent
5be22413c9
commit
125a0c3419
@ -4,14 +4,14 @@ import { NODE_HANDLE_WIDTH_PX } from '@/workflow/workflow-diagram/constants/Node
|
|||||||
import { NODE_ICON_LEFT_MARGIN } from '@/workflow/workflow-diagram/constants/NodeIconLeftMargin';
|
import { NODE_ICON_LEFT_MARGIN } from '@/workflow/workflow-diagram/constants/NodeIconLeftMargin';
|
||||||
import { NODE_ICON_WIDTH } from '@/workflow/workflow-diagram/constants/NodeIconWidth';
|
import { NODE_ICON_WIDTH } from '@/workflow/workflow-diagram/constants/NodeIconWidth';
|
||||||
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||||
|
import { WorkflowDiagramNodeVariant } from '@/workflow/workflow-diagram/types/WorkflowDiagramNodeVariant';
|
||||||
|
import { css } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Handle, Position } from '@xyflow/react';
|
import { Handle, Position } from '@xyflow/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { capitalize, isDefined } from 'twenty-shared';
|
import { capitalize, isDefined } from 'twenty-shared';
|
||||||
import { Label, OverflowingTextWithTooltip } from 'twenty-ui';
|
import { Label, OverflowingTextWithTooltip } from 'twenty-ui';
|
||||||
|
|
||||||
type Variant = 'placeholder';
|
|
||||||
|
|
||||||
const StyledStepNodeContainer = styled.div`
|
const StyledStepNodeContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -19,52 +19,109 @@ const StyledStepNodeContainer = styled.div`
|
|||||||
padding-block: ${({ theme }) => theme.spacing(3)};
|
padding-block: ${({ theme }) => theme.spacing(3)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledStepNodeType = styled(Label)`
|
const StyledStepNodeType = styled.div<{
|
||||||
background-color: ${({ theme }) => theme.background.tertiary};
|
nodeVariant: WorkflowDiagramNodeVariant;
|
||||||
border-radius: ${({ theme }) => theme.border.radius.sm}
|
}>`
|
||||||
${({ theme }) => theme.border.radius.sm} 0 0;
|
${({ nodeVariant, theme }) => {
|
||||||
|
switch (nodeVariant) {
|
||||||
|
case 'success': {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.tag.background.turquoise};
|
||||||
|
color: ${theme.tag.text.turquoise};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
case 'failure': {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.tag.background.red};
|
||||||
|
color: ${theme.color.red};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.background.tertiary};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
align-self: flex-start;
|
||||||
|
border-radius: ${({ theme }) =>
|
||||||
|
`${theme.border.radius.sm} ${theme.border.radius.sm} 0 0`};
|
||||||
margin-left: ${({ theme }) => theme.spacing(2)};
|
margin-left: ${({ theme }) => theme.spacing(2)};
|
||||||
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
|
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
|
||||||
align-self: flex-start;
|
|
||||||
|
|
||||||
.selectable.selected &,
|
.selectable.selected &,
|
||||||
.selectable:focus &,
|
.selectable:focus &,
|
||||||
.selectable:focus-visible & {
|
.selectable:focus-visible & {
|
||||||
background-color: ${({ theme }) => theme.color.blue};
|
${({ nodeVariant, theme }) => {
|
||||||
color: ${({ theme }) => theme.font.color.inverted};
|
switch (nodeVariant) {
|
||||||
|
case 'empty':
|
||||||
|
case 'default': {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.color.blue};
|
||||||
|
color: ${theme.font.color.inverted};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
`;
|
`.withComponent(Label);
|
||||||
|
|
||||||
const StyledStepNodeInnerContainer = styled.div<{ variant?: Variant }>`
|
const StyledStepNodeInnerContainer = styled.div<{
|
||||||
|
variant: WorkflowDiagramNodeVariant;
|
||||||
|
}>`
|
||||||
background-color: ${({ theme }) => theme.background.secondary};
|
background-color: ${({ theme }) => theme.background.secondary};
|
||||||
border: ${NODE_BORDER_WIDTH}px solid
|
border-color: ${({ theme }) => theme.border.color.medium};
|
||||||
${({ theme }) => theme.border.color.medium};
|
|
||||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||||
|
border-style: solid;
|
||||||
|
border-width: ${NODE_BORDER_WIDTH}px;
|
||||||
|
box-shadow: ${({ variant, theme }) =>
|
||||||
|
variant === 'empty' ? 'none' : theme.boxShadow.strong};
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
padding: ${({ theme }) => theme.spacing(2)};
|
padding: ${({ theme }) => theme.spacing(2)};
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
box-shadow: ${({ variant, theme }) =>
|
|
||||||
variant === 'placeholder' ? 'none' : theme.boxShadow.strong};
|
|
||||||
|
|
||||||
.selectable.selected &,
|
.selectable.selected &,
|
||||||
.selectable:focus &,
|
.selectable:focus &,
|
||||||
.selectable:focus-visible & {
|
.selectable:focus-visible & {
|
||||||
background-color: ${({ theme }) => theme.accent.quaternary};
|
${({ theme, variant }) => {
|
||||||
border-color: ${({ theme }) => theme.color.blue};
|
switch (variant) {
|
||||||
|
case 'success': {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.adaptiveColors.turquoise1};
|
||||||
|
border-color: ${theme.adaptiveColors.turquoise4};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
case 'failure': {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.background.danger};
|
||||||
|
border-color: ${theme.color.red};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return css`
|
||||||
|
background-color: ${theme.accent.quaternary};
|
||||||
|
border-color: ${theme.color.blue};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledStepNodeLabel = styled.div<{ variant?: Variant }>`
|
const StyledStepNodeLabel = styled.div<{
|
||||||
|
variant: WorkflowDiagramNodeVariant;
|
||||||
|
}>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||||
column-gap: ${({ theme }) => theme.spacing(2)};
|
column-gap: ${({ theme }) => theme.spacing(2)};
|
||||||
color: ${({ variant, theme }) =>
|
color: ${({ variant, theme }) =>
|
||||||
variant === 'placeholder'
|
variant === 'empty'
|
||||||
? theme.font.color.extraLight
|
? theme.font.color.extraLight
|
||||||
: theme.font.color.primary};
|
: theme.font.color.primary};
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
@ -106,7 +163,7 @@ export const WorkflowDiagramBaseStepNode = ({
|
|||||||
}: {
|
}: {
|
||||||
nodeType: WorkflowDiagramStepNodeData['nodeType'];
|
nodeType: WorkflowDiagramStepNodeData['nodeType'];
|
||||||
name: string;
|
name: string;
|
||||||
variant?: Variant;
|
variant: WorkflowDiagramNodeVariant;
|
||||||
Icon?: React.ReactNode;
|
Icon?: React.ReactNode;
|
||||||
RightFloatingElement?: React.ReactNode;
|
RightFloatingElement?: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
@ -116,7 +173,7 @@ export const WorkflowDiagramBaseStepNode = ({
|
|||||||
<StyledTargetHandle type="target" position={Position.Top} />
|
<StyledTargetHandle type="target" position={Position.Top} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<StyledStepNodeType variant="small">
|
<StyledStepNodeType variant="small" nodeVariant={variant}>
|
||||||
{capitalize(nodeType)}
|
{capitalize(nodeType)}
|
||||||
</StyledStepNodeType>
|
</StyledStepNodeType>
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export const WorkflowDiagramEmptyTrigger = () => {
|
|||||||
<WorkflowDiagramBaseStepNode
|
<WorkflowDiagramBaseStepNode
|
||||||
name="Add a Trigger"
|
name="Add a Trigger"
|
||||||
nodeType="trigger"
|
nodeType="trigger"
|
||||||
variant="placeholder"
|
variant="empty"
|
||||||
Icon={<StyledStepNodeLabelIconContainer />}
|
Icon={<StyledStepNodeLabelIconContainer />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
|
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
|
||||||
import { WorkflowDiagramBaseStepNode } from '@/workflow/workflow-diagram/components/WorkflowDiagramBaseStepNode';
|
import { WorkflowDiagramBaseStepNode } from '@/workflow/workflow-diagram/components/WorkflowDiagramBaseStepNode';
|
||||||
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||||
|
import { WorkflowDiagramNodeVariant } from '@/workflow/workflow-diagram/types/WorkflowDiagramNodeVariant';
|
||||||
import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWorkflowNodeIconKey';
|
import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWorkflowNodeIconKey';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@ -17,9 +18,11 @@ const StyledStepNodeLabelIconContainer = styled.div`
|
|||||||
|
|
||||||
export const WorkflowDiagramStepNodeBase = ({
|
export const WorkflowDiagramStepNodeBase = ({
|
||||||
data,
|
data,
|
||||||
|
variant,
|
||||||
RightFloatingElement,
|
RightFloatingElement,
|
||||||
}: {
|
}: {
|
||||||
data: WorkflowDiagramStepNodeData;
|
data: WorkflowDiagramStepNodeData;
|
||||||
|
variant: WorkflowDiagramNodeVariant;
|
||||||
RightFloatingElement?: React.ReactNode;
|
RightFloatingElement?: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -93,6 +96,7 @@ export const WorkflowDiagramStepNodeBase = ({
|
|||||||
return (
|
return (
|
||||||
<WorkflowDiagramBaseStepNode
|
<WorkflowDiagramBaseStepNode
|
||||||
name={data.name}
|
name={data.name}
|
||||||
|
variant={variant}
|
||||||
nodeType={data.nodeType}
|
nodeType={data.nodeType}
|
||||||
Icon={renderStepIcon()}
|
Icon={renderStepIcon()}
|
||||||
RightFloatingElement={RightFloatingElement}
|
RightFloatingElement={RightFloatingElement}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export const WorkflowDiagramStepNodeEditable = ({
|
|||||||
return (
|
return (
|
||||||
<WorkflowDiagramStepNodeEditableContent
|
<WorkflowDiagramStepNodeEditableContent
|
||||||
data={data}
|
data={data}
|
||||||
|
variant="default"
|
||||||
selected={selected ?? false}
|
selected={selected ?? false}
|
||||||
onDelete={() => {
|
onDelete={() => {
|
||||||
deleteStep(id);
|
deleteStep(id);
|
||||||
|
|||||||
@ -1,19 +1,23 @@
|
|||||||
import { WorkflowDiagramStepNodeBase } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeBase';
|
import { WorkflowDiagramStepNodeBase } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeBase';
|
||||||
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||||
|
import { WorkflowDiagramNodeVariant } from '@/workflow/workflow-diagram/types/WorkflowDiagramNodeVariant';
|
||||||
import { FloatingIconButton, IconTrash } from 'twenty-ui';
|
import { FloatingIconButton, IconTrash } from 'twenty-ui';
|
||||||
|
|
||||||
export const WorkflowDiagramStepNodeEditableContent = ({
|
export const WorkflowDiagramStepNodeEditableContent = ({
|
||||||
data,
|
data,
|
||||||
selected,
|
selected,
|
||||||
|
variant,
|
||||||
onDelete,
|
onDelete,
|
||||||
}: {
|
}: {
|
||||||
data: WorkflowDiagramStepNodeData;
|
data: WorkflowDiagramStepNodeData;
|
||||||
|
variant: WorkflowDiagramNodeVariant;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
onDelete: () => void;
|
onDelete: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<WorkflowDiagramStepNodeBase
|
<WorkflowDiagramStepNodeBase
|
||||||
data={data}
|
data={data}
|
||||||
|
variant={variant}
|
||||||
RightFloatingElement={
|
RightFloatingElement={
|
||||||
selected ? (
|
selected ? (
|
||||||
<FloatingIconButton
|
<FloatingIconButton
|
||||||
|
|||||||
@ -6,5 +6,5 @@ export const WorkflowDiagramStepNodeReadonly = ({
|
|||||||
}: {
|
}: {
|
||||||
data: WorkflowDiagramStepNodeData;
|
data: WorkflowDiagramStepNodeData;
|
||||||
}) => {
|
}) => {
|
||||||
return <WorkflowDiagramStepNodeBase data={data} />;
|
return <WorkflowDiagramStepNodeBase variant="default" data={data} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,9 +2,9 @@ import { Meta, StoryObj } from '@storybook/react';
|
|||||||
|
|
||||||
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
import { WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||||
import { fn } from '@storybook/test';
|
import { fn } from '@storybook/test';
|
||||||
import { ReactFlowProvider } from '@xyflow/react';
|
|
||||||
import '@xyflow/react/dist/style.css';
|
import '@xyflow/react/dist/style.css';
|
||||||
import { CatalogDecorator, CatalogStory } from 'twenty-ui';
|
import { CatalogDecorator, CatalogStory } from 'twenty-ui';
|
||||||
|
import { ReactflowDecorator } from '~/testing/decorators/ReactflowDecorator';
|
||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
import { WorkflowDiagramStepNodeEditableContent } from '../WorkflowDiagramStepNodeEditableContent';
|
import { WorkflowDiagramStepNodeEditableContent } from '../WorkflowDiagramStepNodeEditableContent';
|
||||||
|
|
||||||
@ -17,12 +17,43 @@ export default meta;
|
|||||||
|
|
||||||
type Story = StoryObj<typeof WorkflowDiagramStepNodeEditableContent>;
|
type Story = StoryObj<typeof WorkflowDiagramStepNodeEditableContent>;
|
||||||
|
|
||||||
|
const ALL_STEPS = [
|
||||||
|
{
|
||||||
|
nodeType: 'trigger',
|
||||||
|
triggerType: 'DATABASE_EVENT',
|
||||||
|
name: 'Record is Created',
|
||||||
|
},
|
||||||
|
{ nodeType: 'trigger', triggerType: 'MANUAL', name: 'Manual' },
|
||||||
|
{
|
||||||
|
nodeType: 'action',
|
||||||
|
actionType: 'CREATE_RECORD',
|
||||||
|
name: 'Create Record',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nodeType: 'action',
|
||||||
|
actionType: 'UPDATE_RECORD',
|
||||||
|
name: 'Update Record',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nodeType: 'action',
|
||||||
|
actionType: 'DELETE_RECORD',
|
||||||
|
name: 'Delete Record',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nodeType: 'action',
|
||||||
|
actionType: 'SEND_EMAIL',
|
||||||
|
name: 'Send Email',
|
||||||
|
},
|
||||||
|
{ nodeType: 'action', actionType: 'CODE', name: 'Code' },
|
||||||
|
] satisfies WorkflowDiagramStepNodeData[];
|
||||||
|
|
||||||
export const All: CatalogStory<
|
export const All: CatalogStory<
|
||||||
Story,
|
Story,
|
||||||
typeof WorkflowDiagramStepNodeEditableContent
|
typeof WorkflowDiagramStepNodeEditableContent
|
||||||
> = {
|
> = {
|
||||||
args: {
|
args: {
|
||||||
onDelete: fn(),
|
onDelete: fn(),
|
||||||
|
variant: 'default',
|
||||||
selected: false,
|
selected: false,
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
@ -37,57 +68,22 @@ export const All: CatalogStory<
|
|||||||
dimensions: [
|
dimensions: [
|
||||||
{
|
{
|
||||||
name: 'step type',
|
name: 'step type',
|
||||||
values: [
|
values: ALL_STEPS,
|
||||||
{
|
|
||||||
nodeType: 'trigger',
|
|
||||||
triggerType: 'DATABASE_EVENT',
|
|
||||||
name: 'Record is Created',
|
|
||||||
},
|
|
||||||
{ nodeType: 'trigger', triggerType: 'MANUAL', name: 'Manual' },
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'CREATE_RECORD',
|
|
||||||
name: 'Create Record',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'UPDATE_RECORD',
|
|
||||||
name: 'Update Record',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'DELETE_RECORD',
|
|
||||||
name: 'Delete Record',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'SEND_EMAIL',
|
|
||||||
name: 'Send Email',
|
|
||||||
},
|
|
||||||
{ nodeType: 'action', actionType: 'CODE', name: 'Code' },
|
|
||||||
] satisfies WorkflowDiagramStepNodeData[],
|
|
||||||
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
|
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
decorators: [
|
decorators: [CatalogDecorator, ReactflowDecorator],
|
||||||
CatalogDecorator,
|
|
||||||
(Story) => {
|
|
||||||
return (
|
|
||||||
<ReactFlowProvider>
|
|
||||||
<Story />
|
|
||||||
</ReactFlowProvider>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AllSelected: CatalogStory<
|
export const AllSelected: CatalogStory<
|
||||||
Story,
|
Story,
|
||||||
typeof WorkflowDiagramStepNodeEditableContent
|
typeof WorkflowDiagramStepNodeEditableContent
|
||||||
> = {
|
> = {
|
||||||
args: {
|
args: {
|
||||||
onDelete: fn(),
|
onDelete: fn(),
|
||||||
|
variant: 'default',
|
||||||
selected: true,
|
selected: true,
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
@ -103,48 +99,131 @@ export const AllSelected: CatalogStory<
|
|||||||
dimensions: [
|
dimensions: [
|
||||||
{
|
{
|
||||||
name: 'step type',
|
name: 'step type',
|
||||||
values: [
|
values: ALL_STEPS,
|
||||||
{
|
|
||||||
nodeType: 'trigger',
|
|
||||||
triggerType: 'DATABASE_EVENT',
|
|
||||||
name: 'Record is Created',
|
|
||||||
},
|
|
||||||
{ nodeType: 'trigger', triggerType: 'MANUAL', name: 'Manual' },
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'CREATE_RECORD',
|
|
||||||
name: 'Create Record',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'UPDATE_RECORD',
|
|
||||||
name: 'Update Record',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'DELETE_RECORD',
|
|
||||||
name: 'Delete Record',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeType: 'action',
|
|
||||||
actionType: 'SEND_EMAIL',
|
|
||||||
name: 'Send Email',
|
|
||||||
},
|
|
||||||
{ nodeType: 'action', actionType: 'CODE', name: 'Code' },
|
|
||||||
] satisfies WorkflowDiagramStepNodeData[],
|
|
||||||
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
|
props: (data: WorkflowDiagramStepNodeData) => ({ data }),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
decorators: [
|
decorators: [CatalogDecorator, ReactflowDecorator],
|
||||||
CatalogDecorator,
|
};
|
||||||
(Story) => {
|
|
||||||
return (
|
export const AllSuccess: CatalogStory<
|
||||||
<ReactFlowProvider>
|
Story,
|
||||||
<Story />
|
typeof WorkflowDiagramStepNodeEditableContent
|
||||||
</ReactFlowProvider>
|
> = {
|
||||||
);
|
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 }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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: [CatalogDecorator, ReactflowDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
export type WorkflowDiagramNodeVariant =
|
||||||
|
| 'default'
|
||||||
|
| 'success'
|
||||||
|
| 'failure'
|
||||||
|
| 'empty';
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { Decorator } from '@storybook/react';
|
||||||
|
import { ReactFlowProvider } from '@xyflow/react';
|
||||||
|
|
||||||
|
export const ReactflowDecorator: Decorator = (Story) => {
|
||||||
|
return (
|
||||||
|
<ReactFlowProvider>
|
||||||
|
<Story />
|
||||||
|
</ReactFlowProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { THEME_COMMON } from '@ui/theme/constants/ThemeCommon';
|
||||||
|
|
||||||
|
export const ADAPTIVE_COLORS_DARK = {
|
||||||
|
turquoise1: THEME_COMMON.color.turquoise80,
|
||||||
|
turquoise2: THEME_COMMON.color.turquoise70,
|
||||||
|
turquoise3: THEME_COMMON.color.turquoise60,
|
||||||
|
turquoise4: THEME_COMMON.color.turquoise50,
|
||||||
|
};
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { THEME_COMMON } from '@ui/theme/constants/ThemeCommon';
|
||||||
|
|
||||||
|
export const ADAPTIVE_COLORS_LIGHT = {
|
||||||
|
turquoise1: THEME_COMMON.color.turquoise10,
|
||||||
|
turquoise2: THEME_COMMON.color.turquoise20,
|
||||||
|
turquoise3: THEME_COMMON.color.turquoise30,
|
||||||
|
turquoise4: THEME_COMMON.color.turquoise40,
|
||||||
|
};
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { ADAPTIVE_COLORS_DARK } from '@ui/theme/constants/AdaptiveColorsDark';
|
||||||
import { BLUR_DARK } from '@ui/theme/constants/BlurDark';
|
import { BLUR_DARK } from '@ui/theme/constants/BlurDark';
|
||||||
import { ILLUSTRATION_ICON_DARK } from '@ui/theme/constants/IllustrationIconDark';
|
import { ILLUSTRATION_ICON_DARK } from '@ui/theme/constants/IllustrationIconDark';
|
||||||
import { SNACK_BAR_DARK, ThemeType } from '..';
|
import { SNACK_BAR_DARK, ThemeType } from '..';
|
||||||
@ -24,5 +25,6 @@ export const THEME_DARK: ThemeType = {
|
|||||||
tag: TAG_DARK,
|
tag: TAG_DARK,
|
||||||
code: CODE_DARK,
|
code: CODE_DARK,
|
||||||
IllustrationIcon: ILLUSTRATION_ICON_DARK,
|
IllustrationIcon: ILLUSTRATION_ICON_DARK,
|
||||||
|
adaptiveColors: ADAPTIVE_COLORS_DARK,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { ADAPTIVE_COLORS_LIGHT } from '@ui/theme/constants/AdaptiveColorsLight';
|
||||||
import { BLUR_LIGHT } from '@ui/theme/constants/BlurLight';
|
import { BLUR_LIGHT } from '@ui/theme/constants/BlurLight';
|
||||||
import { ILLUSTRATION_ICON_LIGHT } from '@ui/theme/constants/IllustrationIconLight';
|
import { ILLUSTRATION_ICON_LIGHT } from '@ui/theme/constants/IllustrationIconLight';
|
||||||
import { SNACK_BAR_LIGHT } from '@ui/theme/constants/SnackBarLight';
|
import { SNACK_BAR_LIGHT } from '@ui/theme/constants/SnackBarLight';
|
||||||
@ -24,5 +25,6 @@ export const THEME_LIGHT = {
|
|||||||
tag: TAG_LIGHT,
|
tag: TAG_LIGHT,
|
||||||
code: CODE_LIGHT,
|
code: CODE_LIGHT,
|
||||||
IllustrationIcon: ILLUSTRATION_ICON_LIGHT,
|
IllustrationIcon: ILLUSTRATION_ICON_LIGHT,
|
||||||
|
adaptiveColors: ADAPTIVE_COLORS_LIGHT,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export * from './constants/AccentDark';
|
export * from './constants/AccentDark';
|
||||||
export * from './constants/AccentLight';
|
export * from './constants/AccentLight';
|
||||||
|
export * from './constants/AdaptiveColorsDark';
|
||||||
|
export * from './constants/AdaptiveColorsLight';
|
||||||
export * from './constants/Animation';
|
export * from './constants/Animation';
|
||||||
export * from './constants/BackgroundDark';
|
export * from './constants/BackgroundDark';
|
||||||
export * from './constants/BackgroundLight';
|
export * from './constants/BackgroundLight';
|
||||||
|
|||||||
Reference in New Issue
Block a user