feat: introduce steps in flow editor
This commit is contained in:

committed by
Ömer Faruk Aydın

parent
a232408f22
commit
247b25cfc4
@@ -19,7 +19,7 @@ export default function AppIcon(props: AppIconProps & AvatarProps) {
|
|||||||
<Avatar
|
<Avatar
|
||||||
component="span"
|
component="span"
|
||||||
variant="square"
|
variant="square"
|
||||||
sx={{ bgcolor: color, display: 'inline-flex', width: 50, height: 50, ...sx }}
|
sx={{ bgcolor: color, display: 'flex', width: 50, height: 50, ...sx }}
|
||||||
imgProps={{ style: inlineImgStyle }}
|
imgProps={{ style: inlineImgStyle }}
|
||||||
src={url}
|
src={url}
|
||||||
alt={name}
|
alt={name}
|
||||||
|
@@ -5,10 +5,11 @@ import FlowStep from 'components/FlowStep';
|
|||||||
import type { Flow } from 'types/flow';
|
import type { Flow } from 'types/flow';
|
||||||
|
|
||||||
type EditorProps = {
|
type EditorProps = {
|
||||||
flow?: Flow;
|
flow: Flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Editor(props: EditorProps) {
|
export default function Editor(props: EditorProps) {
|
||||||
|
const [currentStep, setCurrentStep] = React.useState<number | null>(null);
|
||||||
const { flow } = props;
|
const { flow } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -17,13 +18,20 @@ export default function Editor(props: EditorProps) {
|
|||||||
flex={1}
|
flex={1}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
width={800}
|
|
||||||
maxWidth="100%"
|
|
||||||
alignSelf="center"
|
alignSelf="center"
|
||||||
py={3}
|
py={3}
|
||||||
gap={2}
|
gap={2}
|
||||||
>
|
>
|
||||||
{flow?.steps?.map(step => (<FlowStep key={step.id} step={step} />))}
|
{flow?.steps?.map((step, index) => (
|
||||||
|
<FlowStep
|
||||||
|
key={step.id}
|
||||||
|
step={step}
|
||||||
|
index={index + 1}
|
||||||
|
collapsed={currentStep !== index}
|
||||||
|
onOpen={() => setCurrentStep(index)}
|
||||||
|
onClose={() => setCurrentStep(null)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
};
|
};
|
@@ -9,6 +9,7 @@ import Switch from '@mui/material/Switch';
|
|||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
||||||
|
|
||||||
|
import Container from 'components/Container';
|
||||||
import Editor from 'components/Editor';
|
import Editor from 'components/Editor';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import { GET_FLOW } from 'graphql/queries/get-flow';
|
import { GET_FLOW } from 'graphql/queries/get-flow';
|
||||||
@@ -33,7 +34,7 @@ export default function EditorLayout(props: EditorLayoutProps) {
|
|||||||
<ArrowBackIosNewIcon fontSize="small" />
|
<ArrowBackIosNewIcon fontSize="small" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<Typography variant="body1" noWrap sx={{ width: 300, maxWidth: '300px '}}>
|
<Typography variant="body1" noWrap sx={{ display: 'flex', flex: 1, maxWidth: '50vw' }}>
|
||||||
{flow?.name}
|
{flow?.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -49,11 +50,11 @@ export default function EditorLayout(props: EditorLayoutProps) {
|
|||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Box display="flex" flex="1" flexDirection="column">
|
<Container maxWidth="md">
|
||||||
{!flow && 'not found'}
|
{!flow && 'not found'}
|
||||||
|
|
||||||
{flow && <Editor flow={flow} />}
|
{flow && <Editor flow={flow} />}
|
||||||
</Box>
|
</Container>
|
||||||
</Stack>
|
</Stack>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@@ -1,18 +1,58 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useQuery } from '@apollo/client';
|
||||||
|
import Stack from '@mui/material/Stack';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
|
||||||
import { Wrapper } from './style';
|
import AppIcon from 'components/AppIcon';
|
||||||
|
import { GET_APP } from 'graphql/queries/get-app';
|
||||||
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
import type { Step } from 'types/step';
|
||||||
|
import { StepType } from 'types/step';
|
||||||
|
import { Header, Wrapper } from './style';
|
||||||
|
|
||||||
type FlowStepProps = {
|
type FlowStepProps = {
|
||||||
collapsed?: boolean;
|
collapsed?: boolean;
|
||||||
step?: any;
|
step: Step;
|
||||||
|
index?: number;
|
||||||
|
onOpen?: () => void;
|
||||||
|
onClose?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function FlowStep(props: FlowStepProps) {
|
export default function FlowStep(props: FlowStepProps) {
|
||||||
const { step } = props;
|
const { collapsed, index, step } = props;
|
||||||
|
const formatMessage = useFormatMessage();
|
||||||
|
const { data } = useQuery(GET_APP, { variables: { key: step?.appKey }})
|
||||||
|
const app = data?.getApp;
|
||||||
|
|
||||||
|
if (!app) return null;
|
||||||
|
|
||||||
|
const onOpen = () => collapsed && props.onOpen?.();
|
||||||
|
const onClose = () => props.onClose?.();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper elevation={1}>
|
<Wrapper elevation={collapsed ? 1 : 4} onClick={onOpen}>
|
||||||
{step?.type} - {step?.appKey} - {step?.key} - {step?.connectionId}
|
<Header borderBottom={!collapsed}>
|
||||||
|
<Stack direction="row" alignItems="center" gap={2}>
|
||||||
|
<AppIcon url={app.iconUrl} name={app.name} />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Typography variant="caption">
|
||||||
|
{step.type === StepType.Trigger ? formatMessage('flowStep.triggerType') : formatMessage('flowStep.actionType')}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography variant="body2">
|
||||||
|
{index}. {app.name}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</Stack>
|
||||||
|
</Header>
|
||||||
|
|
||||||
|
{!collapsed && (
|
||||||
|
<Button onClick={onClose}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@@ -1,8 +1,16 @@
|
|||||||
import { styled } from '@mui/material/styles';
|
import { styled, alpha } from '@mui/material/styles';
|
||||||
import Card from '@mui/material/Card';
|
import Card from '@mui/material/Card';
|
||||||
|
|
||||||
export const Wrapper = styled(Card)`
|
export const Wrapper = styled(Card)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: ${({ theme }) => theme.spacing(1, 2)};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
type HeaderProps = {
|
||||||
|
borderBottom?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Header = styled('div', { shouldForwardProp: prop => prop !== 'borderBottom' })<HeaderProps>`
|
||||||
|
border-bottom: 1px solid ${({ theme, borderBottom }) => borderBottom ? alpha(theme.palette.divider, .8) : 'transparent'};
|
||||||
|
padding: ${({ theme }) => theme.spacing(2, 2)};
|
||||||
|
cursor: ${({ borderBottom }) => borderBottom ? 'unset' : 'pointer'};
|
||||||
|
`;
|
@@ -10,7 +10,9 @@ export const GET_FLOW = gql`
|
|||||||
type
|
type
|
||||||
key
|
key
|
||||||
appKey
|
appKey
|
||||||
connectionId
|
connection {
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,5 +32,7 @@
|
|||||||
"connection.addedAt": "added {datetime}",
|
"connection.addedAt": "added {datetime}",
|
||||||
"createFlow.creating": "Creating a flow...",
|
"createFlow.creating": "Creating a flow...",
|
||||||
"flow.active": "Enabled",
|
"flow.active": "Enabled",
|
||||||
"flow.inactive": "Disabled"
|
"flow.inactive": "Disabled",
|
||||||
|
"flowStep.triggerType": "Trigger",
|
||||||
|
"flowStep.actionType": "Action"
|
||||||
}
|
}
|
@@ -1,7 +1,12 @@
|
|||||||
|
export enum StepType {
|
||||||
|
Trigger = 'trigger',
|
||||||
|
Action = 'action',
|
||||||
|
}
|
||||||
|
|
||||||
export type Step = {
|
export type Step = {
|
||||||
id: string;
|
id: string;
|
||||||
key: string;
|
key: string;
|
||||||
appKey: string;
|
appKey: string;
|
||||||
type: 'trigger' | 'action';
|
type: StepType;
|
||||||
connectionId: number;
|
connectionId: number;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user