feat: introduce dummy flow editor
This commit is contained in:
29
packages/web/src/components/Editor/index.tsx
Normal file
29
packages/web/src/components/Editor/index.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
|
||||||
|
import FlowStep from 'components/FlowStep';
|
||||||
|
import type { Flow } from 'types/flow';
|
||||||
|
|
||||||
|
type EditorProps = {
|
||||||
|
flow?: Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Editor(props: EditorProps) {
|
||||||
|
const { flow } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
display="flex"
|
||||||
|
flex={1}
|
||||||
|
flexDirection="column"
|
||||||
|
alignItems="center"
|
||||||
|
width={800}
|
||||||
|
maxWidth="100%"
|
||||||
|
alignSelf="center"
|
||||||
|
py={3}
|
||||||
|
gap={2}
|
||||||
|
>
|
||||||
|
{flow?.steps?.map(step => (<FlowStep key={step.id} step={step} />))}
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
};
|
60
packages/web/src/components/EditorLayout/index.tsx
Normal file
60
packages/web/src/components/EditorLayout/index.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useQuery } from '@apollo/client';
|
||||||
|
import Stack from '@mui/material/Stack';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
|
import Switch from '@mui/material/Switch';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
||||||
|
|
||||||
|
import Editor from 'components/Editor';
|
||||||
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
import { GET_FLOW } from 'graphql/queries/get-flow';
|
||||||
|
import type { Flow } from 'types/flow';
|
||||||
|
|
||||||
|
type EditorLayoutProps = {
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function EditorLayout(props: EditorLayoutProps) {
|
||||||
|
const { flowId } = useParams();
|
||||||
|
const formatMessage = useFormatMessage();
|
||||||
|
const { data } = useQuery(GET_FLOW, { variables: { id: flowId }});
|
||||||
|
const flow: Flow = data?.getFlow;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack direction="column" height="100%">
|
||||||
|
<Stack direction="row" bgcolor="white" justifyContent="space-between" alignItems="center" boxShadow={1} py={1} px={1}>
|
||||||
|
<Box display="flex" flex={1} alignItems="center">
|
||||||
|
<IconButton size="small">
|
||||||
|
<ArrowBackIosNewIcon fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Typography variant="body1" noWrap sx={{ width: 300, maxWidth: '300px '}}>
|
||||||
|
{flow?.name}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box pr={1}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch checked={false} />
|
||||||
|
}
|
||||||
|
label={formatMessage('flow.inactive')}
|
||||||
|
labelPlacement="start"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Box display="flex" flex="1" flexDirection="column">
|
||||||
|
{!flow && 'not found'}
|
||||||
|
|
||||||
|
{flow && <Editor flow={flow} />}
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
18
packages/web/src/components/FlowStep/index.tsx
Normal file
18
packages/web/src/components/FlowStep/index.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { Wrapper } from './style';
|
||||||
|
|
||||||
|
type FlowStepProps = {
|
||||||
|
collapsed?: boolean;
|
||||||
|
step?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FlowStep(props: FlowStepProps) {
|
||||||
|
const { step } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper elevation={1}>
|
||||||
|
{step?.type} - {step?.appKey} - {step?.key} - {step?.connectionId}
|
||||||
|
</Wrapper>
|
||||||
|
)
|
||||||
|
};
|
8
packages/web/src/components/FlowStep/style.ts
Normal file
8
packages/web/src/components/FlowStep/style.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
import Card from '@mui/material/Card';
|
||||||
|
|
||||||
|
export const Wrapper = styled(Card)`
|
||||||
|
width: 100%;
|
||||||
|
padding: ${({ theme }) => theme.spacing(1, 2)};
|
||||||
|
`;
|
||||||
|
|
@@ -16,5 +16,6 @@ export const APP_FLOWS = (appKey: string) => `/app/${appKey}/flows`;
|
|||||||
export const APP_FLOWS_PATTERN = '/app/:appKey/flows';
|
export const APP_FLOWS_PATTERN = '/app/:appKey/flows';
|
||||||
export const NEW_APP_CONNECTION = '/apps/new';
|
export const NEW_APP_CONNECTION = '/apps/new';
|
||||||
export const CREATE_FLOW = '/editor/create';
|
export const CREATE_FLOW = '/editor/create';
|
||||||
export const FLOW = (flowKey: string) => `/flows/${flowKey}`;
|
export const FLOW_EDITOR = (flowId: string) => `/editor/${flowId}`;
|
||||||
export const FLOW_PATTERN = '/flows/:flowKey';
|
export const FLOW = (flowId: string) => `/flows/${flowId}`;
|
||||||
|
export const FLOW_PATTERN = '/flows/:flowId';
|
||||||
|
17
packages/web/src/graphql/queries/get-flow.ts
Normal file
17
packages/web/src/graphql/queries/get-flow.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const GET_FLOW = gql`
|
||||||
|
query GetFlow($id: String!) {
|
||||||
|
getFlow(id: $id) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
steps {
|
||||||
|
id
|
||||||
|
type
|
||||||
|
key
|
||||||
|
appKey
|
||||||
|
connectionId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
@@ -30,5 +30,7 @@
|
|||||||
"connection.delete": "Delete",
|
"connection.delete": "Delete",
|
||||||
"connection.deletedMessage": "The connection has been deleted.",
|
"connection.deletedMessage": "The connection has been deleted.",
|
||||||
"connection.addedAt": "added {datetime}",
|
"connection.addedAt": "added {datetime}",
|
||||||
"createFlow.creating": "Creating a flow..."
|
"createFlow.creating": "Creating a flow...",
|
||||||
|
"flow.active": "Enabled",
|
||||||
|
"flow.inactive": "Disabled"
|
||||||
}
|
}
|
@@ -21,7 +21,7 @@ export default function CreateFlow() {
|
|||||||
const flowId = response.data?.createFlow?.id;
|
const flowId = response.data?.createFlow?.id;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate(URLS.FLOW(flowId));
|
navigate(URLS.FLOW_EDITOR(flowId));
|
||||||
}, 1234);
|
}, 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
import * as React from 'react';
|
import EditorLayout from 'components/EditorLayout';
|
||||||
import { Routes, Route } from 'react-router-dom';
|
|
||||||
import CreateFlowPage from './create';
|
|
||||||
|
|
||||||
export default function Editor() {
|
export default function FlowEditor() {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<EditorLayout />
|
||||||
<Route path="/create" element={<CreateFlowPage />} />
|
|
||||||
</Routes>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
14
packages/web/src/pages/Editor/routes.tsx
Normal file
14
packages/web/src/pages/Editor/routes.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Routes, Route } from 'react-router-dom';
|
||||||
|
import CreateFlowPage from './create';
|
||||||
|
import EditorPage from './index';
|
||||||
|
|
||||||
|
export default function EditorRoutes() {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path="/create" element={<CreateFlowPage />} />
|
||||||
|
|
||||||
|
<Route path="/:flowId" element={<EditorPage />} />
|
||||||
|
</Routes>
|
||||||
|
)
|
||||||
|
}
|
@@ -4,7 +4,7 @@ import Applications from 'pages/Applications';
|
|||||||
import Application from 'pages/Application';
|
import Application from 'pages/Application';
|
||||||
import Flows from 'pages/Flows';
|
import Flows from 'pages/Flows';
|
||||||
import Explore from 'pages/Explore';
|
import Explore from 'pages/Explore';
|
||||||
import Editor from 'pages/Editor';
|
import EditorRoutes from 'pages/Editor/routes';
|
||||||
import * as URLS from 'config/urls';
|
import * as URLS from 'config/urls';
|
||||||
|
|
||||||
export default (
|
export default (
|
||||||
@@ -17,7 +17,7 @@ export default (
|
|||||||
|
|
||||||
<Route path={`${URLS.APP_PATTERN}/*`} element={<Layout><Application /></Layout>} />
|
<Route path={`${URLS.APP_PATTERN}/*`} element={<Layout><Application /></Layout>} />
|
||||||
|
|
||||||
<Route path={`${URLS.EDITOR}/*`} element={<Editor />} />
|
<Route path={`${URLS.EDITOR}/*`} element={<EditorRoutes />} />
|
||||||
|
|
||||||
<Route path="/" element={<Navigate to={URLS.FLOWS} />} />
|
<Route path="/" element={<Navigate to={URLS.FLOWS} />} />
|
||||||
|
|
||||||
|
@@ -229,6 +229,9 @@ const extendedTheme = createTheme({
|
|||||||
a: {
|
a: {
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
},
|
},
|
||||||
|
'#root': {
|
||||||
|
height: '100vh'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MuiDialog: {
|
MuiDialog: {
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
|
import type { Step } from './step';
|
||||||
|
|
||||||
export type Flow = {
|
export type Flow = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
steps: Step[];
|
||||||
};
|
};
|
||||||
|
7
packages/web/src/types/step.ts
Normal file
7
packages/web/src/types/step.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export type Step = {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
appKey: string;
|
||||||
|
type: 'trigger' | 'action';
|
||||||
|
connectionId: number;
|
||||||
|
};
|
Reference in New Issue
Block a user