External Agent Graphql and Backend Integration with Table Section (#2211)
External Agent Graphql and Backend Integration with Table Section Signed-off-by: Oum Nivrathi Kale <oum.kale@mayadata.io>
This commit is contained in:
		
							parent
							
								
									a2f48cf031
								
							
						
					
					
						commit
						3036775fc8
					
				| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
<svg width="76" height="94" viewBox="0 0 76 94" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<path d="M17.6347 93.2451H17.6353L58.3139 93.2451L58.3144 93.2451C61.3158 93.2399 64.183 92.0006 66.2425 89.8176C68.3116 87.6409 69.4895 84.6152 69.4895 81.4026V28.6887C73.4971 27.4938 76.0674 23.5599 75.5234 19.3868L75.5234 19.3867C74.9671 15.1274 71.3384 11.9412 67.0424 11.9403H56.3745L56.3745 9.59475C56.3745 9.59452 56.3745 9.59429 56.3745 9.59406C56.3874 7.24329 55.4579 4.98607 53.7938 3.32548L53.7937 3.32542C52.1298 1.66582 49.8694 0.741539 47.5188 0.76038H28.4303C26.0798 0.741539 23.8194 1.66582 22.1554 3.32542L22.1554 3.32548C20.4914 4.98599 19.5618 7.24307 19.5746 9.59371V11.9403H8.90685H8.90678C4.61077 11.9412 0.982026 15.1274 0.425776 19.3867L0.425766 19.3868C-0.11825 23.5599 2.45202 27.4938 6.45969 28.6887V81.4026C6.45969 84.6153 7.63761 87.6411 9.70687 89.8178C11.7672 92.0007 14.6342 93.2399 17.6347 93.2451ZM24.5547 9.59285L24.5546 9.58852C24.5415 8.56106 24.9454 7.57206 25.6747 6.84659L25.6748 6.84646C26.4032 6.12122 27.3945 5.72258 28.4231 5.74032V5.74037H28.429L47.5202 5.74042L47.5261 5.74032C48.5547 5.72258 49.546 6.12122 50.2743 6.84646L50.2746 6.84672C51.0037 7.57122 51.4077 8.56096 51.3945 9.58852V9.59285V11.9403H24.5546L24.5547 9.59285ZM50.6599 34.0166C49.2846 34.0166 48.1699 35.1313 48.1699 36.5066V77.1416C48.1699 78.516 49.2845 79.6316 50.6599 79.6316C52.0353 79.6316 53.1499 78.516 53.1499 77.1416V36.5066C53.1499 35.1313 52.0352 34.0166 50.6599 34.0166ZM25.2894 34.0166C23.9141 34.0166 22.7994 35.1313 22.7994 36.5066V77.1416C22.7994 78.516 23.914 79.6316 25.2894 79.6316C26.6648 79.6316 27.7794 78.516 27.7794 77.1416V36.5066C27.7794 35.1313 26.6647 34.0166 25.2894 34.0166ZM58.3139 88.2651H17.6353C14.1776 88.2651 11.4397 85.2916 11.4397 81.4026V28.9603H64.5095V81.4026C64.5095 85.2916 61.7715 88.2651 58.3139 88.2651ZM8.90685 16.9203H67.0423C68.9919 16.9203 70.5723 18.5007 70.5723 20.4503C70.5723 22.3999 68.9919 23.9803 67.0423 23.9803H8.90685C6.95723 23.9803 5.37686 22.3999 5.37686 20.4503C5.37686 18.5007 6.95723 16.9203 8.90685 16.9203ZM37.9746 34.0166C36.5993 34.0166 35.4846 35.1313 35.4846 36.5066V77.1416C35.4846 78.516 36.5992 79.6316 37.9746 79.6316C39.35 79.6316 40.4646 78.516 40.4646 77.1416V36.5066C40.4646 35.1313 39.3499 34.0166 37.9746 34.0166Z" fill="#CA2C2C" stroke="#CA2C2C" stroke-width="0.68"/>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.3 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
<svg width="13" height="15" viewBox="0 0 13 15" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<path d="M3.50514 14.3007H3.50505C3.06379 14.3 2.64215 14.1177 2.33916 13.7967C2.03488 13.4766 1.86166 13.0316 1.86166 12.5592V4.80715C1.2723 4.63143 0.894318 4.05291 0.97432 3.43922L0.974321 3.43921C1.05612 2.81284 1.58976 2.34428 2.22153 2.34415H2.22154H3.79033V1.99908V1.99893H3.84033L3.50514 14.3007ZM3.50514 14.3007H9.48727H9.48736M3.50514 14.3007H9.48736M9.48736 14.3007C9.92873 14.3 10.3504 14.1177 10.6532 13.7967C10.9575 13.4766 11.1307 13.0316 11.1307 12.5592V4.80715C11.7201 4.63143 12.0981 4.05291 12.0181 3.43922L12.0181 3.43921M9.48736 14.3007L12.0181 3.43921M12.0181 3.43921C11.9363 2.81284 11.4026 2.34428 10.7709 2.34415H9.20208L12.0181 3.43921ZM8.82255 1.07725L8.82256 1.07726C9.06726 1.32145 9.20396 1.65337 9.20208 1.99904V1.99893H9.15208L9.20208 1.99921L8.82255 1.07725ZM8.82255 1.07725C8.57785 0.833194 8.24543 0.697271 7.89977 0.700042M8.82255 1.07725L7.89977 0.700042M5.09244 1.38239C4.92768 1.37955 4.76885 1.4434 4.65214 1.55962C4.5353 1.67584 4.47058 1.8343 4.47268 1.99893L5.09244 1.38239ZM5.09244 1.38239H7.89997H5.09244ZM7.89977 0.700042H7.89997V0.750042C8.23233 0.747324 8.55196 0.877994 8.78724 1.11266L7.89977 0.700042ZM7.89977 0.700042H5.09264H5.09244H7.89977ZM9.15208 2.34415V2.39415H9.20208L9.15208 2.34415ZM4.52268 1.99893H4.52269L4.52268 1.9983C4.52075 1.8472 4.58015 1.70176 4.6874 1.59507L4.68742 1.59505C4.79452 1.4884 4.9403 1.42978 5.09157 1.43238V1.43239H5.09244L7.89997 1.4324L7.90084 1.43238C8.05211 1.42978 8.19789 1.4884 8.30499 1.59505L8.30503 1.59509C8.41225 1.70164 8.47166 1.84718 8.46973 1.9983H8.46973V1.99893V2.34415H4.52268V1.99893ZM8.36169 5.59066C8.15944 5.59066 7.99551 5.75459 7.99551 5.95684V11.9326C7.99551 12.1347 8.15942 12.2988 8.36169 12.2988C8.56395 12.2988 8.72786 12.1347 8.72786 11.9326V5.95684C8.72786 5.75459 8.56394 5.59066 8.36169 5.59066ZM4.63074 5.59066C4.42849 5.59066 4.26456 5.75459 4.26456 5.95684V11.9326C4.26456 12.1347 4.42847 12.2988 4.63074 12.2988C4.833 12.2988 4.99692 12.1347 4.99692 11.9326V5.95684C4.99692 5.75459 4.83299 5.59066 4.63074 5.59066ZM9.48727 13.5684H3.50514C2.99665 13.5684 2.59401 13.1311 2.59401 12.5592V4.84709H10.3984V12.5592C10.3984 13.1311 9.99576 13.5684 9.48727 13.5684ZM2.22154 3.0765H10.7709C11.0576 3.0765 11.29 3.30891 11.29 3.59562C11.29 3.88233 11.0576 4.11474 10.7709 4.11474H2.22154C1.93483 4.11474 1.70242 3.88233 1.70242 3.59562C1.70242 3.30891 1.93483 3.0765 2.22154 3.0765ZM6.49621 5.59066C6.29396 5.59066 6.13004 5.75459 6.13004 5.95684V11.9326C6.13004 12.1347 6.29395 12.2988 6.49621 12.2988C6.69847 12.2988 6.86238 12.1347 6.86238 11.9326V5.95684C6.86238 5.75459 6.69846 5.59066 6.49621 5.59066Z" fill="#CA2C2C" stroke="#CA2C2C" stroke-width="0.1"/>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.7 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
<svg width="15" height="13" viewBox="0 0 15 13" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<path d="M14.1775 1.15706C13.65 0.629221 12.9344 0.332764 12.1882 0.333016C11.4423 0.331256 10.7266 0.627618 10.2003 1.15615L6.56882 4.78765C5.85032 5.50729 5.57564 6.55841 5.85026 7.53755C5.93066 7.8226 6.22693 7.9885 6.51198 7.9081C6.79703 7.82769 6.96293 7.53142 6.88253 7.24637C6.71323 6.64086 6.88309 5.99111 7.32707 5.54593L10.9585 1.91496C11.6375 1.23586 12.7384 1.23574 13.4175 1.91471C14.0966 2.59366 14.0967 3.69458 13.4178 4.37368L9.78632 8.00515C9.54834 8.24345 9.2461 8.40725 8.91653 8.47653C8.62658 8.53689 8.44047 8.82087 8.50083 9.11083C8.55274 9.36015 8.77284 9.53856 9.02751 9.53777C9.06499 9.5378 9.10238 9.53385 9.13905 9.52599C9.67167 9.41366 10.16 9.14872 10.5446 8.76344L14.1761 5.1325C15.2742 4.03509 15.2749 2.25525 14.1775 1.15706Z" fill="#777777"/>
 | 
			
		||||
<path d="M9.13415 5.47721C9.05374 5.19216 8.75747 5.02625 8.47242 5.10666C8.18737 5.18707 8.02147 5.48333 8.10188 5.76838C8.27117 6.3739 8.10131 7.02365 7.65733 7.46882L4.02583 11.1003C3.34689 11.7794 2.24596 11.7796 1.56686 11.1006C0.887759 10.4216 0.887633 9.32071 1.56658 8.64161L5.19808 5.00957C5.43569 4.77134 5.73758 4.60754 6.06681 4.53819C6.35723 4.48009 6.54557 4.19759 6.48747 3.9072C6.42937 3.61681 6.14687 3.42844 5.85647 3.48653C5.85292 3.48726 5.84941 3.48798 5.84589 3.48876C5.31318 3.60122 4.82464 3.86616 4.43983 4.25132L0.808327 7.88282C-0.281225 8.98918 -0.267588 10.7693 0.838774 11.8589C1.93307 12.9365 3.68963 12.9366 4.78408 11.8591L8.41555 8.22707C9.13409 7.50744 9.40877 6.45631 9.13415 5.47721Z" fill="#777777"/>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
| 
						 | 
				
			
			@ -229,7 +229,7 @@ workflowCluster:
 | 
			
		|||
      menu6: pending
 | 
			
		||||
      # For Table
 | 
			
		||||
      tableStatus: Status
 | 
			
		||||
      tableCluster: cluster
 | 
			
		||||
      tableCluster: Target agent
 | 
			
		||||
      name: Name
 | 
			
		||||
      time: Time
 | 
			
		||||
      run: Last Run
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ const ConnectTargets = lazy(() =>
 | 
			
		|||
);
 | 
			
		||||
const SchedulePage = lazy(() => import('../../pages/SchedulePage'));
 | 
			
		||||
const AnalyticsPage = lazy(() => import('../../pages/AnalyticsPage'));
 | 
			
		||||
 | 
			
		||||
const ClusterInfo = lazy(() => import('../../components/Targets/ClusterInfo'));
 | 
			
		||||
interface RoutesProps {
 | 
			
		||||
  isOwner: boolean;
 | 
			
		||||
  isProjectAvailable: boolean;
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +92,7 @@ const Routes: React.FC<RoutesProps> = ({ isOwner, isProjectAvailable }) => {
 | 
			
		|||
        />
 | 
			
		||||
        <Route exact path="/community" component={Community} />
 | 
			
		||||
        <Route exact path="/targets" component={TargetHome} />
 | 
			
		||||
        <Route exact path="/targets/cluster" component={ClusterInfo} />
 | 
			
		||||
        <Route exact path="/target-connect" component={ConnectTargets} />
 | 
			
		||||
        {isOwner ? (
 | 
			
		||||
          <Route exact path="/settings" component={Settings} />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,37 +1,81 @@
 | 
			
		|||
import { TableCell, Typography } from '@material-ui/core';
 | 
			
		||||
import { TableCell, Typography, IconButton } from '@material-ui/core';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import {
 | 
			
		||||
  ExecutionData,
 | 
			
		||||
  WorkflowRun,
 | 
			
		||||
} from '../../../models/graphql/workflowData';
 | 
			
		||||
import moment from 'moment';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
import useStyles from './styles';
 | 
			
		||||
import { Cluster } from '../../../models/graphql/clusterData';
 | 
			
		||||
import { history } from '../../../redux/configureStore';
 | 
			
		||||
 | 
			
		||||
interface TableDataProps {
 | 
			
		||||
  data: WorkflowRun;
 | 
			
		||||
  exeData: ExecutionData;
 | 
			
		||||
  data: Cluster;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const TableData = () => {
 | 
			
		||||
const TableData: React.FC<TableDataProps> = ({ data }) => {
 | 
			
		||||
  const classes = useStyles();
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
  // Function to convert UNIX time in format of DD MMM YYY
 | 
			
		||||
  const formatDate = (date: string) => {
 | 
			
		||||
    const updated = new Date(parseInt(date, 10) * 1000).toString();
 | 
			
		||||
    const resDate = moment(updated).format('DD MMM YYYY');
 | 
			
		||||
    if (date) return resDate;
 | 
			
		||||
    return 'Date not available';
 | 
			
		||||
  };
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <TableCell className={classes.tableDataStatus}>Status</TableCell>
 | 
			
		||||
      <TableCell className={classes.workflowNameData}>
 | 
			
		||||
        <Typography>
 | 
			
		||||
          <strong>cluster</strong>
 | 
			
		||||
      <TableCell className={classes.tableDataStatus}>
 | 
			
		||||
        {data.is_active ? (
 | 
			
		||||
          <Typography className={`${classes.check} ${classes.active}`}>
 | 
			
		||||
            {t('workflowCluster.header.formControl.menu1')}
 | 
			
		||||
          </Typography>
 | 
			
		||||
        ) : (
 | 
			
		||||
          <Typography className={`${classes.check} ${classes.notactive}`}>
 | 
			
		||||
            {t('workflowCluster.header.formControl.menu2')}
 | 
			
		||||
          </Typography>
 | 
			
		||||
        )}
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell
 | 
			
		||||
        key={data.cluster_id}
 | 
			
		||||
        onClick={() => {
 | 
			
		||||
          history.push({ pathname: '/targets/cluster', state: { data } });
 | 
			
		||||
        }}
 | 
			
		||||
        className={classes.workflowNameData}
 | 
			
		||||
      >
 | 
			
		||||
        <IconButton size="small">
 | 
			
		||||
          <Typography>{data.cluster_name}</Typography>
 | 
			
		||||
        </IconButton>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell>
 | 
			
		||||
        <Typography className={classes.clusterName}>
 | 
			
		||||
          {formatDate(data.created_at)}
 | 
			
		||||
        </Typography>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell>
 | 
			
		||||
        <Typography className={classes.clusterName}>Name</Typography>
 | 
			
		||||
        <Typography className={classes.stepsData}>
 | 
			
		||||
          {data.no_of_workflows}
 | 
			
		||||
        </Typography>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell className={classes.stepsDataschedule}>
 | 
			
		||||
        <Typography>{data.no_of_schedules}</Typography>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell>{formatDate(data.updated_at)}</TableCell>
 | 
			
		||||
      <TableCell>
 | 
			
		||||
        <Typography>{/* reconnect */}</Typography>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell>
 | 
			
		||||
        <Typography className={classes.stepsData}>#</Typography>
 | 
			
		||||
        <div className={classes.deleteCluster}>
 | 
			
		||||
          <div>
 | 
			
		||||
            <IconButton>
 | 
			
		||||
              <img alt="delete" src="/icons/bin-red.svg" />
 | 
			
		||||
            </IconButton>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <Typography>
 | 
			
		||||
              {t('workflowCluster.header.formControl.delete')}
 | 
			
		||||
            </Typography>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell>
 | 
			
		||||
        <Typography>Time</Typography>
 | 
			
		||||
      </TableCell>
 | 
			
		||||
      <TableCell>Run</TableCell>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,12 +5,32 @@ import {
 | 
			
		|||
  TableContainer,
 | 
			
		||||
  TableHead,
 | 
			
		||||
  TableRow,
 | 
			
		||||
  TablePagination,
 | 
			
		||||
  IconButton,
 | 
			
		||||
  Typography,
 | 
			
		||||
} from '@material-ui/core';
 | 
			
		||||
import moment from 'moment';
 | 
			
		||||
import React, { useState } from 'react';
 | 
			
		||||
import { useSelector } from 'react-redux';
 | 
			
		||||
import { useQuery } from '@apollo/client';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
import HeaderSection from './HeaderSection';
 | 
			
		||||
import useStyles from './styles';
 | 
			
		||||
import { GET_CLUSTER } from '../../../graphql';
 | 
			
		||||
import Loader from '../../../components/Loader';
 | 
			
		||||
import { RootState } from '../../../redux/reducers';
 | 
			
		||||
import TableData from './TableData';
 | 
			
		||||
import {
 | 
			
		||||
  sortAlphaAsc,
 | 
			
		||||
  sortAlphaDesc,
 | 
			
		||||
  sortNumAsc,
 | 
			
		||||
  sortNumDesc,
 | 
			
		||||
} from '../../../utils/sort';
 | 
			
		||||
import {
 | 
			
		||||
  Cluster,
 | 
			
		||||
  ClusterVars,
 | 
			
		||||
  Clusters,
 | 
			
		||||
} from '../../../models/graphql/clusterData';
 | 
			
		||||
 | 
			
		||||
interface FilterOptions {
 | 
			
		||||
  search: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,9 +39,8 @@ interface FilterOptions {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
interface SortData {
 | 
			
		||||
  lastRun: { sort: boolean; ascending: boolean };
 | 
			
		||||
  name: { sort: boolean; ascending: boolean };
 | 
			
		||||
  noOfSteps: { sort: boolean; ascending: boolean };
 | 
			
		||||
  lastRun: { sort: boolean; ascending: boolean };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface DateData {
 | 
			
		||||
| 
						 | 
				
			
			@ -30,15 +49,115 @@ interface DateData {
 | 
			
		|||
  toDate: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface PaginationData {
 | 
			
		||||
  pageNo: number;
 | 
			
		||||
  rowsPerPage: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const BrowseCluster = () => {
 | 
			
		||||
  const classes = useStyles();
 | 
			
		||||
  // States for filters
 | 
			
		||||
 | 
			
		||||
  const selectedProjectID = useSelector(
 | 
			
		||||
    (state: RootState) => state.userData.selectedProjectID
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const [filters, setFilters] = useState<FilterOptions>({
 | 
			
		||||
    search: '',
 | 
			
		||||
    status: 'All',
 | 
			
		||||
    cluster: 'All',
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const { data, loading, error } = useQuery<Clusters, ClusterVars>(
 | 
			
		||||
    GET_CLUSTER,
 | 
			
		||||
    {
 | 
			
		||||
      variables: {
 | 
			
		||||
        project_id: selectedProjectID,
 | 
			
		||||
      },
 | 
			
		||||
      fetchPolicy: 'cache-and-network',
 | 
			
		||||
      pollInterval: 3000,
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const [dateRange, setDateRange] = React.useState<DateData>({
 | 
			
		||||
    dateValue: 'Select a period',
 | 
			
		||||
    fromDate: new Date(0).toString(),
 | 
			
		||||
    toDate: new Date(new Date().setHours(23, 59, 59)).toString(),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const [sortData, setSortData] = useState<SortData>({
 | 
			
		||||
    name: { sort: false, ascending: true },
 | 
			
		||||
    lastRun: { sort: true, ascending: true },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const filteredData = data?.getCluster
 | 
			
		||||
    .filter((dataRow) =>
 | 
			
		||||
      dataRow.cluster_name.toLowerCase().includes(filters.search.toLowerCase())
 | 
			
		||||
    )
 | 
			
		||||
    .filter((dataRow) => {
 | 
			
		||||
      if (filters.status === 'All') {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      if (
 | 
			
		||||
        (dataRow.is_cluster_confirmed as boolean).toString().toLowerCase() ===
 | 
			
		||||
          'false' &&
 | 
			
		||||
        filters.status === 'pending'
 | 
			
		||||
      ) {
 | 
			
		||||
        const p = 'pending';
 | 
			
		||||
        return p.includes(filters.status.toLowerCase());
 | 
			
		||||
      }
 | 
			
		||||
      if ((dataRow.is_active as boolean).toString().toLowerCase() === 'false') {
 | 
			
		||||
        const p = 'false';
 | 
			
		||||
        return p.includes(filters.status.toLowerCase());
 | 
			
		||||
      }
 | 
			
		||||
      if ((dataRow.is_active as boolean).toString().toLowerCase() === 'true') {
 | 
			
		||||
        const p = 'true';
 | 
			
		||||
        return p.includes(filters.status.toLowerCase());
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    })
 | 
			
		||||
    .filter((dataRow) =>
 | 
			
		||||
      filters.cluster === 'All'
 | 
			
		||||
        ? true
 | 
			
		||||
        : dataRow.cluster_type
 | 
			
		||||
            .toLowerCase()
 | 
			
		||||
            .includes(filters.cluster.toLowerCase())
 | 
			
		||||
    )
 | 
			
		||||
    .filter((dataRow) => {
 | 
			
		||||
      return dateRange.fromDate && dateRange.toDate === undefined
 | 
			
		||||
        ? true
 | 
			
		||||
        : parseInt(dataRow.updated_at, 10) * 1000 >=
 | 
			
		||||
            new Date(moment(dateRange.fromDate).format()).getTime() &&
 | 
			
		||||
            parseInt(dataRow.updated_at, 10) * 1000 <=
 | 
			
		||||
              new Date(moment(dateRange.toDate).format()).getTime();
 | 
			
		||||
    })
 | 
			
		||||
    .sort((a: Cluster, b: Cluster) => {
 | 
			
		||||
      // Sorting based on unique fields
 | 
			
		||||
      if (sortData.name.sort) {
 | 
			
		||||
        const x = a.cluster_name;
 | 
			
		||||
        const y = b.cluster_name;
 | 
			
		||||
 | 
			
		||||
        return sortData.name.ascending
 | 
			
		||||
          ? sortAlphaAsc(x, y)
 | 
			
		||||
          : sortAlphaDesc(x, y);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (sortData.lastRun.sort) {
 | 
			
		||||
        const x = parseInt(a.created_at, 10);
 | 
			
		||||
        const y = parseInt(b.created_at, 10);
 | 
			
		||||
 | 
			
		||||
        return sortData.lastRun.ascending
 | 
			
		||||
          ? sortNumAsc(y, x)
 | 
			
		||||
          : sortNumDesc(y, x);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return 0;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  const [paginationData, setPaginationData] = useState<PaginationData>({
 | 
			
		||||
    pageNo: 0,
 | 
			
		||||
    rowsPerPage: 5,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const [popAnchorEl, setPopAnchorEl] = React.useState<null | HTMLElement>(
 | 
			
		||||
    null
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			@ -55,13 +174,6 @@ const BrowseCluster = () => {
 | 
			
		|||
    setOpen(true);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // State for start date and end date
 | 
			
		||||
  const [dateRange, setDateRange] = React.useState<DateData>({
 | 
			
		||||
    dateValue: 'Select a period',
 | 
			
		||||
    fromDate: new Date(0).toString(),
 | 
			
		||||
    toDate: new Date(new Date().setHours(23, 59, 59)).toString(),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Functions passed as props in the headerSeaction
 | 
			
		||||
  const changeSearch = (
 | 
			
		||||
    event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +199,6 @@ const BrowseCluster = () => {
 | 
			
		|||
    setFilters({ ...filters, cluster: event.target.value as string });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Function to set the date range for filtering
 | 
			
		||||
  const dateChange = (selectFromDate: string, selectToDate: string) => {
 | 
			
		||||
    setDateRange({
 | 
			
		||||
      dateValue: `${moment(selectFromDate)
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +208,7 @@ const BrowseCluster = () => {
 | 
			
		|||
      toDate: new Date(new Date(selectToDate).setHours(23, 59, 59)).toString(),
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div>
 | 
			
		||||
| 
						 | 
				
			
			@ -122,71 +234,156 @@ const BrowseCluster = () => {
 | 
			
		|||
        <TableContainer className={classes.tableMain}>
 | 
			
		||||
          <Table stickyHeader aria-label="simple table">
 | 
			
		||||
            <TableHead>
 | 
			
		||||
              <TableRow>
 | 
			
		||||
              <TableRow className={classes.tableRows}>
 | 
			
		||||
                {/* Status */}
 | 
			
		||||
                <TableCell className={classes.headerStatus}>
 | 
			
		||||
                  <div className={classes.tableCell}>
 | 
			
		||||
                    <Typography>Status</Typography>
 | 
			
		||||
                    <div className={classes.sortDiv}>
 | 
			
		||||
                      <img
 | 
			
		||||
                        src="/icons/arrow_downward.svg"
 | 
			
		||||
                        alt="ConnectTarget icon"
 | 
			
		||||
                      />
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <Typography>
 | 
			
		||||
                      {t('workflowCluster.header.formControl.tableStatus')}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                    <IconButton
 | 
			
		||||
                      aria-label="sort last run descending"
 | 
			
		||||
                      size="small"
 | 
			
		||||
                      onClick={() =>
 | 
			
		||||
                        setSortData({
 | 
			
		||||
                          ...sortData,
 | 
			
		||||
                          lastRun: { sort: true, ascending: false },
 | 
			
		||||
                        })
 | 
			
		||||
                      }
 | 
			
		||||
                    >
 | 
			
		||||
                      <div className={classes.sortDiv}>
 | 
			
		||||
                        <img
 | 
			
		||||
                          src="/icons/arrow_downward.svg"
 | 
			
		||||
                          alt="ConnectTarget icon"
 | 
			
		||||
                        />
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </IconButton>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </TableCell>
 | 
			
		||||
                {/* Workflow Name */}
 | 
			
		||||
                <TableCell className={classes.workflowName}>
 | 
			
		||||
                  <div className={classes.tableCell}>
 | 
			
		||||
                    <Typography>Target Cluster</Typography>
 | 
			
		||||
                    <div className={classes.sortDiv}>
 | 
			
		||||
                      <img
 | 
			
		||||
                        src="/icons/arrow_downward.svg"
 | 
			
		||||
                        alt="ConnectTarget icon"
 | 
			
		||||
                      />
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <Typography>
 | 
			
		||||
                      {t('workflowCluster.header.formControl.tableCluster')}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                    <IconButton
 | 
			
		||||
                      aria-label="sort last run descending"
 | 
			
		||||
                      size="small"
 | 
			
		||||
                      onClick={() =>
 | 
			
		||||
                        setSortData({
 | 
			
		||||
                          ...sortData,
 | 
			
		||||
                          name: { sort: true, ascending: false },
 | 
			
		||||
                        })
 | 
			
		||||
                      }
 | 
			
		||||
                    >
 | 
			
		||||
                      <div className={classes.sortDiv}>
 | 
			
		||||
                        <img
 | 
			
		||||
                          src="/icons/arrow_downward.svg"
 | 
			
		||||
                          alt="ConnectTarget icon"
 | 
			
		||||
                        />
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </IconButton>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </TableCell>
 | 
			
		||||
 | 
			
		||||
                {/* Target Cluster */}
 | 
			
		||||
                <TableCell>
 | 
			
		||||
                  <Typography className={classes.targetCluster}>
 | 
			
		||||
                    Connection Data
 | 
			
		||||
                    {t('workflowCluster.header.formControl.connectionDate')}
 | 
			
		||||
                  </Typography>
 | 
			
		||||
                </TableCell>
 | 
			
		||||
 | 
			
		||||
                {/* Reliability */}
 | 
			
		||||
                <TableCell className={classes.headData}>
 | 
			
		||||
                  # of workflows
 | 
			
		||||
                  {t('workflowCluster.header.formControl.noWorkflows')}
 | 
			
		||||
                </TableCell>
 | 
			
		||||
 | 
			
		||||
                {/* No of Experiments */}
 | 
			
		||||
                <TableCell className={classes.headData}>
 | 
			
		||||
                  <div className={classes.tableCell}>
 | 
			
		||||
                    <Typography># of schedules</Typography>
 | 
			
		||||
                    <Typography>
 | 
			
		||||
                      {t('workflowCluster.header.formControl.noSchedules')}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </TableCell>
 | 
			
		||||
 | 
			
		||||
                {/* Last Run */}
 | 
			
		||||
                <TableCell className={classes.headData}>
 | 
			
		||||
                  <div className={classes.tableCell}>
 | 
			
		||||
                    <Typography>Last Run</Typography>
 | 
			
		||||
                    <Typography>
 | 
			
		||||
                      {t('workflowCluster.header.formControl.run')}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </TableCell>
 | 
			
		||||
 | 
			
		||||
                {/* Re-connect */}
 | 
			
		||||
                <TableCell />
 | 
			
		||||
                <TableCell />
 | 
			
		||||
                <TableCell />
 | 
			
		||||
              </TableRow>
 | 
			
		||||
            </TableHead>
 | 
			
		||||
 | 
			
		||||
            {/* Body */}
 | 
			
		||||
            <TableBody>
 | 
			
		||||
              <TableRow>
 | 
			
		||||
                <TableCell colSpan={8}>
 | 
			
		||||
                  <Typography align="center">No records available</Typography>
 | 
			
		||||
                </TableCell>
 | 
			
		||||
              </TableRow>
 | 
			
		||||
              {loading ? (
 | 
			
		||||
                <TableRow>
 | 
			
		||||
                  <TableCell colSpan={8}>
 | 
			
		||||
                    <Loader />
 | 
			
		||||
                  </TableCell>
 | 
			
		||||
                </TableRow>
 | 
			
		||||
              ) : error ? (
 | 
			
		||||
                <TableRow>
 | 
			
		||||
                  <TableCell data-cy="browseScheduleError" colSpan={8}>
 | 
			
		||||
                    <Typography align="center">
 | 
			
		||||
                      {t('workflowCluster.header.formControl.fetchingError')}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                  </TableCell>
 | 
			
		||||
                </TableRow>
 | 
			
		||||
              ) : filteredData ? (
 | 
			
		||||
                filteredData
 | 
			
		||||
                  .slice(
 | 
			
		||||
                    paginationData.pageNo * paginationData.rowsPerPage,
 | 
			
		||||
                    paginationData.pageNo * paginationData.rowsPerPage +
 | 
			
		||||
                      paginationData.rowsPerPage
 | 
			
		||||
                  )
 | 
			
		||||
                  .map((data: Cluster) => (
 | 
			
		||||
                    <TableRow
 | 
			
		||||
                      data-cy="browseScheduleData"
 | 
			
		||||
                      key={data.cluster_id}
 | 
			
		||||
                    >
 | 
			
		||||
                      <TableData data={data} />
 | 
			
		||||
                    </TableRow>
 | 
			
		||||
                  ))
 | 
			
		||||
              ) : (
 | 
			
		||||
                <TableRow>
 | 
			
		||||
                  <TableCell data-cy="browseScheduleNoData" colSpan={0}>
 | 
			
		||||
                    <Typography align="center">
 | 
			
		||||
                      {t('workflowCluster.header.formControl.recordAvailable')}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                  </TableCell>
 | 
			
		||||
                </TableRow>
 | 
			
		||||
              )}
 | 
			
		||||
            </TableBody>
 | 
			
		||||
          </Table>
 | 
			
		||||
        </TableContainer>
 | 
			
		||||
 | 
			
		||||
        {/* Pagination Section */}
 | 
			
		||||
        <TablePagination
 | 
			
		||||
          rowsPerPageOptions={[5, 10, 25]}
 | 
			
		||||
          component="div"
 | 
			
		||||
          count={filteredData?.length ?? 0}
 | 
			
		||||
          rowsPerPage={paginationData.rowsPerPage}
 | 
			
		||||
          page={paginationData.pageNo}
 | 
			
		||||
          onChangePage={(_, page) =>
 | 
			
		||||
            setPaginationData({ ...paginationData, pageNo: page })
 | 
			
		||||
          }
 | 
			
		||||
          onChangeRowsPerPage={(event) => {
 | 
			
		||||
            setPaginationData({
 | 
			
		||||
              ...paginationData,
 | 
			
		||||
              pageNo: 0,
 | 
			
		||||
              rowsPerPage: parseInt(event.target.value, 10),
 | 
			
		||||
            });
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
      </section>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -144,6 +144,23 @@ const useStyles = makeStyles((theme) => ({
 | 
			
		|||
  datePickerColor: {
 | 
			
		||||
    color: theme.palette.secondary.dark,
 | 
			
		||||
  },
 | 
			
		||||
  // Table status
 | 
			
		||||
  check: {
 | 
			
		||||
    width: '5.9125rem',
 | 
			
		||||
    textAlign: 'center',
 | 
			
		||||
    borderRadius: 3,
 | 
			
		||||
    paddingTop: theme.spacing(0.375),
 | 
			
		||||
    paddingBottom: theme.spacing(0.375),
 | 
			
		||||
    color: theme.palette.primary.dark,
 | 
			
		||||
  },
 | 
			
		||||
  active: {
 | 
			
		||||
    color: theme.palette.primary.dark,
 | 
			
		||||
    background: theme.palette.customColors.menuOption.active,
 | 
			
		||||
  },
 | 
			
		||||
  notactive: {
 | 
			
		||||
    color: theme.palette.error.dark,
 | 
			
		||||
    backgroundColor: theme.palette.error.light,
 | 
			
		||||
  },
 | 
			
		||||
  statusFont: {
 | 
			
		||||
    fontSize: '0.725rem',
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -206,8 +206,8 @@ const BrowseSchedule = () => {
 | 
			
		|||
                        onClick={() =>
 | 
			
		||||
                          setSortData({
 | 
			
		||||
                            ...sortData,
 | 
			
		||||
                            name: { sort: true, ascending: true },
 | 
			
		||||
                            startDate: { sort: false, ascending: true },
 | 
			
		||||
                            name: { sort: false, ascending: false },
 | 
			
		||||
                            startDate: { sort: false, ascending: false },
 | 
			
		||||
                          })
 | 
			
		||||
                        }
 | 
			
		||||
                      >
 | 
			
		||||
| 
						 | 
				
			
			@ -219,8 +219,8 @@ const BrowseSchedule = () => {
 | 
			
		|||
                        onClick={() =>
 | 
			
		||||
                          setSortData({
 | 
			
		||||
                            ...sortData,
 | 
			
		||||
                            name: { sort: true, ascending: false },
 | 
			
		||||
                            startDate: { sort: false, ascending: false },
 | 
			
		||||
                            name: { sort: false, ascending: true },
 | 
			
		||||
                            startDate: { sort: true, ascending: true },
 | 
			
		||||
                          })
 | 
			
		||||
                        }
 | 
			
		||||
                      >
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,6 +68,7 @@ const BrowseWorkflow = () => {
 | 
			
		|||
    WORKFLOW_DETAILS,
 | 
			
		||||
    {
 | 
			
		||||
      variables: { projectID: selectedProjectID },
 | 
			
		||||
      pollInterval: 500,
 | 
			
		||||
      fetchPolicy: 'cache-and-network',
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,8 +29,9 @@ const MenuProps = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
interface Cluster {
 | 
			
		||||
  cluster_id: string;
 | 
			
		||||
  cluster_name: string;
 | 
			
		||||
  is_active: boolean;
 | 
			
		||||
  cluster_id: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface WorkflowClusterProps {
 | 
			
		||||
| 
						 | 
				
			
			@ -66,8 +67,9 @@ const WorkflowCluster: React.FC<WorkflowClusterProps> = ({ gotoStep }) => {
 | 
			
		|||
        data.getCluster.forEach((e: Cluster) => {
 | 
			
		||||
          if (e.is_active === true) {
 | 
			
		||||
            clusters.push({
 | 
			
		||||
              cluster_id: e.cluster_id,
 | 
			
		||||
              cluster_name: e.cluster_name,
 | 
			
		||||
              is_active: e.is_active,
 | 
			
		||||
              cluster_id: e.cluster_id,
 | 
			
		||||
            });
 | 
			
		||||
            workflow.setWorkflowDetails({
 | 
			
		||||
              cronSyntax: '',
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +140,7 @@ const WorkflowCluster: React.FC<WorkflowClusterProps> = ({ gotoStep }) => {
 | 
			
		|||
            >
 | 
			
		||||
              {clusterData.map((name: Cluster) => (
 | 
			
		||||
                <MenuItem key={name.cluster_id} value={name.cluster_id}>
 | 
			
		||||
                  {name.cluster_id}
 | 
			
		||||
                  {name.cluster_name}
 | 
			
		||||
                </MenuItem>
 | 
			
		||||
              ))}
 | 
			
		||||
            </Select>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue