feat: Introduce adding a new app connection
This commit is contained in:
@@ -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": [
|
||||
|
66
packages/web/src/components/AddNewAppConnection/index.tsx
Normal file
66
packages/web/src/components/AddNewAppConnection/index.tsx
Normal 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>
|
||||
);
|
||||
};
|
@@ -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();
|
||||
|
@@ -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',
|
||||
}
|
||||
}));
|
||||
|
@@ -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';
|
11
packages/web/src/graphql/cache.ts
Normal file
11
packages/web/src/graphql/cache.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { InMemoryCache } from '@apollo/client';
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
App: {
|
||||
keyFields: ['key']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default cache;
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
}
|
@@ -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>
|
||||
);
|
||||
|
@@ -16,7 +16,7 @@ export default (
|
||||
<Flows />
|
||||
</Route>
|
||||
|
||||
<Route path={URLS.APPS}>
|
||||
<Route path={[URLS.APPS, URLS.NEW_APP_CONNECTION]}>
|
||||
<Applications />
|
||||
</Route>
|
||||
|
||||
|
Reference in New Issue
Block a user