feat: introduce basic flows page

This commit is contained in:
Ali BARIN
2022-01-05 21:36:51 +01:00
parent d25d327ef7
commit 430f0d07e8
8 changed files with 186 additions and 9 deletions

View File

@@ -18,7 +18,7 @@ function AppFlowRow(props: AppFlowRowProps) {
return (
<>
<Card sx={{ my: 2 }}>
<CardActionArea component={Link} to={URLS.FLOW('dummy')}>
<CardActionArea component={Link} to={URLS.FLOW(flow.id)}>
<CardContent>
<Box>
<Typography variant="h6" noWrap>

View File

@@ -0,0 +1,38 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import Card from '@mui/material/Card';
import Box from '@mui/material/Box';
import CardActionArea from '@mui/material/CardActionArea';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import type { Flow } from 'types/flow';
import * as URLS from 'config/urls';
import { CardContent, Typography } from './style';
type FlowRowProps = {
flow: Flow;
}
export default function FlowRow(props: FlowRowProps) {
const { flow } = props;
return (
<Link to={URLS.FLOW(flow.id)}>
<Card sx={{ mb: 1 }}>
<CardActionArea>
<CardContent>
<Box>
<Typography variant="h6" noWrap>
{flow.name}
</Typography>
</Box>
<Box>
<ArrowForwardIosIcon sx={{ color: (theme) => theme.palette.primary.main }} />
</Box>
</CardContent>
</CardActionArea>
</Card>
</Link>
);
}

View File

@@ -0,0 +1,27 @@
import { styled } from '@mui/material/styles';
import MuiCardContent from '@mui/material/CardContent';
import MuiTypography from '@mui/material/Typography';
export const CardContent = styled(MuiCardContent)(({ theme }) => ({
display: 'grid',
gridTemplateRows: 'auto',
gridTemplateColumns: '1fr auto',
gridColumnGap: theme.spacing(2),
alignItems: 'center',
}));
export const Typography = styled(MuiTypography)(({ theme }) => ({
'&.MuiTypography-h6': {
textTransform: 'capitalize',
},
display: 'inline-block',
width: 500,
maxWidth: '70%',
}));
export const DesktopOnlyBreakline = styled('br')(({ theme }) => ({
[theme.breakpoints.down('sm')]: {
display: 'none',
}
}));

View File

@@ -1,9 +1,9 @@
export const DASHBOARD = '/dashboard';
export const APPS = '/apps';
export const CONNECTIONS = '/connections';
export const FLOWS = '/flows';
export const EXPLORE = '/explore';
export const EDITOR = '/editor';
export const APPS = '/apps';
export const NEW_APP_CONNECTION = '/apps/new';
export const APP = (appKey: string) => `/app/${appKey}`;
export const APP_PATTERN = '/app/:appKey';
export const APP_CONNECTIONS = (appKey: string) => `/app/${appKey}/connections`;
@@ -14,8 +14,11 @@ export const APP_RECONNECT_CONNECTION = (appKey: string, connectionId: string) =
export const APP_RECONNECT_CONNECTION_PATTERN = '/app/:appKey/connections/:connectionId/reconnect';
export const APP_FLOWS = (appKey: string) => `/app/${appKey}/flows`;
export const APP_FLOWS_PATTERN = '/app/:appKey/flows';
export const NEW_APP_CONNECTION = '/apps/new';
export const EDITOR = '/editor';
export const CREATE_FLOW = '/editor/create';
export const FLOW_EDITOR = (flowId: string) => `/editor/${flowId}`;
export const FLOWS = '/flows';
export const FLOW = (flowId: string) => `/flows/${flowId}`;
export const FLOW_PATTERN = '/flows/:flowId';

View File

@@ -1,7 +1,6 @@
{
"brandText": "Automatisch",
"searchPlaceholder": "Search",
"welcomeText": "Here comes the dashboard homepage.",
"drawer.dashboard": "Dashboard",
"drawer.flows": "Flows",
"drawer.apps": "My Apps",
@@ -15,7 +14,7 @@
"app.noConnections": "You don't have any connections yet.",
"app.flows": "Flows",
"app.noFlows": "You don't have any flows yet.",
"apps.title": "My Apps",
"apps.title": "Apps",
"apps.addConnection": "Add connection",
"apps.addNewAppConnection": "Add a new app connection",
"apps.searchApp": "Search for app",
@@ -34,5 +33,7 @@
"flow.active": "Enabled",
"flow.inactive": "Disabled",
"flowStep.triggerType": "Trigger",
"flowStep.actionType": "Action"
"flowStep.actionType": "Action",
"flows.create": "Create flow",
"flows.title": "Flows"
}

View File

@@ -0,0 +1,45 @@
import * as React from 'react';
import { useQuery } from '@apollo/client';
import { Link, Route, Navigate, Routes, useParams, useMatch, useNavigate } from 'react-router-dom';
import type { LinkProps } from 'react-router-dom';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import AddIcon from '@mui/icons-material/Add';
import useFormatMessage from 'hooks/useFormatMessage';
import { GET_APP } from 'graphql/queries/get-app';
import * as URLS from 'config/urls';
import ConditionalIconButton from 'components/ConditionalIconButton';
import AppConnections from 'components/AppConnections';
import AppFlows from 'components/AppFlows';
import AddAppConnection from 'components/AddAppConnection';
import AppIcon from 'components/AppIcon';
import Container from 'components/Container';
import PageTitle from 'components/PageTitle';
type ApplicationParams = {
flowId: string;
};
export default function Flow() {
const { flowId } = useParams() as ApplicationParams;
return (
<>
<Box sx={{ py: 3 }}>
<Container>
<Grid container>
<Grid item xs>
{flowId}
</Grid>
</Grid>
</Container>
</Box>
</>
);
};

View File

@@ -1,11 +1,71 @@
import * as React from 'react';
import { Link, Routes, Route, useNavigate } from 'react-router-dom';
import type { LinkProps } from 'react-router-dom';
import { useQuery } from '@apollo/client';
import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
import AddIcon from '@mui/icons-material/Add';
import FlowRow from 'components/FlowRow';
import ConditionalIconButton from 'components/ConditionalIconButton';
import Container from 'components/Container';
import PageTitle from 'components/PageTitle';
import SearchInput from 'components/SearchInput';
import useFormatMessage from 'hooks/useFormatMessage'
import { GET_FLOWS } from 'graphql/queries/get-flows';
import * as URLS from 'config/urls';
import type { Flow } from 'types/flow';
export default function Flows() {
const formatMessage = useFormatMessage();
const [flowName, setFlowName] = React.useState('');
const { data } = useQuery(GET_FLOWS);
const flows: Flow[] = data?.getFlows?.filter((flow: Flow) => flow.name?.toLowerCase().includes(flowName.toLowerCase()));
const onSearchChange = React.useCallback((event) => {
setFlowName(event.target.value);
}, []);
const CreateFlowLink = React.useMemo(
() =>
React.forwardRef<HTMLAnchorElement, Omit<LinkProps, 'to'>>(function InlineLink(
linkProps,
ref,
) {
return <Link ref={ref} to={URLS.CREATE_FLOW} {...linkProps} />;
}),
[],
);
return (
<Box sx={{ py: 3 }}>
<Container>
Flows
<Grid container sx={{ mb: [2, 5] }} columnSpacing={1.5} rowSpacing={3}>
<Grid container item xs sm alignItems="center" order={{ xs: 0 }}>
<PageTitle>{formatMessage('flows.title')}</PageTitle>
</Grid>
<Grid item xs={12} sm="auto" order={{ xs: 2, sm: 1 }}>
<SearchInput onChange={onSearchChange} />
</Grid>
<Grid container item xs="auto" sm="auto" alignItems="center" order={{ xs: 1, sm: 2 }}>
<ConditionalIconButton
type="submit"
variant="contained"
color="primary"
size="large"
component={CreateFlowLink}
fullWidth
icon={<AddIcon />}
>
{formatMessage('flows.create')}
</ConditionalIconButton>
</Grid>
</Grid>
{flows?.map((flow) => (<FlowRow key={flow.id} flow={flow} />))}
</Container>
</Box>
);

View File

@@ -3,6 +3,7 @@ import Layout from 'components/Layout';
import Applications from 'pages/Applications';
import Application from 'pages/Application';
import Flows from 'pages/Flows';
import Flow from 'pages/Flow';
import Explore from 'pages/Explore';
import EditorRoutes from 'pages/Editor/routes';
import * as URLS from 'config/urls';
@@ -11,6 +12,8 @@ export default (
<Routes>
<Route path={URLS.FLOWS} element={<Layout><Flows /></Layout>} />
<Route path={`${URLS.FLOW_PATTERN}/*`} element={<Layout><Flow /></Layout>} />
<Route path={`${URLS.APPS}/*`} element={<Layout><Applications /></Layout>} />
<Route path={URLS.EXPLORE} element={<Layout><Explore /></Layout>} />