feat: add app connections w/ testing and deleting functions

This commit is contained in:
Ali BARIN
2021-10-18 23:58:40 +02:00
parent 672cc4c60c
commit 2293c939e7
27 changed files with 349 additions and 34 deletions

View File

@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useState } from 'react';
import { useQuery } from '@apollo/client';
import { Link } from 'react-router-dom';
import DialogTitle from '@mui/material/DialogTitle';

View File

@@ -0,0 +1,57 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import Menu from '@mui/material/Menu';
import type { PopoverProps } from '@mui/material/Popover';
import MenuItem from '@mui/material/MenuItem';
import * as URLS from 'config/urls';
import useFormatMessage from 'hooks/useFormatMessage';
type Action = {
type: 'test' | 'reconnect' | 'delete' | 'viewFlows';
};
type ContextMenuProps = {
appKey: string;
onClose: () => void;
onMenuItemClick: (event: React.MouseEvent, action: Action) => void;
anchorEl: PopoverProps['anchorEl'];
};
export default function ContextMenu(props: ContextMenuProps) {
const { appKey, onClose, onMenuItemClick, anchorEl } = props;
const formatMessage = useFormatMessage();
const createActionHandler = React.useCallback((action: Action) => {
return function clickHandler(event: React.MouseEvent) {
onMenuItemClick(event, action);
onClose();
};
}, [onMenuItemClick, onClose]);
return (
<Menu
open={true}
onClose={onClose}
hideBackdrop={false}
anchorEl={anchorEl}
>
<MenuItem component={Link} to={URLS.APP_FLOWS(appKey)} onClick={createActionHandler({ type: 'viewFlows' })}>
{formatMessage('connection.viewFlows')}
</MenuItem>
<MenuItem onClick={createActionHandler({ type: 'test' })}>
{formatMessage('connection.testConnection')}
</MenuItem>
<MenuItem onClick={createActionHandler({ type: 'reconnect' })}>
{formatMessage('connection.reconnect')}
</MenuItem>
<MenuItem onClick={createActionHandler({ type: 'delete' })}>
{formatMessage('connection.delete')}
</MenuItem>
</Menu>
);
};

View File

@@ -0,0 +1,94 @@
import * as React from 'react';
import { useLazyQuery, useMutation } from '@apollo/client';
import Card from '@mui/material/Card';
import Box from '@mui/material/Box';
import CardActionArea from '@mui/material/CardActionArea';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
import { DELETE_CONNECTION } from 'graphql/mutations/delete-connection';
import { TEST_CONNECTION } from 'graphql/queries/test-connection';
import ConnectionContextMenu from 'components/AppConnectionContextMenu';
import useFormatMessage from 'hooks/useFormatMessage';
import type { Connection } from 'types/connection';
import { CardContent, Typography } from './style';
type AppConnectionRowProps = {
connection: Connection;
}
const countTranslation = (value: React.ReactNode) => (<><strong>{value}</strong><br /></>);
function AppConnectionRow(props: AppConnectionRowProps) {
const [testConnection, { data: testData, called: testCalled, loading: testLoading }] = useLazyQuery(TEST_CONNECTION);
const [deleteConnection] = useMutation(DELETE_CONNECTION);
const formatMessage = useFormatMessage();
const { id, key, data } = props.connection;
const contextButtonRef = React.useRef<SVGSVGElement | null>(null);
const [anchorEl, setAnchorEl] = React.useState<SVGSVGElement | null>(null);
const handleClose = () => {
setAnchorEl(null);
};
const onContextMenuClick = (event: React.MouseEvent<HTMLButtonElement>) => setAnchorEl(contextButtonRef.current);
const onContextMenuAction = React.useCallback((event, action: { [key: string]: string }) => {
if (action.type === 'delete') {
deleteConnection({
variables: { id },
update: (cache, mutationResult) => {
const connectionCacheId = cache.identify({
__typename: 'connection',
id,
});
cache.evict({
id: connectionCacheId,
});
}
});
} else if (action.type === 'test') {
testConnection({ variables: { id } });
}
}, [deleteConnection, id, testConnection]);
return (
<>
<Card sx={{ my: 2 }}>
<CardActionArea onClick={onContextMenuClick}>
<CardContent>
<Box>
<Typography variant="h6">
{data.screenName}
</Typography>
</Box>
<Box>
{testCalled && !testLoading && (testData ? 'yes' : 'no')}
</Box>
<Box sx={{ px: 2 }}>
<Typography variant="body2">
{formatMessage('connection.flowCount', { count: countTranslation(0) })}
</Typography>
</Box>
<Box>
<MoreHorizIcon ref={contextButtonRef} />
</Box>
</CardContent>
</CardActionArea>
</Card>
{anchorEl && <ConnectionContextMenu
appKey={key}
onClose={handleClose}
onMenuItemClick={onContextMenuAction}
anchorEl={anchorEl}
/>}
</>
);
}
export default AppConnectionRow;

View File

@@ -0,0 +1,17 @@
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 auto auto',
gridColumnGap: theme.spacing(2),
alignItems: 'center',
}));
export const Typography = styled(MuiTypography)(({ theme }) => ({
textAlign: 'center',
display: 'inline-block',
}));

View File

@@ -0,0 +1,23 @@
import { useQuery } from '@apollo/client';
import { GET_APP_CONNECTIONS } from 'graphql/queries/get-app-connections';
import AppConnectionRow from 'components/AppConnectionRow';
import type { Connection } from 'types/connection';
type AppConnectionsProps = {
appKey: String;
}
export default function AppConnections(props: AppConnectionsProps) {
const { appKey: key } = props;
const { data } = useQuery(GET_APP_CONNECTIONS, { variables: { key } });
const appConnections: Connection[] = data?.getApp?.connections || [];
return (
<>
{appConnections.map((appConnection: Connection) => (
<AppConnectionRow key={appConnection.id} connection={appConnection} />
))}
</>
)
};

View File

@@ -24,7 +24,7 @@ function AppRow(props: AppRowProps) {
<Link to={URLS.APP(name.toLowerCase())}>
<Card sx={{ my: 2 }}>
<CardActionArea>
<CardContent>
<CardContent>
<Box>
<AppIcon name={name} url={iconUrl} color={primaryColor} />
</Box>

View File

@@ -19,12 +19,10 @@ export default function InputCreator(props: InputCreatorProps) {
const {
key: name,
label,
type,
required,
readOnly,
value,
description,
docUrl,
clickToCopy,
} = schema;

View File

@@ -9,7 +9,7 @@ type LayoutProps = {
}
export default function Layout({ children }: LayoutProps) {
const [isDrawerOpen, setDrawerOpen] = useState(false);
const [isDrawerOpen, setDrawerOpen] = useState(true);
const onMenuClick = useCallback(() => { setDrawerOpen(value => !value) }, []);
return (