feat: Introduce adding a new app connection

This commit is contained in:
Ali BARIN
2021-10-17 15:50:42 +02:00
parent 084a831e7a
commit a1363f7fdd
11 changed files with 126 additions and 13 deletions

View File

@@ -3,7 +3,7 @@
"private": true,
"scripts": {
"start": "lerna run --stream --scope=@*/{web,backend} dev",
"start:web": "lerna run --stream --scope @*/web start",
"start:web": "lerna run --stream --scope @*/web dev",
"start:backend": "lerna run --stream --scope @*/backend dev"
},
"workspaces": [

View File

@@ -0,0 +1,66 @@
import { useCallback, useState } from 'react';
import { useQuery } from '@apollo/client';
import { Link } from 'react-router-dom';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import Dialog from '@mui/material/Dialog';
import TextField from '@mui/material/TextField';
import SearchIcon from '@mui/icons-material/Search';
import InputAdornment from '@mui/material/InputAdornment';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import * as URLS from 'config/urls';
import AppIcon from 'components/AppIcon';
import type { App } from 'types/app';
import { GET_APPS } from 'graphql/queries/get-apps';
import useFormatMessage from 'hooks/useFormatMessage';
type AddNewAppConnectionProps = {
onClose: () => void;
};
export default function AddNewAppConnection(props: AddNewAppConnectionProps){
const { onClose } = props;
const formatMessage = useFormatMessage();
const [appName, setAppName] = useState<string | null>(null);
const { data } = useQuery(GET_APPS, { variables: {name: appName } });
return (
<Dialog open={true} onClose={onClose} maxWidth="sm" fullWidth>
<DialogTitle>{formatMessage('apps.addNewAppConnection')}</DialogTitle>
<DialogContent>
<TextField
fullWidth
variant="filled"
label={formatMessage('apps.searchApp')}
onChange={(event) => setAppName(event.target.value)}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
<List>
{data?.getApps?.map((app: App) => (
<ListItem disablePadding key={app.name}>
<ListItemButton component={Link} to={URLS.APP_ADD_CONNECTION(app.name.toLowerCase())}>
<ListItemIcon>
<AppIcon color={app.primaryColor} url={app.iconUrl} name={app.name} />
</ListItemIcon>
<ListItemText primary={app.name} />
</ListItemButton>
</ListItem>
))}
</List>
</DialogContent>
</Dialog>
);
};

View File

@@ -14,7 +14,7 @@ type AppRowProps = {
application: App;
}
const countTranslation = (value: React.ReactNode) => (<><strong>{value}</strong><DesktopOnlyBreakline /></>);
const countTranslation = (value: React.ReactNode) => (<><strong>{value}</strong><br /></>);
function AppRow(props: AppRowProps) {
const formatMessage = useFormatMessage();

View File

@@ -20,7 +20,7 @@ export const Typography = styled(MuiTypography)(({ theme }) => ({
}));
export const DesktopOnlyBreakline = styled('br')(({ theme }) => ({
[theme.breakpoints.down('md')]: {
[theme.breakpoints.down('sm')]: {
display: 'none',
}
}));

View File

@@ -10,3 +10,5 @@ export const APP_ADD_CONNECTION = (appSlug: string) => `/app/${appSlug}/connecti
export const APP_ADD_CONNECTION_PATTERN = '/app/:slug/connections/add';
export const APP_FLOWS = (appSlug: string) => `/app/${appSlug}/flows`;
export const APP_FLOWS_PATTERN = '/app/:slug/flows';
export const NEW_APP_CONNECTION = '/apps/new';

View File

@@ -0,0 +1,11 @@
import { InMemoryCache } from '@apollo/client';
const cache = new InMemoryCache({
typePolicies: {
App: {
keyFields: ['key']
}
}
});
export default cache;

View File

@@ -1,7 +1,7 @@
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { ApolloClient } from '@apollo/client';
import cache from './cache';
import appConfig from 'config/app';
const cache = new InMemoryCache();
const client = new ApolloClient({
uri: appConfig.graphqlUrl,
cache

View File

@@ -3,6 +3,7 @@ import { gql } from '@apollo/client';
export const GET_APPS = gql`
query GetApps($name: String) {
getApps(name: $name) {
key
name
iconUrl
docUrl

View File

@@ -11,5 +11,9 @@
"app.addConnection": "Add connection",
"app.settings": "Settings",
"app.connections": "Connections",
"app.flows": "Flows"
"app.flows": "Flows",
"apps.title": "Apps",
"apps.addConnection": "Add connection",
"apps.addNewAppConnection": "Add a new app connection",
"apps.searchApp": "Search for app"
}

View File

@@ -1,17 +1,23 @@
import { useCallback, useState } from 'react';
import { Link, Route, useHistory } from 'react-router-dom';
import { useQuery } from '@apollo/client';
import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import Container from 'components/Container';
import AddNewAppConnection from 'components/AddNewAppConnection';
import PageTitle from 'components/PageTitle';
import AppRow from 'components/AppRow';
import SearchInput from 'components/SearchInput';
import * as URLS from 'config/urls';
import useFormatMessage from 'hooks/useFormatMessage'
import { GET_APPS } from 'graphql/queries/get-apps';
import * as URLS from 'config/urls';
import type { App } from 'types/app';
export default function Applications() {
const history = useHistory();
const formatMessage = useFormatMessage();
const [appName, setAppName] = useState(null);
const { data } = useQuery(GET_APPS, { variables: {name: appName } });
@@ -19,22 +25,45 @@ export default function Applications() {
setAppName(event.target.value);
}, []);
const goToApps = useCallback(() => {
history.push(URLS.APPS);
}, [history]);
return (
<Box sx={{ py: 3 }}>
<Container>
<Grid container sx={{ mb: 3 }}>
<Grid item xs={6}>
<PageTitle>Applications</PageTitle>
<Grid container sx={{ mb: 3 }} spacing={1}>
<Grid item xs={12} sm>
<PageTitle>{formatMessage('apps.title')}</PageTitle>
</Grid>
<Grid container item xs={6} justifyContent="flex-end">
<SearchInput onChange={onSearchChange} />
<Grid container item xs={12} sm="auto" justifyContent="flex-end" spacing={2}>
<Grid item xs={12} sm="auto">
<SearchInput onChange={onSearchChange} />
</Grid>
<Grid item xs={12} sm="auto">
<Button
type="submit"
variant="contained"
color="primary"
component={Link}
to={URLS.NEW_APP_CONNECTION}
fullWidth
>
{formatMessage('apps.addConnection')}
</Button>
</Grid>
</Grid>
</Grid>
{data?.getApps?.map((app: App) => (
<AppRow key={app.name} application={app} />
))}
<Route exact path={URLS.NEW_APP_CONNECTION}>
<AddNewAppConnection onClose={goToApps} />
</Route>
</Container>
</Box>
);

View File

@@ -16,7 +16,7 @@ export default (
<Flows />
</Route>
<Route path={URLS.APPS}>
<Route path={[URLS.APPS, URLS.NEW_APP_CONNECTION]}>
<Applications />
</Route>