chore(litmus-portal): Added date filter in workflows table and some important refactorings (#1962)
This commit has the following changes: - Date filter in the workflows table - Important refactoring in the Browse Workflow Section - Minor CSS fixes Signed-off-by: Amit Kumar Das <amitkumar.das@mayadata.io>
This commit is contained in:
parent
d74c1d3898
commit
9fb8cef94f
|
@ -2753,6 +2753,16 @@
|
||||||
"csstype": "^2.2.0"
|
"csstype": "^2.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-date-range": {
|
||||||
|
"version": "0.95.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-date-range/-/react-date-range-0.95.1.tgz",
|
||||||
|
"integrity": "sha512-jzuh7fL9F1Y3eSoeyWoS/H2zSCn9WXvlbLfOOox9bopmZjyNwp/fx08TYrgi8jAJ60F2Aap8uA2BQbe8+7mNGg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"moment": ">=2.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/react-dom": {
|
"@types/react-dom": {
|
||||||
"version": "16.9.8",
|
"version": "16.9.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz",
|
||||||
|
@ -13718,6 +13728,24 @@
|
||||||
"gl-mat4": "^1.0.1"
|
"gl-mat4": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"materialui-daterange-picker": {
|
||||||
|
"version": "1.1.91",
|
||||||
|
"resolved": "https://registry.npmjs.org/materialui-daterange-picker/-/materialui-daterange-picker-1.1.91.tgz",
|
||||||
|
"integrity": "sha512-vMEQlI3WrTuWEVgAhO6P5X6WfC46A1I4BwnlaEKz9Tbsw/1vj1fms5BX37yJkZZs4+Rbj1XIp34l7uy3UyuVyw==",
|
||||||
|
"requires": {
|
||||||
|
"@material-ui/core": "^4.9.4",
|
||||||
|
"@material-ui/icons": "^4.9.1",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"date-fns": "^1.30.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"date-fns": {
|
||||||
|
"version": "1.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
|
||||||
|
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"math-log2": {
|
"math-log2": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/math-log2/-/math-log2-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/math-log2/-/math-log2-1.0.1.tgz",
|
||||||
|
@ -14174,8 +14202,7 @@
|
||||||
"moment": {
|
"moment": {
|
||||||
"version": "2.27.0",
|
"version": "2.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
|
||||||
"integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==",
|
"integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"monotone-convex-hull-2d": {
|
"monotone-convex-hull-2d": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
"js-yaml": "^3.14.0",
|
"js-yaml": "^3.14.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"localforage": "^1.7.3",
|
"localforage": "^1.7.3",
|
||||||
|
"materialui-daterange-picker": "^1.1.91",
|
||||||
|
"moment": "^2.27.0",
|
||||||
"plotly.js": "^1.54.6",
|
"plotly.js": "^1.54.6",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"rc-progress": "^3.0.0",
|
"rc-progress": "^3.0.0",
|
||||||
|
|
|
@ -12,9 +12,10 @@ import LinearProgressBar from '../../ReturningHome/ProgressBar/LinearProgressBar
|
||||||
import useStyles from './styles';
|
import useStyles from './styles';
|
||||||
import timeDifferenceForDate from '../../../../utils/datesModifier';
|
import timeDifferenceForDate from '../../../../utils/datesModifier';
|
||||||
import { history } from '../../../../redux/configureStore';
|
import { history } from '../../../../redux/configureStore';
|
||||||
|
import { WorkflowRun } from '../../../../models/workflowData';
|
||||||
|
|
||||||
interface TableDataProps {
|
interface TableDataProps {
|
||||||
data: any;
|
data: WorkflowRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TableData: React.FC<TableDataProps> = ({ data }) => {
|
const TableData: React.FC<TableDataProps> = ({ data }) => {
|
||||||
|
@ -33,7 +34,7 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
||||||
const handleMenu = () => {};
|
const handleMenu = () => {};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TableCell className={classes.headerStatus1}>
|
<TableCell className={classes.tableDataStatus}>
|
||||||
<CustomStatus status={JSON.parse(data.execution_data).phase} />
|
<CustomStatus status={JSON.parse(data.execution_data).phase} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className={classes.workflowNameData}>
|
<TableCell className={classes.workflowNameData}>
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
InputBase,
|
||||||
|
InputAdornment,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
Select,
|
||||||
|
MenuItem,
|
||||||
|
Typography,
|
||||||
|
IconButton,
|
||||||
|
Popover,
|
||||||
|
} from '@material-ui/core';
|
||||||
|
import SearchIcon from '@material-ui/icons/Search';
|
||||||
|
import { DateRangePicker } from 'materialui-daterange-picker';
|
||||||
|
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
||||||
|
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
||||||
|
import useStyles from './styles';
|
||||||
|
|
||||||
|
interface HeaderSectionProps {
|
||||||
|
searchValue: string;
|
||||||
|
statusValue: string;
|
||||||
|
clusterValue: string;
|
||||||
|
isOpen: boolean;
|
||||||
|
isDateOpen: boolean;
|
||||||
|
popAnchorEl: HTMLElement | null;
|
||||||
|
displayDate: string;
|
||||||
|
changeSearch: (
|
||||||
|
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||||
|
) => void;
|
||||||
|
changeStatus: (
|
||||||
|
event: React.ChangeEvent<{
|
||||||
|
name?: string | undefined;
|
||||||
|
value: unknown;
|
||||||
|
}>,
|
||||||
|
child: React.ReactNode
|
||||||
|
) => void;
|
||||||
|
changeCluster: (
|
||||||
|
event: React.ChangeEvent<{
|
||||||
|
name?: string | undefined;
|
||||||
|
value: unknown;
|
||||||
|
}>,
|
||||||
|
child: React.ReactNode
|
||||||
|
) => void;
|
||||||
|
popOverClick: (
|
||||||
|
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||||
|
) => void;
|
||||||
|
popOverClose: (
|
||||||
|
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||||
|
) => void;
|
||||||
|
toggle: () => void;
|
||||||
|
selectDate: (range: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HeaderSection: React.FC<HeaderSectionProps> = ({
|
||||||
|
searchValue,
|
||||||
|
statusValue,
|
||||||
|
clusterValue,
|
||||||
|
isOpen,
|
||||||
|
popAnchorEl,
|
||||||
|
isDateOpen,
|
||||||
|
displayDate,
|
||||||
|
changeSearch,
|
||||||
|
changeStatus,
|
||||||
|
changeCluster,
|
||||||
|
popOverClick,
|
||||||
|
popOverClose,
|
||||||
|
toggle,
|
||||||
|
selectDate,
|
||||||
|
}) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={classes.headerSection}>
|
||||||
|
{/* Search Field */}
|
||||||
|
<InputBase
|
||||||
|
id="input-with-icon-adornment"
|
||||||
|
placeholder="Search"
|
||||||
|
className={classes.search}
|
||||||
|
value={searchValue}
|
||||||
|
onChange={changeSearch}
|
||||||
|
startAdornment={
|
||||||
|
<InputAdornment position="start">
|
||||||
|
<SearchIcon />
|
||||||
|
</InputAdornment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Select Workflow */}
|
||||||
|
<FormControl
|
||||||
|
variant="outlined"
|
||||||
|
className={classes.formControl}
|
||||||
|
color="secondary"
|
||||||
|
focused
|
||||||
|
>
|
||||||
|
<InputLabel className={classes.selectText}>
|
||||||
|
Workflow Status
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={statusValue}
|
||||||
|
onChange={changeStatus}
|
||||||
|
label="Workflow Status"
|
||||||
|
className={classes.selectText}
|
||||||
|
>
|
||||||
|
<MenuItem value="All">All</MenuItem>
|
||||||
|
<MenuItem value="Failed">Failed</MenuItem>
|
||||||
|
<MenuItem value="Running">Running</MenuItem>
|
||||||
|
<MenuItem value="Succeeded">Succeeded</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
{/* Select Cluster */}
|
||||||
|
<FormControl
|
||||||
|
variant="outlined"
|
||||||
|
className={classes.formControl}
|
||||||
|
color="secondary"
|
||||||
|
focused
|
||||||
|
>
|
||||||
|
<InputLabel className={classes.selectText}>Target Cluster</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={clusterValue}
|
||||||
|
onChange={changeCluster}
|
||||||
|
label="Target Cluster"
|
||||||
|
className={classes.selectText}
|
||||||
|
>
|
||||||
|
<MenuItem value="All">All</MenuItem>
|
||||||
|
<MenuItem value="Predefined">Cluset pre-defined</MenuItem>
|
||||||
|
<MenuItem value="Kubernetes">Kubernetes Cluster</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<div className={classes.selectDate}>
|
||||||
|
<Typography className={classes.displayDate}>
|
||||||
|
{displayDate}
|
||||||
|
<IconButton
|
||||||
|
style={{ width: 10, height: 10 }}
|
||||||
|
onClick={popOverClick}
|
||||||
|
>
|
||||||
|
{isOpen ? <KeyboardArrowDownIcon /> : <ChevronRightIcon />}
|
||||||
|
</IconButton>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<Popover
|
||||||
|
open={isOpen}
|
||||||
|
anchorEl={popAnchorEl}
|
||||||
|
onClose={popOverClose}
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'bottom',
|
||||||
|
horizontal: 'center',
|
||||||
|
}}
|
||||||
|
transformOrigin={{
|
||||||
|
vertical: 'top',
|
||||||
|
horizontal: 'center',
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
marginTop: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DateRangePicker
|
||||||
|
open={isDateOpen}
|
||||||
|
toggle={toggle}
|
||||||
|
onChange={selectDate}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default HeaderSection;
|
|
@ -1,12 +1,6 @@
|
||||||
import { useQuery } from '@apollo/client';
|
import { useQuery } from '@apollo/client';
|
||||||
import {
|
import {
|
||||||
FormControl,
|
|
||||||
IconButton,
|
IconButton,
|
||||||
InputAdornment,
|
|
||||||
InputBase,
|
|
||||||
InputLabel,
|
|
||||||
MenuItem,
|
|
||||||
Select,
|
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
|
@ -16,9 +10,9 @@ import {
|
||||||
TableRow,
|
TableRow,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
|
import moment from 'moment';
|
||||||
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
|
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
|
||||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||||
import SearchIcon from '@material-ui/icons/Search';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { WORKFLOW_DETAILS, WORKFLOW_EVENTS } from '../../../../graphql';
|
import { WORKFLOW_DETAILS, WORKFLOW_EVENTS } from '../../../../graphql';
|
||||||
|
@ -41,6 +35,7 @@ import {
|
||||||
import Loader from '../../../Loader';
|
import Loader from '../../../Loader';
|
||||||
import useStyles from './styles';
|
import useStyles from './styles';
|
||||||
import TableData from './TableData';
|
import TableData from './TableData';
|
||||||
|
import HeaderSection from './headerSection';
|
||||||
|
|
||||||
interface FilterOptions {
|
interface FilterOptions {
|
||||||
search: string;
|
search: string;
|
||||||
|
@ -59,6 +54,12 @@ interface SortData {
|
||||||
noOfSteps: { sort: boolean; ascending: boolean };
|
noOfSteps: { sort: boolean; ascending: boolean };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DateData {
|
||||||
|
dateValue: string;
|
||||||
|
fromDate: Date | undefined;
|
||||||
|
toDate: Date | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const BrowseWorkflow = () => {
|
const BrowseWorkflow = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const userData: UserData = useSelector((state: RootState) => state.userData);
|
const userData: UserData = useSelector((state: RootState) => state.userData);
|
||||||
|
@ -72,7 +73,6 @@ const BrowseWorkflow = () => {
|
||||||
variables: { projectID: selectedProjectID },
|
variables: { projectID: selectedProjectID },
|
||||||
fetchPolicy: 'cache-and-network',
|
fetchPolicy: 'cache-and-network',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Using subscription to get realtime data
|
// Using subscription to get realtime data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
subscribeToMore<WorkflowSubscription>({
|
subscribeToMore<WorkflowSubscription>({
|
||||||
|
@ -121,6 +121,29 @@ const BrowseWorkflow = () => {
|
||||||
rowsPerPage: 5,
|
rowsPerPage: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [popAnchorEl, setPopAnchorEl] = React.useState<null | HTMLElement>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
const isOpen = Boolean(popAnchorEl);
|
||||||
|
|
||||||
|
const [open, setOpen] = React.useState<boolean>(false);
|
||||||
|
|
||||||
|
const handlePopOverClose = () => {
|
||||||
|
setPopAnchorEl(null);
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
const handlePopOverClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
|
setPopAnchorEl(event.currentTarget);
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// State for start date and end date
|
||||||
|
const [dateRange, setDateRange] = React.useState<DateData>({
|
||||||
|
dateValue: 'Select a period',
|
||||||
|
fromDate: new Date(0),
|
||||||
|
toDate: new Date(new Date().valueOf() + 1000 * 3600 * 24),
|
||||||
|
});
|
||||||
|
|
||||||
const filteredData = data?.getWorkFlowRuns
|
const filteredData = data?.getWorkFlowRuns
|
||||||
.filter((dataRow) =>
|
.filter((dataRow) =>
|
||||||
dataRow.workflow_name.toLowerCase().includes(filters.search)
|
dataRow.workflow_name.toLowerCase().includes(filters.search)
|
||||||
|
@ -137,6 +160,14 @@ const BrowseWorkflow = () => {
|
||||||
? true
|
? true
|
||||||
: dataRow.cluster_name.toLowerCase().includes(filters.cluster)
|
: dataRow.cluster_name.toLowerCase().includes(filters.cluster)
|
||||||
)
|
)
|
||||||
|
.filter((dataRow) => {
|
||||||
|
return dateRange.fromDate && dateRange.toDate === undefined
|
||||||
|
? true
|
||||||
|
: parseInt(dataRow.last_updated, 10) * 1000 >=
|
||||||
|
new Date(moment(dateRange.fromDate).format()).getTime() &&
|
||||||
|
parseInt(dataRow.last_updated, 10) * 1000 <=
|
||||||
|
new Date(moment(dateRange.toDate).format()).getTime();
|
||||||
|
})
|
||||||
.sort((a: WorkflowRun, b: WorkflowRun) => {
|
.sort((a: WorkflowRun, b: WorkflowRun) => {
|
||||||
// Sorting based on unique fields
|
// Sorting based on unique fields
|
||||||
if (sortData.name.sort) {
|
if (sortData.name.sort) {
|
||||||
|
@ -178,94 +209,73 @@ const BrowseWorkflow = () => {
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Functions passed as props in the headerSeaction
|
||||||
|
const changeSearch = (
|
||||||
|
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
setFilters({ ...filters, search: event.target.value as string });
|
||||||
|
setPaginationData({ ...paginationData, pageNo: 0 });
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeStatus = (
|
||||||
|
event: React.ChangeEvent<{
|
||||||
|
name?: string | undefined;
|
||||||
|
value: unknown;
|
||||||
|
}>
|
||||||
|
) => {
|
||||||
|
setFilters({ ...filters, status: event.target.value as string });
|
||||||
|
setPaginationData({ ...paginationData, pageNo: 0 });
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeCluster = (
|
||||||
|
event: React.ChangeEvent<{
|
||||||
|
name?: string | undefined;
|
||||||
|
value: unknown;
|
||||||
|
}>
|
||||||
|
) => {
|
||||||
|
setFilters({ ...filters, cluster: event.target.value as string });
|
||||||
|
setPaginationData({ ...paginationData, pageNo: 0 });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to set the date range for filtering
|
||||||
|
const dateChange = (range: any) => {
|
||||||
|
setDateRange({
|
||||||
|
dateValue: `${moment(range?.startDate)
|
||||||
|
.format('DD.MM.YYYY')
|
||||||
|
.toString()}-${moment(range?.endDate).format('DD.MM.YYYY').toString()}`,
|
||||||
|
fromDate:
|
||||||
|
moment(range?.startDate).format('DD-MM-YYYY') ===
|
||||||
|
moment(new Date()).format('DD-MM-YYYY')
|
||||||
|
? new Date(new Date().setHours(0, 0, 0))
|
||||||
|
: new Date(range?.startDate.setHours(0, 0, 0)),
|
||||||
|
toDate:
|
||||||
|
moment(range?.endDate).format('DD-MM-YYYY') ===
|
||||||
|
moment(new Date()).format('DD-MM-YYYY')
|
||||||
|
? new Date(new Date().setHours(23, 59, 59))
|
||||||
|
: new Date(range?.endDate.setHours(23, 59, 59)),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<section className="Heading section">
|
<section className="Heading section">
|
||||||
<div className={classes.headerSection}>
|
{/* Header Section */}
|
||||||
<InputBase
|
<HeaderSection
|
||||||
id="input-with-icon-adornment"
|
searchValue={filters.search}
|
||||||
placeholder="Search"
|
changeSearch={changeSearch}
|
||||||
className={classes.search}
|
statusValue={filters.status}
|
||||||
value={filters.search}
|
changeStatus={changeStatus}
|
||||||
onChange={(e) => {
|
clusterValue={filters.cluster}
|
||||||
setFilters({ ...filters, search: e.target.value as string });
|
changeCluster={changeCluster}
|
||||||
setPaginationData({ ...paginationData, pageNo: 0 });
|
popOverClick={handlePopOverClick}
|
||||||
}}
|
popOverClose={handlePopOverClose}
|
||||||
startAdornment={
|
isOpen={isOpen}
|
||||||
<InputAdornment position="start">
|
popAnchorEl={popAnchorEl}
|
||||||
<SearchIcon />
|
isDateOpen={open}
|
||||||
</InputAdornment>
|
toggle={handlePopOverClose}
|
||||||
}
|
displayDate={dateRange.dateValue}
|
||||||
/>
|
selectDate={dateChange}
|
||||||
<FormControl className={classes.select}>
|
/>
|
||||||
<InputLabel id="demo-simple-select-outlined-label">
|
|
||||||
Workflow Status
|
|
||||||
</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="demo-simple-select-outlined-label"
|
|
||||||
id="demo-simple-select-outlined"
|
|
||||||
value={filters.status}
|
|
||||||
onChange={(e) => {
|
|
||||||
setFilters({ ...filters, status: e.target.value as string });
|
|
||||||
setPaginationData({ ...paginationData, pageNo: 0 });
|
|
||||||
}}
|
|
||||||
disableUnderline
|
|
||||||
>
|
|
||||||
<MenuItem value="All">
|
|
||||||
<Typography className={classes.menuItem}>All</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="Failed">
|
|
||||||
<Typography className={classes.menuItem}>Failed</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="Running">
|
|
||||||
<Typography className={classes.menuItem}>Running</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="Succeeded">
|
|
||||||
<Typography className={classes.menuItem}>Succeeded</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormControl className={classes.select1}>
|
|
||||||
<InputLabel id="demo-simple-select-outlined-label">
|
|
||||||
Target Cluster
|
|
||||||
</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="demo-simple-select-outlined-label"
|
|
||||||
id="demo-simple-select-outlined"
|
|
||||||
value={filters.cluster}
|
|
||||||
onChange={(e) => {
|
|
||||||
setFilters({ ...filters, cluster: e.target.value as string });
|
|
||||||
setPaginationData({ ...paginationData, pageNo: 0 });
|
|
||||||
}}
|
|
||||||
disableUnderline
|
|
||||||
>
|
|
||||||
<MenuItem value="All">
|
|
||||||
<Typography className={classes.menuItem}>All</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="Predefined">
|
|
||||||
<Typography className={classes.menuItem}>
|
|
||||||
Cluset pre-defined
|
|
||||||
</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="Kubernetes">
|
|
||||||
<Typography className={classes.menuItem}>
|
|
||||||
Kubernetes Cluster
|
|
||||||
</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl className={classes.select}>
|
|
||||||
<InputLabel id="demo-simple-select-outlined-label">Date</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="demo-simple-select-outlined-label"
|
|
||||||
id="demo-simple-select-outlined"
|
|
||||||
value=""
|
|
||||||
disableUnderline
|
|
||||||
onChange={() => {}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
<section className="table section">
|
<section className="table section">
|
||||||
<TableContainer className={classes.tableMain}>
|
<TableContainer className={classes.tableMain}>
|
||||||
|
@ -394,7 +404,7 @@ const BrowseWorkflow = () => {
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
{/* Menu */}
|
{/* Menu Cell */}
|
||||||
<TableCell />
|
<TableCell />
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
|
@ -1,39 +1,60 @@
|
||||||
import { makeStyles } from '@material-ui/core';
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
// Header Section Properties
|
||||||
headerSection: {
|
headerSection: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
height: '5.625rem',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignContent: 'center',
|
alignContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
border: '1px solid ',
|
border: '1px solid ',
|
||||||
borderColor: theme.palette.text.hint,
|
borderColor: theme.palette.customColors.black(0.07),
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
},
|
},
|
||||||
|
|
||||||
search: {
|
search: {
|
||||||
|
fontSize: 14,
|
||||||
marginRight: 'auto',
|
marginRight: 'auto',
|
||||||
|
borderBottom: `1px solid ${theme.palette.customColors.black(0.1)}`,
|
||||||
marginLeft: theme.spacing(6.25),
|
marginLeft: theme.spacing(6.25),
|
||||||
},
|
},
|
||||||
select: {
|
|
||||||
width: '9.375rem',
|
// Form Select Properties
|
||||||
marginLeft: theme.spacing(1.25),
|
formControl: {
|
||||||
paddingBottom: theme.spacing(2.5),
|
margin: theme.spacing(0.5),
|
||||||
|
marginRight: theme.spacing(2.5),
|
||||||
|
height: '2.5rem',
|
||||||
|
minWidth: '9rem',
|
||||||
},
|
},
|
||||||
select1: {
|
|
||||||
width: '10.375rem',
|
selectText: {
|
||||||
marginLeft: theme.spacing(1.25),
|
height: '2.5rem',
|
||||||
paddingBottom: theme.spacing(2.5),
|
padding: theme.spacing(0.5),
|
||||||
},
|
},
|
||||||
headerText: {
|
|
||||||
marginLeft: theme.spacing(3.75),
|
selectDate: {
|
||||||
color: theme.palette.text.disabled,
|
display: 'flex',
|
||||||
paddingBottom: theme.spacing(0.625),
|
flexDirection: 'row',
|
||||||
|
height: '2.5rem',
|
||||||
|
minWidth: '9rem',
|
||||||
|
border: '1.7px solid',
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: theme.palette.secondary.main,
|
||||||
|
marginRight: theme.spacing(3.75),
|
||||||
},
|
},
|
||||||
|
displayDate: {
|
||||||
|
marginLeft: theme.spacing(1.875),
|
||||||
|
paddingTop: theme.spacing(0.75),
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Table and Table Data Properties
|
||||||
tableMain: {
|
tableMain: {
|
||||||
marginTop: theme.spacing(6.25),
|
marginTop: theme.spacing(6.25),
|
||||||
border: '1px solid rgba(0,0,0,0.1)',
|
border: `1px solid ${theme.palette.customColors.black(0.07)}`,
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
height: '29.219rem',
|
height: '29.219rem',
|
||||||
},
|
},
|
||||||
|
@ -42,10 +63,22 @@ const useStyles = makeStyles((theme) => ({
|
||||||
},
|
},
|
||||||
headerStatus: {
|
headerStatus: {
|
||||||
paddingLeft: theme.spacing(10),
|
paddingLeft: theme.spacing(10),
|
||||||
color: 'rgba(0, 0, 0, 0.4)',
|
color: theme.palette.customColors.black(0.4),
|
||||||
},
|
},
|
||||||
headerStatus1: {
|
workflowName: {
|
||||||
paddingLeft: theme.spacing(8),
|
borderRight: `1px solid ${theme.palette.customColors.black(0.1)}`,
|
||||||
|
color: theme.palette.customColors.black(0.4),
|
||||||
|
},
|
||||||
|
sortDiv: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
paddingLeft: theme.spacing(1.25),
|
||||||
|
},
|
||||||
|
headData: {
|
||||||
|
color: theme.palette.customColors.black(0.4),
|
||||||
|
},
|
||||||
|
tableDataStatus: {
|
||||||
|
paddingLeft: theme.spacing(8.5),
|
||||||
},
|
},
|
||||||
progressBar: {
|
progressBar: {
|
||||||
width: '6.5rem',
|
width: '6.5rem',
|
||||||
|
@ -53,23 +86,13 @@ const useStyles = makeStyles((theme) => ({
|
||||||
steps: {
|
steps: {
|
||||||
marginLeft: theme.spacing(5.625),
|
marginLeft: theme.spacing(5.625),
|
||||||
},
|
},
|
||||||
menuItem: {
|
|
||||||
paddingLeft: theme.spacing(1.75),
|
|
||||||
},
|
|
||||||
workflowName: {
|
|
||||||
borderRight: '1px solid rgba(0,0,0,0.1)',
|
|
||||||
color: theme.palette.customColors.black(0.4),
|
|
||||||
},
|
|
||||||
workflowNameData: {
|
workflowNameData: {
|
||||||
borderRight: '1px solid rgba(0,0,0,0.1)',
|
borderRight: `1px solid ${theme.palette.customColors.black(0.1)}`,
|
||||||
},
|
},
|
||||||
targetCluster: {
|
targetCluster: {
|
||||||
paddingLeft: theme.spacing(3.75),
|
paddingLeft: theme.spacing(3.75),
|
||||||
color: theme.palette.customColors.black(0.4),
|
color: theme.palette.customColors.black(0.4),
|
||||||
},
|
},
|
||||||
headData: {
|
|
||||||
color: theme.palette.customColors.black(0.4),
|
|
||||||
},
|
|
||||||
clusterName: {
|
clusterName: {
|
||||||
marginLeft: theme.spacing(3.75),
|
marginLeft: theme.spacing(3.75),
|
||||||
},
|
},
|
||||||
|
@ -86,11 +109,6 @@ const useStyles = makeStyles((theme) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
sortDiv: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
paddingLeft: theme.spacing(1.25),
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useStyles;
|
export default useStyles;
|
||||||
|
|
|
@ -11,47 +11,52 @@ import {
|
||||||
import MoreVertIcon from '@material-ui/icons/MoreVert';
|
import MoreVertIcon from '@material-ui/icons/MoreVert';
|
||||||
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
||||||
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
||||||
|
import moment from 'moment';
|
||||||
import useStyles from './styles';
|
import useStyles from './styles';
|
||||||
import LinearProgressBar from '../../ReturningHome/ProgressBar/LinearProgressBar';
|
import LinearProgressBar from '../../ReturningHome/ProgressBar/LinearProgressBar';
|
||||||
import { history } from '../../../../redux/configureStore';
|
import { history } from '../../../../redux/configureStore';
|
||||||
|
import { WorkflowRun } from '../../../../models/workflowData';
|
||||||
|
|
||||||
interface TableDataProps {
|
interface TableDataProps {
|
||||||
data: any;
|
data: WorkflowRun;
|
||||||
|
deleteRow: (workflowId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TableData: React.FC<TableDataProps> = ({ data }) => {
|
const TableData: React.FC<TableDataProps> = ({ data, deleteRow }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
|
// States for PopOver to display Experiment Weights
|
||||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
const [popAnchorEl, setPopAnchorEl] = React.useState<null | HTMLElement>(
|
const [popAnchorEl, setPopAnchorEl] = React.useState<null | HTMLElement>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
|
||||||
setAnchorEl(event.currentTarget);
|
|
||||||
};
|
|
||||||
const isOpen = Boolean(popAnchorEl);
|
const isOpen = Boolean(popAnchorEl);
|
||||||
const id = isOpen ? 'simple-popover' : undefined;
|
const id = isOpen ? 'simple-popover' : undefined;
|
||||||
const handlePopOverClose = () => {
|
const handlePopOverClose = () => {
|
||||||
setPopAnchorEl(null);
|
setPopAnchorEl(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePopOverClick = (event: React.MouseEvent<HTMLElement>) => {
|
const handlePopOverClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
setPopAnchorEl(event.currentTarget);
|
setPopAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
const handleMenu = () => {};
|
|
||||||
|
|
||||||
|
// Function to convert UNIX time in format of DD MMM YYY
|
||||||
const formatDate = (date: any) => {
|
const formatDate = (date: any) => {
|
||||||
const updated = new Date(date * 1000).toString();
|
const updated = new Date(date * 1000).toString();
|
||||||
const day = updated.slice(8, 10);
|
const resDate = moment(updated).format('DD MMM YYYY');
|
||||||
const month = updated.slice(4, 7);
|
|
||||||
const year = updated.slice(11, 15);
|
|
||||||
const resDate = `${day} ${month} ${year}`;
|
|
||||||
return resDate;
|
return resDate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Dummy Experiment Weights
|
||||||
const exWeight = [
|
const exWeight = [
|
||||||
{
|
{
|
||||||
name: 'Node add test',
|
name: 'Node add test',
|
||||||
|
@ -103,7 +108,7 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
||||||
<KeyboardArrowDownIcon className={classes.expInfo} />
|
<KeyboardArrowDownIcon className={classes.expInfo} />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={classes.expDiv1}>
|
<div className={classes.expDiv}>
|
||||||
<Typography>
|
<Typography>
|
||||||
<strong>Show Experiment</strong>
|
<strong>Show Experiment</strong>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -180,7 +185,10 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
||||||
<Typography className={classes.btnText}>Edit Schedule</Typography>
|
<Typography className={classes.btnText}>Edit Schedule</Typography>
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value="Analysis" onClick={handleMenu}>
|
<MenuItem
|
||||||
|
value="Analysis"
|
||||||
|
onClick={() => deleteRow(data.workflow_id)}
|
||||||
|
>
|
||||||
<div className={classes.expDiv}>
|
<div className={classes.expDiv}>
|
||||||
<img
|
<img
|
||||||
src="/icons/deleteSchedule.svg"
|
src="/icons/deleteSchedule.svg"
|
||||||
|
|
|
@ -16,13 +16,27 @@ import {
|
||||||
TableCell,
|
TableCell,
|
||||||
TableBody,
|
TableBody,
|
||||||
TablePagination,
|
TablePagination,
|
||||||
|
IconButton,
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
|
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
|
||||||
|
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import useStyles from './styles';
|
import useStyles from './styles';
|
||||||
import { WORKFLOW_DETAILS } from '../../../../graphql';
|
import { WORKFLOW_DETAILS } from '../../../../graphql';
|
||||||
import TableData from './TableData';
|
import TableData from './TableData';
|
||||||
import { Workflow, WorkflowDataVars } from '../../../../models/workflowData';
|
import {
|
||||||
|
Workflow,
|
||||||
|
WorkflowDataVars,
|
||||||
|
WorkflowRun,
|
||||||
|
ExecutionData,
|
||||||
|
} from '../../../../models/workflowData';
|
||||||
import Loader from '../../../Loader';
|
import Loader from '../../../Loader';
|
||||||
|
import {
|
||||||
|
sortAlphaAsc,
|
||||||
|
sortAlphaDesc,
|
||||||
|
sortNumAsc,
|
||||||
|
sortNumDesc,
|
||||||
|
} from '../../../../utils/sort';
|
||||||
import { UserData } from '../../../../models/user';
|
import { UserData } from '../../../../models/user';
|
||||||
import { RootState } from '../../../../redux/reducers';
|
import { RootState } from '../../../../redux/reducers';
|
||||||
|
|
||||||
|
@ -36,6 +50,11 @@ interface PaginationData {
|
||||||
rowsPerPage: number;
|
rowsPerPage: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SortData {
|
||||||
|
startDate: { sort: boolean; ascending: boolean };
|
||||||
|
name: { sort: boolean; ascending: boolean };
|
||||||
|
}
|
||||||
|
|
||||||
const ScheduleWorkflow = () => {
|
const ScheduleWorkflow = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const userData: UserData = useSelector((state: RootState) => state.userData);
|
const userData: UserData = useSelector((state: RootState) => state.userData);
|
||||||
|
@ -59,6 +78,12 @@ const ScheduleWorkflow = () => {
|
||||||
rowsPerPage: 5,
|
rowsPerPage: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// State for sorting
|
||||||
|
const [sortData, setSortData] = useState<SortData>({
|
||||||
|
name: { sort: false, ascending: true },
|
||||||
|
startDate: { sort: true, ascending: true },
|
||||||
|
});
|
||||||
|
|
||||||
const filteredData = data?.getWorkFlowRuns
|
const filteredData = data?.getWorkFlowRuns
|
||||||
.filter((dataRow) =>
|
.filter((dataRow) =>
|
||||||
dataRow.workflow_name.toLowerCase().includes(filter.search)
|
dataRow.workflow_name.toLowerCase().includes(filter.search)
|
||||||
|
@ -68,12 +93,41 @@ const ScheduleWorkflow = () => {
|
||||||
? true
|
? true
|
||||||
: dataRow.cluster_name.toLowerCase().includes(filter.cluster)
|
: dataRow.cluster_name.toLowerCase().includes(filter.cluster)
|
||||||
)
|
)
|
||||||
.reverse();
|
.sort((a: WorkflowRun, b: WorkflowRun) => {
|
||||||
|
// Sorting based on unique fields
|
||||||
|
if (sortData.name.sort) {
|
||||||
|
const x = a.workflow_name;
|
||||||
|
const y = b.workflow_name;
|
||||||
|
|
||||||
|
return sortData.name.ascending
|
||||||
|
? sortAlphaAsc(x, y)
|
||||||
|
: sortAlphaDesc(x, y);
|
||||||
|
}
|
||||||
|
if (sortData.startDate.sort) {
|
||||||
|
const x = parseInt(
|
||||||
|
(JSON.parse(a.execution_data) as ExecutionData).startedAt,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
|
||||||
|
const y = parseInt(
|
||||||
|
(JSON.parse(b.execution_data) as ExecutionData).startedAt,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
|
||||||
|
return sortData.startDate.ascending
|
||||||
|
? sortNumAsc(y, x)
|
||||||
|
: sortNumDesc(y, x);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
const deleteRow = () => {
|
||||||
|
// Delete Mutation Here
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<section className="Heading section">
|
<section className="Heading section">
|
||||||
<div className={classes.headerSection}>
|
<div className={classes.headerSection}>
|
||||||
|
{/* Search Field */}
|
||||||
<InputBase
|
<InputBase
|
||||||
id="input-with-icon-adornment"
|
id="input-with-icon-adornment"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
|
@ -88,59 +142,126 @@ const ScheduleWorkflow = () => {
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<FormControl className={classes.select}>
|
{/* Select Cluster */}
|
||||||
<InputLabel id="demo-simple-select-outlined-label">
|
<FormControl
|
||||||
|
variant="outlined"
|
||||||
|
className={classes.formControl}
|
||||||
|
color="secondary"
|
||||||
|
focused
|
||||||
|
>
|
||||||
|
<InputLabel className={classes.selectText}>
|
||||||
Target Cluster
|
Target Cluster
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
labelId="demo-simple-select-outlined-label"
|
|
||||||
id="demo-simple-select-outlined"
|
|
||||||
value={filter.cluster}
|
value={filter.cluster}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setFilter({ ...filter, cluster: event.target.value as string })
|
setFilter({ ...filter, cluster: event.target.value as string })
|
||||||
}
|
}
|
||||||
disableUnderline
|
label="Target Cluster"
|
||||||
|
className={classes.selectText}
|
||||||
>
|
>
|
||||||
<MenuItem value="All">
|
<MenuItem value="All">All</MenuItem>
|
||||||
<Typography className={classes.menuItem}>All</Typography>
|
<MenuItem value="Predefined">Cluset pre-defined</MenuItem>
|
||||||
</MenuItem>
|
<MenuItem value="Kubernetes">Kubernetes Cluster</MenuItem>
|
||||||
<MenuItem value="Predefined">
|
|
||||||
<Typography className={classes.menuItem}>
|
|
||||||
Cluset pre-defined
|
|
||||||
</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value="Kubernetes">
|
|
||||||
<Typography className={classes.menuItem}>
|
|
||||||
Kubernetes Cluster
|
|
||||||
</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="table section">
|
<section className="table section">
|
||||||
|
{/* Table Header */}
|
||||||
<TableContainer className={classes.tableMain}>
|
<TableContainer className={classes.tableMain}>
|
||||||
<Table stickyHeader aria-label="simple table">
|
<Table stickyHeader aria-label="simple table">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow className={classes.tableHead}>
|
<TableRow className={classes.tableHead}>
|
||||||
|
{/* WorkFlow Name */}
|
||||||
<TableCell className={classes.workflowName}>
|
<TableCell className={classes.workflowName}>
|
||||||
<Typography style={{ paddingLeft: 65 }}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
Workflow Name
|
<Typography style={{ paddingLeft: 65, paddingTop: 10 }}>
|
||||||
</Typography>
|
Workflow Name
|
||||||
|
</Typography>
|
||||||
|
<div className={classes.sortDiv}>
|
||||||
|
<IconButton
|
||||||
|
aria-label="sort name ascending"
|
||||||
|
size="small"
|
||||||
|
onClick={() =>
|
||||||
|
setSortData({
|
||||||
|
...sortData,
|
||||||
|
name: { sort: true, ascending: true },
|
||||||
|
startDate: { sort: false, ascending: true },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ExpandLessIcon fontSize="inherit" />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
aria-label="sort name descending"
|
||||||
|
size="small"
|
||||||
|
onClick={() =>
|
||||||
|
setSortData({
|
||||||
|
...sortData,
|
||||||
|
name: { sort: true, ascending: false },
|
||||||
|
startDate: { sort: false, ascending: false },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ExpandMoreIcon fontSize="inherit" />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
{/* Starting Date */}
|
||||||
<TableCell className={classes.headerStatus}>
|
<TableCell className={classes.headerStatus}>
|
||||||
Starting Date
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
|
<Typography style={{ paddingTop: 10 }}>
|
||||||
|
Starting Date
|
||||||
|
</Typography>
|
||||||
|
<div className={classes.sortDiv}>
|
||||||
|
<IconButton
|
||||||
|
aria-label="sort last run ascending"
|
||||||
|
size="small"
|
||||||
|
onClick={() =>
|
||||||
|
setSortData({
|
||||||
|
...sortData,
|
||||||
|
startDate: { sort: true, ascending: true },
|
||||||
|
name: { sort: false, ascending: true },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ExpandLessIcon fontSize="inherit" />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
aria-label="sort last run descending"
|
||||||
|
size="small"
|
||||||
|
onClick={() =>
|
||||||
|
setSortData({
|
||||||
|
...sortData,
|
||||||
|
startDate: { sort: true, ascending: false },
|
||||||
|
name: { sort: false, ascending: true },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ExpandMoreIcon fontSize="inherit" />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
{/* Regularity */}
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography className={classes.regularity}>
|
<Typography className={classes.regularity}>
|
||||||
Regularity
|
Regularity
|
||||||
</Typography>
|
</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
{/* Cluster */}
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography className={classes.targetCluster}>
|
<Typography className={classes.targetCluster}>
|
||||||
Cluster
|
Cluster
|
||||||
</Typography>
|
</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
{/* Show Experiments */}
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography className={classes.showExp}>
|
<Typography className={classes.showExp}>
|
||||||
Show Experiments
|
Show Experiments
|
||||||
|
@ -169,9 +290,9 @@ const ScheduleWorkflow = () => {
|
||||||
paginationData.pageNo * paginationData.rowsPerPage +
|
paginationData.pageNo * paginationData.rowsPerPage +
|
||||||
paginationData.rowsPerPage
|
paginationData.rowsPerPage
|
||||||
)
|
)
|
||||||
.map((data: any) => (
|
.map((data) => (
|
||||||
<TableRow key={data.workflow_run_id}>
|
<TableRow key={data.workflow_run_id}>
|
||||||
<TableData data={data} />
|
<TableData data={data} deleteRow={deleteRow} />
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
|
@ -184,6 +305,8 @@ const ScheduleWorkflow = () => {
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
|
||||||
|
{/* Pagination Section */}
|
||||||
<TablePagination
|
<TablePagination
|
||||||
rowsPerPageOptions={[5, 10, 25]}
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
component="div"
|
component="div"
|
||||||
|
|
|
@ -1,27 +1,39 @@
|
||||||
import { makeStyles } from '@material-ui/core';
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
// Header Section Properties
|
||||||
headerSection: {
|
headerSection: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
height: '5.625rem',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignContent: 'center',
|
alignContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
border: '1px solid ',
|
border: '1px solid ',
|
||||||
borderColor: theme.palette.text.hint,
|
borderColor: theme.palette.customColors.black(0.07),
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
|
fontSize: 14,
|
||||||
marginRight: 'auto',
|
marginRight: 'auto',
|
||||||
|
borderBottom: `1px solid ${theme.palette.customColors.black(0.1)}`,
|
||||||
marginLeft: theme.spacing(6.25),
|
marginLeft: theme.spacing(6.25),
|
||||||
},
|
},
|
||||||
select: {
|
|
||||||
width: '10.375rem',
|
// Form Select Properties
|
||||||
marginLeft: theme.spacing(1.25),
|
formControl: {
|
||||||
paddingBottom: theme.spacing(2.5),
|
margin: theme.spacing(0.5),
|
||||||
marginRight: theme.spacing(3.75),
|
marginRight: theme.spacing(6.25),
|
||||||
|
height: '2.5rem',
|
||||||
|
minWidth: '9rem',
|
||||||
},
|
},
|
||||||
|
selectText: {
|
||||||
|
height: '2.5rem',
|
||||||
|
padding: theme.spacing(0.5),
|
||||||
|
},
|
||||||
|
|
||||||
|
// Table and Table Data Properties
|
||||||
headerText: {
|
headerText: {
|
||||||
marginLeft: theme.spacing(3.75),
|
marginLeft: theme.spacing(3.75),
|
||||||
color: theme.palette.text.disabled,
|
color: theme.palette.text.disabled,
|
||||||
|
@ -29,9 +41,9 @@ const useStyles = makeStyles((theme) => ({
|
||||||
},
|
},
|
||||||
tableMain: {
|
tableMain: {
|
||||||
marginTop: theme.spacing(6.25),
|
marginTop: theme.spacing(6.25),
|
||||||
border: '1px solid rgba(0,0,0,0.1)',
|
border: `1px solid ${theme.palette.customColors.black(0.07)}`,
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
height: '29.180rem',
|
height: '29.220rem',
|
||||||
},
|
},
|
||||||
tableHead: {
|
tableHead: {
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
|
@ -54,11 +66,16 @@ const useStyles = makeStyles((theme) => ({
|
||||||
paddingLeft: theme.spacing(1.75),
|
paddingLeft: theme.spacing(1.75),
|
||||||
},
|
},
|
||||||
workflowName: {
|
workflowName: {
|
||||||
borderRight: '1px solid rgba(0,0,0,0.1)',
|
borderRight: `1px solid ${theme.palette.customColors.black(0.1)}`,
|
||||||
color: theme.palette.customColors.black(0.4),
|
color: theme.palette.customColors.black(0.4),
|
||||||
},
|
},
|
||||||
|
sortDiv: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
marginLeft: theme.spacing(1.25),
|
||||||
|
},
|
||||||
workflowNameData: {
|
workflowNameData: {
|
||||||
borderRight: '1px solid rgba(0,0,0,0.1)',
|
borderRight: `1px solid ${theme.palette.customColors.black(0.1)}`,
|
||||||
},
|
},
|
||||||
regularity: {
|
regularity: {
|
||||||
paddingLeft: theme.spacing(3.75),
|
paddingLeft: theme.spacing(3.75),
|
||||||
|
@ -84,24 +101,6 @@ const useStyles = makeStyles((theme) => ({
|
||||||
paddingLeft: theme.spacing(1),
|
paddingLeft: theme.spacing(1),
|
||||||
color: theme.palette.customColors.black(0.4),
|
color: theme.palette.customColors.black(0.4),
|
||||||
},
|
},
|
||||||
expDiv: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
},
|
|
||||||
expDiv1: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
cursor: 'pointer',
|
|
||||||
},
|
|
||||||
weightDiv: {
|
|
||||||
width: 243,
|
|
||||||
padding: '25px 20px',
|
|
||||||
},
|
|
||||||
weightInfo: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
paddingBottom: theme.spacing(0.625),
|
|
||||||
},
|
|
||||||
clusterData: {
|
clusterData: {
|
||||||
paddingTop: theme.spacing(1.25),
|
paddingTop: theme.spacing(1.25),
|
||||||
},
|
},
|
||||||
|
@ -123,6 +122,22 @@ const useStyles = makeStyles((theme) => ({
|
||||||
btnText: {
|
btnText: {
|
||||||
paddingLeft: theme.spacing(1.625),
|
paddingLeft: theme.spacing(1.625),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Experiment Weights PopOver Property
|
||||||
|
weightDiv: {
|
||||||
|
width: '15.1875rem',
|
||||||
|
padding: theme.spacing(3.125, 2.6),
|
||||||
|
},
|
||||||
|
weightInfo: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
paddingBottom: theme.spacing(0.625),
|
||||||
|
},
|
||||||
|
expDiv: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
cursor: 'pointer',
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useStyles;
|
export default useStyles;
|
||||||
|
|
Loading…
Reference in New Issue