Added Delete Cluster Feature For Targets (#2334)

* delete target

Signed-off-by: Oum Kale <oum.kale@mayadata.io>

* delete cluster

Signed-off-by: Oum Kale <oum.kale@mayadata.io>

* delete cluster

Signed-off-by: Oum Kale <oum.kale@mayadata.io>

* delete cluster

Signed-off-by: Oum Kale <oum.kale@mayadata.io>

* delete cluster

Signed-off-by: Oum Kale <oum.kale@mayadata.io>

* delete cluster

Signed-off-by: Oum Kale <oum.kale@mayadata.io>

* delete cluster

Signed-off-by: Oum Kale <oum.kale@mayadata.io>
This commit is contained in:
OUM NIVRATHI KALE 2020-11-11 23:02:26 +05:30 committed by GitHub
parent e7c03012cf
commit c9793f8efe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 295 additions and 58 deletions

View File

@ -460,6 +460,15 @@ targets:
head4: 4.Click on the button
head5: Connect the target
conformation: Kuberenetes Agent is confirming, Please wait...
clusterDetails: Cluster Details
modalDelete:
head1: Are you sure to
head2: remove the current Agent?
head3: It will be removed forever
delete: Delete
yes: Yes
no: No
connectTargets:
title: A new Target,

View File

@ -1,14 +1,19 @@
import { Typography } from '@material-ui/core';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useMutation } from '@apollo/client';
import { history } from '../../../redux/configureStore';
import ButtonOutline from '../../Button/ButtonOutline';
// import BrowseWorkflow from '../TargetHome/BrowseWorkflow';
import useStyles from './styles';
import Scaffold from '../../../containers/layouts/Scaffold';
import TargetCopy from '../TargetCopy';
import { Cluster } from '../../../models/graphql/clusterData';
import { Cluster, DeleteCluster } from '../../../models/graphql/clusterData';
import { LocationState } from '../../../models/routerModel';
import { DELETE_CLUSTER } from '../../../graphql';
import Unimodal from '../../../containers/layouts/Unimodal';
import ButtonFilled from '../../Button/ButtonFilled';
import BackButton from '../../Button/BackButton';
interface ClusterProps {
data: Cluster;
@ -21,7 +26,12 @@ const ClusterInfo: React.FC<ClusterVarsProps> = ({ location }) => {
const { data } = location.state;
const classes = useStyles();
const link: string = data.token;
const handleClick = () => {
const [deleteCluster] = useMutation<DeleteCluster>(DELETE_CLUSTER);
const [open, setOpen] = React.useState(false);
const handleDelete = () => {
deleteCluster({ variables: { cluster_id: data.cluster_id } });
history.push('/targets');
};
@ -31,9 +41,9 @@ const ClusterInfo: React.FC<ClusterVarsProps> = ({ location }) => {
<Scaffold>
<section className="Header section">
<div className={classes.backBotton}>
<ButtonOutline isDisabled={false} handleClick={handleClick}>
<BackButton isDisabled={false}>
<div>{t('workflowCluster.header.formControl.back')}</div>
</ButtonOutline>
</BackButton>
<div className={classes.header}>
<Typography variant="h4">
{t('workflowCluster.header.formControl.clusterInfo')}
@ -46,32 +56,47 @@ const ClusterInfo: React.FC<ClusterVarsProps> = ({ location }) => {
<div className={classes.detailsDiv}>
{/* name */}
<div className={classes.firstCol}>
<div className={classes.status}>
<div className={classes.checkCluster}>
<Typography variant="h6">
<strong>Cluster Details</strong>
</Typography>
<div className={classes.linkBox}>
<div className={classes.status}>
<div>
<Typography variant="h6">
<strong>{t('targets.newTarget.clusterDetails')}</strong>
</Typography>
</div>
<div>
{data.is_active ? (
<Typography
className={`${classes.check} ${classes.active}`}
>
{t('workflowCluster.header.formControl.menu1')}
</Typography>
) : data.is_cluster_confirmed === false ? (
<Typography
className={`${classes.check} ${classes.pending}`}
>
{t('workflowCluster.header.formControl.menu6')}
</Typography>
) : (
<Typography
className={`${classes.check} ${classes.notactive}`}
>
{t('workflowCluster.header.formControl.menu2')}
</Typography>
)}
</div>
</div>
<div>
{data.is_active ? (
<Typography
className={`${classes.check} ${classes.active}`}
>
{t('workflowCluster.header.formControl.menu1')}
</Typography>
) : data.is_cluster_confirmed === false ? (
<Typography
className={`${classes.check} ${classes.pending}`}
>
{t('workflowCluster.header.formControl.menu6')}
</Typography>
) : (
<Typography
className={`${classes.check} ${classes.notactive}`}
>
{t('workflowCluster.header.formControl.menu2')}
</Typography>
)}
<div className={classes.buttonBox}>
<ButtonOutline
isDisabled={false}
handleClick={() => {
setOpen(true);
}}
>
<div className={classes.status}>
<img src="/icons/bin-red.svg" alt="Delete" />
<div> {t('targets.modalDelete.delete')} </div>
</div>
</ButtonOutline>
</div>
</div>
</div>
@ -97,18 +122,58 @@ const ClusterInfo: React.FC<ClusterVarsProps> = ({ location }) => {
<Typography>{t('targets.newTarget.head1')}</Typography>
<Typography>{t('targets.newTarget.head2')}</Typography>
<Typography>{t('targets.newTarget.head3')}</Typography>
{/*
<Typography>
{t('targets.newTarget.head4')}{' '}
<strong>{t('targets.newTarget.head5')}</strong>
</Typography>
*/}
</div>
<div className={classes.rightMargin}>
{link && <TargetCopy yamlLink={link} />}
</div>
</div>
</div>
<div>
{open ? (
<div>
<Unimodal
open={open}
handleClose={() => {
setOpen(false);
}}
hasCloseBtn
>
<div className={classes.body}>
<img src="/icons/bin-red-delete.svg" alt="Delete" />
<div className={classes.text}>
<Typography className={classes.typo} align="center">
{t('targets.modalDelete.head1')} <br />
<strong> {t('targets.modalDelete.head2')}</strong>
</Typography>
</div>
<div className={classes.textSecond}>
<Typography className={classes.typoSub} align="center">
{t('targets.modalDelete.head3')}
</Typography>
</div>
<div className={classes.buttonGroup}>
<ButtonOutline
isDisabled={false}
handleClick={() => {
setOpen(false);
}}
>
<> {t('targets.modalDelete.no')}</>
</ButtonOutline>
<ButtonFilled
isDisabled={false}
isPrimary
handleClick={handleDelete}
>
<>{t('targets.modalDelete.yes')}</>
</ButtonFilled>
</div>
</div>
</Unimodal>
</div>
) : null}
</div>
</div>
</section>
</Scaffold>

View File

@ -36,9 +36,7 @@ const useStyles = makeStyles((theme) => ({
paddingTop: theme.spacing(5),
marginLeft: theme.spacing(2),
},
checkCluster: {
marginRight: theme.spacing(2),
},
version: {
marginTop: theme.spacing(2),
},
@ -48,9 +46,20 @@ const useStyles = makeStyles((theme) => ({
marginLeft: theme.spacing(5),
marginTop: theme.spacing(4),
},
linkBox: {
backgroundColor: theme.palette.common.white,
paddingRight: theme.spacing(9),
display: 'flex',
flexDirection: 'row',
width: '100%',
wordWrap: 'break-word',
justifyContent: 'space-between',
},
status: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
gap: '1rem',
},
expDiv: {
display: 'flex',
@ -68,6 +77,10 @@ const useStyles = makeStyles((theme) => ({
rightMargin: {
marginRight: theme.spacing(8),
},
buttonBox: {
display: 'flex',
paddingLeft: theme.spacing(4),
},
connectdevice: {
fontSize: '1rem',
lineHeight: '175%',
@ -102,6 +115,39 @@ const useStyles = makeStyles((theme) => ({
background: theme.palette.customColors.menuOption.pending,
color: theme.palette.warning.main,
},
body: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
marginTop: theme.spacing(7.5),
},
// styles for text
text: {
width: '31.93rem',
height: '5.875rem',
marginTop: theme.spacing(3.75),
marginBottom: theme.spacing(3.75),
},
typo: {
fontSize: '2rem',
},
textSecond: {
width: '29.06rem',
height: '1.6875rem',
marginTop: theme.spacing(1.875),
marginBottom: theme.spacing(3.75),
},
typoSub: {
fontSize: '1rem',
},
// for yes or no buttons
buttonGroup: {
display: 'flex',
gap: '1rem',
marginTop: theme.spacing(2.5),
justifyContent: 'space-between',
},
}));
export default useStyles;

View File

@ -18,6 +18,7 @@ import { RootState } from '../../../redux/reducers';
import Loader from '../../Loader';
import ButtonFilled from '../../Button/ButtonFilled';
import Unimodal from '../../../containers/layouts/Unimodal';
import BackButton from '../../Button/BackButton';
const ConnectTarget = () => {
const classes = useStyles();
@ -26,10 +27,6 @@ const ConnectTarget = () => {
const [id, setID] = React.useState('');
const [modal, setModal] = React.useState(false);
const handleClick = () => {
history.push('/targets');
};
const selectedProjectID = useSelector(
(state: RootState) => state.userData.selectedProjectID
);
@ -71,6 +68,10 @@ const ConnectTarget = () => {
project_id: selectedProjectID,
cluster_type: 'external',
agent_scope: 'cluster',
agent_namespace: '',
serviceaccount: '',
agent_sa_exists: false,
agent_ns_exists: false,
};
createClusterReg({
variables: { ClusterInput: createClusterInput },
@ -87,13 +88,9 @@ const ConnectTarget = () => {
<Scaffold>
<section className="Header section">
<div className={classes.backBotton}>
<ButtonOutline
isDisabled={false}
handleClick={handleClick}
data-cy="backSelect"
>
<BackButton isDisabled={false}>
<Typography>Back</Typography>
</ButtonOutline>
</BackButton>
<div className={classes.header}>
<Typography variant="h4">
{t('targets.connectHome.connectText')}
@ -140,7 +137,9 @@ const ConnectTarget = () => {
<div>
<Unimodal
open={modal}
handleClose={handleClick}
handleClose={() => {
history.push('/targets');
}}
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
hasCloseBtn

View File

@ -97,3 +97,9 @@ export const SYNC_REPO = gql`
}
}
`;
export const DELETE_CLUSTER = gql`
mutation deleteCluster($cluster_id: String!) {
deleteClusterReg(cluster_id: $cluster_id)
}
`;

View File

@ -121,6 +121,11 @@ export const GET_CLUSTER = gql`
no_of_schedules
no_of_workflows
token
agent_namespace
serviceaccount
agent_scope
agent_ns_exists
agent_sa_exists
}
}
`;

View File

@ -2,7 +2,7 @@ export interface Cluster {
cluster_id: string;
project_id: string;
cluster_name: string;
description: String;
description: string;
platform_name: string;
access_key: string;
is_registered: boolean;
@ -14,6 +14,11 @@ export interface Cluster {
no_of_workflows: number;
no_of_schedules: number;
token: string;
agent_namespace: string;
serviceaccount: string;
agent_scope: string;
agent_ns_exists: boolean;
agent_sa_exists: boolean;
}
export interface Clusters {
@ -27,7 +32,11 @@ export interface CreateClusterInput {
platform_name: string;
project_id: string;
cluster_type: string;
agent_namespace: string;
serviceaccount: string;
agent_scope: string;
agent_ns_exists: boolean;
agent_sa_exists: boolean;
};
}
@ -43,4 +52,9 @@ export interface CreateClusterInputResponse {
export interface ClusterVars {
project_id: string;
cluster_type: string;
}
export interface DeleteCluster {
cluster_id: string;
}

View File

@ -6,12 +6,16 @@ import useStyles from './styles';
import { Cluster } from '../../../models/graphql/clusterData';
import { history } from '../../../redux/configureStore';
import timeDifferenceForDate from '../../../utils/datesModifier';
import Unimodal from '../../../containers/layouts/Unimodal';
import ButtonFilled from '../../../components/Button/ButtonFilled';
import ButtonOutline from '../../../components/Button/ButtonOutline';
interface TableDataProps {
data: Cluster;
deleteRow: (clid: string) => void;
}
const TableData: React.FC<TableDataProps> = ({ data }) => {
const TableData: React.FC<TableDataProps> = ({ data, deleteRow }) => {
const classes = useStyles();
const { t } = useTranslation();
@ -22,6 +26,18 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
if (date) return resDate;
return 'Date not available';
};
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(true);
};
const handleClose = () => {
deleteRow(data.cluster_id);
setOpen(false);
};
return (
<>
<TableCell className={classes.tableDataStatus}>
@ -62,6 +78,64 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
<Typography>{data.no_of_workflows}</Typography>
</TableCell>
<TableCell>{timeDifferenceForDate(data.updated_at)}</TableCell>
<TableCell>
<div className={classes.deleteCluster}>
<div>
<IconButton onClick={handleClick}>
<img alt="delete" src="./icons/bin-red.svg" />
</IconButton>
</div>
<div>
<Typography>{t('targets.modalDelete.delete')}</Typography>
</div>
</div>
<div>
{open ? (
<div>
<Unimodal
open={open}
handleClose={() => {
setOpen(false);
}}
hasCloseBtn
>
<div className={classes.body}>
<img src="/icons/bin-red-delete.svg" alt="Delete" />
<div className={classes.text}>
<Typography className={classes.typo} align="center">
{t('targets.modalDelete.head1')} <br />
<strong> {t('targets.modalDelete.head2')}</strong>
</Typography>
</div>
<div className={classes.textSecond}>
<Typography className={classes.typoSub} align="center">
{t('targets.modalDelete.head3')}
</Typography>
</div>
<div className={classes.buttonGroup}>
<ButtonOutline
isDisabled={false}
handleClick={() => {
setOpen(false);
}}
>
<> {t('targets.modalDelete.no')}</>
</ButtonOutline>
<ButtonFilled
isDisabled={false}
isPrimary
handleClick={handleClose}
>
<>{t('targets.modalDelete.yes')}</>
</ButtonFilled>
</div>
</div>
</Unimodal>
</div>
) : null}
</div>
</TableCell>
</>
);
};

View File

@ -13,11 +13,11 @@ import {
import moment from 'moment';
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { useQuery } from '@apollo/client';
import { useMutation, useQuery } from '@apollo/client';
import { useTranslation } from 'react-i18next';
import HeaderSection from './HeaderSection';
import useStyles from './styles';
import { GET_CLUSTER } from '../../../graphql';
import { GET_CLUSTER, DELETE_CLUSTER } from '../../../graphql';
import Loader from '../../../components/Loader';
import { RootState } from '../../../redux/reducers';
import TableData from './TableData';
@ -31,6 +31,7 @@ import {
Cluster,
ClusterVars,
Clusters,
DeleteCluster,
} from '../../../models/graphql/clusterData';
interface FilterOptions {
@ -73,12 +74,16 @@ const BrowseCluster = () => {
{
variables: {
project_id: selectedProjectID,
cluster_type: 'external',
},
fetchPolicy: 'cache-and-network',
pollInterval: 3000,
}
);
// Apollo mutation to delete the selected Target Cluster
const [deleteCluster] = useMutation<DeleteCluster>(DELETE_CLUSTER);
const [dateRange, setDateRange] = React.useState<DateData>({
dateValue: 'Select a period',
fromDate: new Date(0).toString(),
@ -205,6 +210,12 @@ const BrowseCluster = () => {
};
const { t } = useTranslation();
const deleteRow = (clid: string) => {
deleteCluster({
variables: { cluster_id: clid },
});
};
return (
<div>
<section className="Heading section">
@ -309,6 +320,15 @@ const BrowseCluster = () => {
</Typography>
</div>
</TableCell>
{/* Delete Cluster */}
<TableCell className={classes.headData}>
<div className={classes.tableCell}>
<Typography>
{t('workflowCluster.header.formControl.delete')}
</Typography>
</div>
</TableCell>
</TableRow>
</TableHead>
@ -316,13 +336,13 @@ const BrowseCluster = () => {
<TableBody>
{loading ? (
<TableRow>
<TableCell colSpan={6}>
<TableCell colSpan={7}>
<Loader />
</TableCell>
</TableRow>
) : error ? (
<TableRow>
<TableCell data-cy="browseClusterError" colSpan={6}>
<TableCell data-cy="browseClusterError" colSpan={7}>
<Typography align="center">
{t('workflowCluster.header.formControl.fetchingError')}
</Typography>
@ -341,7 +361,7 @@ const BrowseCluster = () => {
key={data.cluster_id}
className={classes.dataRow}
>
<TableData data={data} />
<TableData data={data} deleteRow={deleteRow} />
</TableRow>
))
) : (

View File

@ -213,10 +213,9 @@ const useStyles = makeStyles((theme) => ({
// for yes or no buttons
buttonGroup: {
display: 'flex',
width: '10.75rem',
height: '2.75rem',
marginTop: theme.spacing(2.5),
justifyContent: 'space-between',
gap: '1rem',
},
// delete user
delDiv: {

Binary file not shown.