type(ux): Removed templates tab and minor change in jobCleanUpPolicy (#2886)
* Updated MyHub UI and minor change in jobCleanUpPolicy and removed templates tab * Removed files related to templates * Minor styles fix Signed-off-by: Amit Kumar Das <amit@chaosnative.com>
This commit is contained in:
parent
2913b0fcbd
commit
245f333448
|
@ -1,54 +0,0 @@
|
||||||
export default [
|
|
||||||
{
|
|
||||||
workflowID: 0,
|
|
||||||
title: 'sock-shop-chaos',
|
|
||||||
chaosinfra: false,
|
|
||||||
urlToIcon: '/icons/sock-shop.png',
|
|
||||||
chaosWkfCRDLink: `https://raw.githubusercontent.com/litmuschaos/chaos-charts/${process.env.REACT_APP_HUB_BRANCH_NAME}/workflows/sock-shop-demo/usingCmdProbe/workflow.yaml`,
|
|
||||||
chaosWkfCRDLink_Recur: `https://raw.githubusercontent.com/litmuschaos/chaos-charts/${process.env.REACT_APP_HUB_BRANCH_NAME}/workflows/sock-shop-demo/usingCmdProbe/workflow_cron.yaml`,
|
|
||||||
gitLink: `https://github.com/litmuschaos/chaos-charts/${process.env.REACT_APP_HUB_BRANCH_NAME}/workflows/sock-shop-demo`,
|
|
||||||
experimentPath: 'sock-shop-demo/usingCmdProbe',
|
|
||||||
provider: 'ChaosNative',
|
|
||||||
description: 'Induces chaos on Sock-Shop application',
|
|
||||||
totalRuns: 1000,
|
|
||||||
isCustom: false,
|
|
||||||
details:
|
|
||||||
'This workflow installs and executes chaos on the popular demo application sock-shop, ' +
|
|
||||||
'that simulates an e-commerce website selling socks. It injects a transient fault on an upstream microservice ' +
|
|
||||||
'pod (socks catalogue) while continuously checking the availability of the website. This workflow allows execution ' +
|
|
||||||
'of the same chaos experiment against two versions of the sock-shop deployment: weak and resilient. ' +
|
|
||||||
'The weak is expected to result in a failed workflow while the resilient succeeds, ' +
|
|
||||||
'essentially highlighting the need for deployment best-practices.',
|
|
||||||
recommendation:
|
|
||||||
'Check whether the application is resilient to the pod failure, once the workflow is completed.',
|
|
||||||
experimentinfo:
|
|
||||||
'Provide the application info in spec.appinfo Override the experiment tunables if desired in experiments.spec.components.env',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
workflowID: 1,
|
|
||||||
title: 'podtato-head-chaos',
|
|
||||||
chaosinfra: false,
|
|
||||||
urlToIcon: '/icons/podtato_head.png',
|
|
||||||
chaosWkfCRDLink: `https://raw.githubusercontent.com/litmuschaos/chaos-charts/${process.env.REACT_APP_HUB_BRANCH_NAME}/workflows/podtato-head/workflow.yaml`,
|
|
||||||
chaosWkfCRDLink_Recur: `https://raw.githubusercontent.com/litmuschaos/chaos-charts/${process.env.REACT_APP_HUB_BRANCH_NAME}/workflows/podtato-head/workflow_cron.yaml`,
|
|
||||||
gitLink: `https://github.com/litmuschaos/chaos-charts/tree/${process.env.REACT_APP_HUB_BRANCH_NAME}/workflows/podtato-head`,
|
|
||||||
experimentPath: 'podtato-head',
|
|
||||||
provider: 'ChaosNative',
|
|
||||||
description: 'Induces chaos on podtato-head application',
|
|
||||||
totalRuns: 300,
|
|
||||||
isCustom: false,
|
|
||||||
details:
|
|
||||||
'This workflow installs and executes chaos on the popular demo application podtato-head, ' +
|
|
||||||
'A demo project for showcasing cloud-native application delivery use cases using different tools for various use cases.' +
|
|
||||||
'It injects a transient fault on an upstream microservice ' +
|
|
||||||
'pod while continuously checking the availability of the website. This workflow allows execution ' +
|
|
||||||
'of the same chaos experiment against two versions of the podtato-head deployment: weak and resilient. ' +
|
|
||||||
'The weak is expected to result in a failed workflow while the resilient succeeds, ' +
|
|
||||||
'essentially highlighting the need for deployment best-practices.',
|
|
||||||
recommendation:
|
|
||||||
'Check whether the application is resilient to the pod failure, once the workflow is completed.',
|
|
||||||
experimentinfo:
|
|
||||||
'Provide the application info in spec.appinfo Override the experiment tunables if desired ' +
|
|
||||||
'in experiments.spec.components.env ',
|
|
||||||
},
|
|
||||||
];
|
|
|
@ -1,72 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { preDefinedWorkflowData } from '../../models/predefinedWorkflow';
|
|
||||||
import useActions from '../../redux/actions';
|
|
||||||
import * as WorkflowActions from '../../redux/actions/workflow';
|
|
||||||
import { history } from '../../redux/configureStore';
|
|
||||||
import { getProjectID, getProjectRole } from '../../utils/getSearchParams';
|
|
||||||
import CustomCard from '../WorkflowCard';
|
|
||||||
import CustomWorkflowCard from '../WorkflowCard/CustomWorkflow';
|
|
||||||
import useStyles from './styles';
|
|
||||||
|
|
||||||
interface PredifinedWorkflowsProps {
|
|
||||||
workflows: preDefinedWorkflowData[];
|
|
||||||
callbackOnSelectWorkflow: (index: number) => void;
|
|
||||||
isCustomWorkflowVisible: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PredifinedWorkflows: React.FC<PredifinedWorkflowsProps> = ({
|
|
||||||
workflows,
|
|
||||||
callbackOnSelectWorkflow,
|
|
||||||
isCustomWorkflowVisible,
|
|
||||||
}) => {
|
|
||||||
const workflowAction = useActions(WorkflowActions);
|
|
||||||
const projectID = getProjectID();
|
|
||||||
const userRole = getProjectRole();
|
|
||||||
const classes = useStyles();
|
|
||||||
return (
|
|
||||||
<div className={classes.root} data-cy="PredefinedWorkflowsPanel">
|
|
||||||
{workflows &&
|
|
||||||
workflows.map((w: preDefinedWorkflowData, index: number) => (
|
|
||||||
<div key={w.workflowID} data-cy="templatesCard">
|
|
||||||
<CustomCard
|
|
||||||
key={w.workflowID}
|
|
||||||
title={w.title}
|
|
||||||
urlToIcon={w.urlToIcon}
|
|
||||||
chaosinfra={w.chaosinfra}
|
|
||||||
provider={w.provider}
|
|
||||||
chaosWkfCRDLink={w.chaosWkfCRDLink}
|
|
||||||
selectedID={w.workflowID}
|
|
||||||
handleClick={() => callbackOnSelectWorkflow(index)}
|
|
||||||
description={w.description}
|
|
||||||
totalRuns={w.totalRuns}
|
|
||||||
gitLink={w.gitLink}
|
|
||||||
workflowID={w.workflowID}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
{isCustomWorkflowVisible && (
|
|
||||||
<div data-cy="CustomWorkflowCard">
|
|
||||||
<CustomWorkflowCard
|
|
||||||
handleClick={() => {
|
|
||||||
workflowAction.setWorkflowDetails({
|
|
||||||
name: `custom-chaos-workflow-${Math.round(
|
|
||||||
new Date().getTime() / 1000
|
|
||||||
)}`,
|
|
||||||
description: 'Custom Chaos Workflow',
|
|
||||||
isCustomWorkflow: true,
|
|
||||||
namespace: 'litmus',
|
|
||||||
customWorkflows: [],
|
|
||||||
});
|
|
||||||
history.push({
|
|
||||||
pathname: '/create-workflow/custom',
|
|
||||||
search: `?projectID=${projectID}&projectRole=${userRole}`,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PredifinedWorkflows;
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { makeStyles } from '@material-ui/core';
|
|
||||||
|
|
||||||
const useStyles = makeStyles(() => ({
|
|
||||||
root: {
|
|
||||||
display: 'flex',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
flexDirection: 'row',
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 0,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default useStyles;
|
|
|
@ -17,9 +17,6 @@ const CreateWorkflow = lazy(() => import('../../pages/CreateWorkflow'));
|
||||||
const LoginPage = lazy(() => import('../../pages/LoginPage'));
|
const LoginPage = lazy(() => import('../../pages/LoginPage'));
|
||||||
const GetStarted = lazy(() => import('../../pages/GetStartedPage'));
|
const GetStarted = lazy(() => import('../../pages/GetStartedPage'));
|
||||||
const WorkflowDetails = lazy(() => import('../../pages/WorkflowDetails'));
|
const WorkflowDetails = lazy(() => import('../../pages/WorkflowDetails'));
|
||||||
const BrowseTemplate = lazy(
|
|
||||||
() => import('../../views/ChaosWorkflows/BrowseTemplate')
|
|
||||||
);
|
|
||||||
const HomePage = lazy(() => import('../../pages/HomePage'));
|
const HomePage = lazy(() => import('../../pages/HomePage'));
|
||||||
const Community = lazy(() => import('../../pages/Community'));
|
const Community = lazy(() => import('../../pages/Community'));
|
||||||
const Settings = lazy(() => import('../../pages/Settings'));
|
const Settings = lazy(() => import('../../pages/Settings'));
|
||||||
|
@ -201,11 +198,6 @@ const Routes: React.FC = () => {
|
||||||
path="/workflows/schedule/:scheduleProjectID/:workflowName/set"
|
path="/workflows/schedule/:scheduleProjectID/:workflowName/set"
|
||||||
component={SetNewSchedule}
|
component={SetNewSchedule}
|
||||||
/>
|
/>
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/workflows/template/:templateName"
|
|
||||||
component={BrowseTemplate}
|
|
||||||
/>
|
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/workflows/analytics/:workflowRunId"
|
path="/workflows/analytics/:workflowRunId"
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { RootState } from '../../redux/reducers';
|
||||||
import { getProjectID, getProjectRole } from '../../utils/getSearchParams';
|
import { getProjectID, getProjectRole } from '../../utils/getSearchParams';
|
||||||
import BrowseSchedule from '../../views/ChaosWorkflows/BrowseSchedule';
|
import BrowseSchedule from '../../views/ChaosWorkflows/BrowseSchedule';
|
||||||
import BrowseWorkflow from '../../views/ChaosWorkflows/BrowseWorkflow';
|
import BrowseWorkflow from '../../views/ChaosWorkflows/BrowseWorkflow';
|
||||||
import Templates from '../../views/ChaosWorkflows/Templates';
|
|
||||||
import useStyles from './styles';
|
import useStyles from './styles';
|
||||||
|
|
||||||
const Workflows = () => {
|
const Workflows = () => {
|
||||||
|
@ -80,10 +79,6 @@ const Workflows = () => {
|
||||||
label={`${t('workflows.schedules')}`}
|
label={`${t('workflows.schedules')}`}
|
||||||
data-cy="browseSchedule"
|
data-cy="browseSchedule"
|
||||||
/>
|
/>
|
||||||
<StyledTab
|
|
||||||
label={`${t('workflows.templates')}`}
|
|
||||||
data-cy="templates"
|
|
||||||
/>
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
<TabPanel value={workflowTabValue} index={0}>
|
<TabPanel value={workflowTabValue} index={0}>
|
||||||
|
@ -92,9 +87,6 @@ const Workflows = () => {
|
||||||
<TabPanel value={workflowTabValue} index={1}>
|
<TabPanel value={workflowTabValue} index={1}>
|
||||||
<BrowseSchedule />
|
<BrowseSchedule />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value={workflowTabValue} index={2}>
|
|
||||||
<Templates />
|
|
||||||
</TabPanel>
|
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { Typography } from '@material-ui/core';
|
|
||||||
import React from 'react';
|
|
||||||
import AdjustedWeight from '../../../components/AdjustedWeights';
|
|
||||||
import useStyles from './styles';
|
|
||||||
|
|
||||||
interface ExperimentDetailsProps {
|
|
||||||
testNames: string[];
|
|
||||||
testWeights: number[];
|
|
||||||
experimentinfo?: string | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ExperimentDetails: React.FC<ExperimentDetailsProps> = ({
|
|
||||||
testNames,
|
|
||||||
testWeights,
|
|
||||||
experimentinfo,
|
|
||||||
}) => {
|
|
||||||
const classes = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Typography className={classes.headerText}>
|
|
||||||
Experiment details:
|
|
||||||
</Typography>
|
|
||||||
<div className={classes.experimentWrapperDiv}>
|
|
||||||
{testNames &&
|
|
||||||
testNames.map((test, i) => {
|
|
||||||
// Mapping all the experiments from a selected workflow
|
|
||||||
return (
|
|
||||||
<div className={classes.tests}>
|
|
||||||
<AdjustedWeight
|
|
||||||
testName={test}
|
|
||||||
testValue={testWeights[i]}
|
|
||||||
spacing
|
|
||||||
icon
|
|
||||||
/>
|
|
||||||
<Typography>{experimentinfo}</Typography>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ExperimentDetails;
|
|
|
@ -1,28 +0,0 @@
|
||||||
import { Typography } from '@material-ui/core';
|
|
||||||
import React from 'react';
|
|
||||||
import capitalize from '../../../utils/capitalize';
|
|
||||||
import useStyles from './styles';
|
|
||||||
|
|
||||||
interface HeadProps {
|
|
||||||
image?: string;
|
|
||||||
title?: string;
|
|
||||||
details?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Head: React.FC<HeadProps> = ({ image, title, details }) => {
|
|
||||||
const classes = useStyles();
|
|
||||||
return (
|
|
||||||
<div className={classes.flexRow}>
|
|
||||||
<img src={image} alt="workflowIcon" className={classes.bgIcon} />
|
|
||||||
<div className={classes.body}>
|
|
||||||
<Typography data-cy="expName" className={classes.headerText}>
|
|
||||||
{/* Converting 'some-experiment' to 'Some Experiment' using capitalize utility */}
|
|
||||||
{title?.split('-').map((text) => `${capitalize(text)} `)}
|
|
||||||
</Typography>
|
|
||||||
<Typography className={classes.bodytext}>{details}</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Head;
|
|
|
@ -1,30 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Typography } from '@material-ui/core';
|
|
||||||
import useStyles from './styles';
|
|
||||||
|
|
||||||
interface RecommendationProps {
|
|
||||||
recommendation?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Recommendation: React.FC<RecommendationProps> = ({ recommendation }) => {
|
|
||||||
const classes = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={classes.flexRow}>
|
|
||||||
<div className={classes.body}>
|
|
||||||
<Typography className={classes.headerText}>
|
|
||||||
<strong>Recommendation</strong>
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<div className={classes.bodytext}>
|
|
||||||
<Typography align="left" className={classes.bodytext}>
|
|
||||||
{recommendation}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<img src="/icons/like.svg" alt="Like" className={classes.bgIcon} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Recommendation;
|
|
|
@ -1,107 +0,0 @@
|
||||||
import { Divider, Typography } from '@material-ui/core';
|
|
||||||
import { ButtonFilled, ButtonOutlined } from 'litmus-ui';
|
|
||||||
import localforage from 'localforage';
|
|
||||||
import React from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import BackButton from '../../../components/Button/BackButton';
|
|
||||||
import data from '../../../components/PredifinedWorkflows/data';
|
|
||||||
import Scaffold from '../../../containers/layouts/Scaffold';
|
|
||||||
import { ChooseWorkflowRadio } from '../../../models/localforage/radioButton';
|
|
||||||
import { preDefinedWorkflowData } from '../../../models/predefinedWorkflow';
|
|
||||||
import { LocationState } from '../../../models/routerModel';
|
|
||||||
import useActions from '../../../redux/actions';
|
|
||||||
import * as WorkflowActions from '../../../redux/actions/workflow';
|
|
||||||
import { history } from '../../../redux/configureStore';
|
|
||||||
import { getProjectID, getProjectRole } from '../../../utils/getSearchParams';
|
|
||||||
import ExperimentDetails from './ExperimentDetails';
|
|
||||||
import Head from './Head';
|
|
||||||
import Recommendation from './Recommendation';
|
|
||||||
import useStyles from './styles';
|
|
||||||
|
|
||||||
interface LocationObjectProps {
|
|
||||||
workflowData: preDefinedWorkflowData;
|
|
||||||
testNames: string[];
|
|
||||||
testWeights: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BrowseTemplateProps {
|
|
||||||
location: LocationState<LocationObjectProps>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BrowseAWorkflow: React.FC<BrowseTemplateProps> = ({ location }) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const classes = useStyles();
|
|
||||||
const projectID = getProjectID();
|
|
||||||
const userRole = getProjectRole();
|
|
||||||
const workflowAction = useActions(WorkflowActions);
|
|
||||||
const { workflowData, testNames, testWeights } = location.state;
|
|
||||||
|
|
||||||
const preSelectWorkflow = () => {
|
|
||||||
data.map((w) => {
|
|
||||||
if (w.title === workflowData.title) {
|
|
||||||
const selection: ChooseWorkflowRadio = {
|
|
||||||
selected: 'A',
|
|
||||||
id: w.workflowID.toString(),
|
|
||||||
};
|
|
||||||
localforage.setItem('selectedScheduleOption', selection);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
workflowAction.setWorkflowDetails({
|
|
||||||
isCustomWorkflow: false,
|
|
||||||
});
|
|
||||||
history.push({
|
|
||||||
pathname: '/create-workflow',
|
|
||||||
search: `?projectID=${projectID}&projectRole=${userRole}`,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Scaffold>
|
|
||||||
<div className={classes.back}>
|
|
||||||
<BackButton />
|
|
||||||
</div>
|
|
||||||
<div className={classes.root}>
|
|
||||||
<Typography className={classes.headerTitle}>
|
|
||||||
{t('browseTemplate.browseAWorkflow')}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="subtitle1" className={classes.bodytext}>
|
|
||||||
{t('browseTemplate.seeDetails')}
|
|
||||||
</Typography>
|
|
||||||
<section className={classes.contentWrapper}>
|
|
||||||
{/* Header */}
|
|
||||||
<Head
|
|
||||||
image={workflowData.urlToIcon}
|
|
||||||
title={workflowData.title}
|
|
||||||
details={workflowData.details}
|
|
||||||
/>
|
|
||||||
<Divider className={classes.m2} />
|
|
||||||
|
|
||||||
{/* Experiment Details */}
|
|
||||||
<ExperimentDetails
|
|
||||||
testNames={testNames}
|
|
||||||
testWeights={testWeights}
|
|
||||||
experimentinfo={workflowData.experimentinfo}
|
|
||||||
/>
|
|
||||||
<Divider className={classes.m2} />
|
|
||||||
|
|
||||||
{/* Recommendation */}
|
|
||||||
<Recommendation recommendation={workflowData.recommendation} />
|
|
||||||
<Divider className={classes.m2} />
|
|
||||||
|
|
||||||
{/* Buttons */}
|
|
||||||
<div className={classes.spaceBetween}>
|
|
||||||
<ButtonOutlined onClick={() => history.goBack()}>
|
|
||||||
{t('browseTemplate.back')}
|
|
||||||
</ButtonOutlined>
|
|
||||||
<ButtonFilled variant="success" onClick={() => preSelectWorkflow()}>
|
|
||||||
{t('browseTemplate.scheduleThisTemplate')}
|
|
||||||
</ButtonFilled>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</Scaffold>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default BrowseAWorkflow;
|
|
|
@ -1,77 +0,0 @@
|
||||||
import { makeStyles, Theme } from '@material-ui/core/styles';
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => ({
|
|
||||||
root: {
|
|
||||||
background: theme.palette.background.paper,
|
|
||||||
width: '90%',
|
|
||||||
margin: '0 auto',
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
},
|
|
||||||
back: {
|
|
||||||
width: '90%',
|
|
||||||
margin: '0 auto',
|
|
||||||
padding: theme.spacing(1, 0),
|
|
||||||
},
|
|
||||||
contentWrapper: {
|
|
||||||
background: theme.palette.cards.background,
|
|
||||||
padding: theme.spacing(1),
|
|
||||||
},
|
|
||||||
headerTitle: {
|
|
||||||
fontSize: '2rem',
|
|
||||||
},
|
|
||||||
bodytext: {
|
|
||||||
marginTop: theme.spacing(3.25),
|
|
||||||
marginBottom: theme.spacing(3),
|
|
||||||
fontSize: '1.0625rem',
|
|
||||||
},
|
|
||||||
m2: {
|
|
||||||
margin: '2rem 0',
|
|
||||||
},
|
|
||||||
spaceBetween: {
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Head
|
|
||||||
|
|
||||||
flexRow: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-even',
|
|
||||||
},
|
|
||||||
headerText: {
|
|
||||||
marginTop: theme.spacing(1.25),
|
|
||||||
fontSize: '1.5625rem',
|
|
||||||
fontWeight: 800,
|
|
||||||
},
|
|
||||||
|
|
||||||
body: {
|
|
||||||
width: '70%',
|
|
||||||
},
|
|
||||||
bgIcon: {
|
|
||||||
width: '7rem',
|
|
||||||
height: '100%',
|
|
||||||
margin: '1rem 3rem',
|
|
||||||
},
|
|
||||||
progress: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
marginLeft: theme.spacing(5),
|
|
||||||
width: theme.spacing(79.5),
|
|
||||||
},
|
|
||||||
|
|
||||||
// Experiment Details
|
|
||||||
|
|
||||||
experimentWrapperDiv: {
|
|
||||||
display: 'grid',
|
|
||||||
margin: theme.spacing(2, 0),
|
|
||||||
gridTemplateColumns: 'repeat(auto-fit, minmax(15rem, 1fr))',
|
|
||||||
gridGap: '1.5rem',
|
|
||||||
},
|
|
||||||
tests: {
|
|
||||||
width: '17rem',
|
|
||||||
margin: theme.spacing(0, 2, 2, 0),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
export default useStyles;
|
|
|
@ -1,72 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PredifinedWorkflows from '../../../components/PredifinedWorkflows';
|
|
||||||
import workflowData from '../../../components/PredifinedWorkflows/data';
|
|
||||||
import useActions from '../../../redux/actions';
|
|
||||||
import * as TemplateSelectionActions from '../../../redux/actions/template';
|
|
||||||
import { history } from '../../../redux/configureStore';
|
|
||||||
import { getProjectID, getProjectRole } from '../../../utils/getSearchParams';
|
|
||||||
import parsed from '../../../utils/yamlUtils';
|
|
||||||
import useStyles from './styles';
|
|
||||||
|
|
||||||
const Templates = () => {
|
|
||||||
const classes = useStyles();
|
|
||||||
const projectID = getProjectID();
|
|
||||||
const projectRole = getProjectRole();
|
|
||||||
|
|
||||||
const template = useActions(TemplateSelectionActions);
|
|
||||||
const testNames: string[] = [];
|
|
||||||
const testWeights: number[] = [];
|
|
||||||
|
|
||||||
// Setting initial selected template ID to 0
|
|
||||||
template.selectTemplate({ selectedTemplateID: -1, isDisable: true });
|
|
||||||
|
|
||||||
const selectWorkflow = (index: number) => {
|
|
||||||
// Updating template ID to the selected one
|
|
||||||
template.selectTemplate({
|
|
||||||
selectedTemplateID: index,
|
|
||||||
isDisable: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch(workflowData[index].chaosWkfCRDLink)
|
|
||||||
.then((data) => {
|
|
||||||
data.text().then((yamlText) => {
|
|
||||||
const tests = parsed(yamlText);
|
|
||||||
tests.forEach((test) => {
|
|
||||||
// Pushing the individual test names of the selected workflow
|
|
||||||
testNames.push(test);
|
|
||||||
|
|
||||||
// The default weight of the all the experiments in the workflow is 10
|
|
||||||
testWeights.push(10);
|
|
||||||
});
|
|
||||||
history.push({
|
|
||||||
pathname: `/workflows/template/${workflowData[index].title}`,
|
|
||||||
search: `?projectID=${projectID}&projectRole=${projectRole}`,
|
|
||||||
state: {
|
|
||||||
workflowData: workflowData[index],
|
|
||||||
testNames,
|
|
||||||
testWeights,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={classes.root}>
|
|
||||||
<div data-cy="templatesPage" className={classes.predefinedCards}>
|
|
||||||
<PredifinedWorkflows
|
|
||||||
callbackOnSelectWorkflow={(index: number) => {
|
|
||||||
selectWorkflow(index);
|
|
||||||
}}
|
|
||||||
workflows={workflowData}
|
|
||||||
isCustomWorkflowVisible={false}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Templates;
|
|
|
@ -1,53 +0,0 @@
|
||||||
import { makeStyles } from '@material-ui/core';
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
|
||||||
root: {
|
|
||||||
width: '90%',
|
|
||||||
margin: '0 auto',
|
|
||||||
marginTop: theme.spacing(2.5),
|
|
||||||
marginBottom: theme.spacing(2.5),
|
|
||||||
},
|
|
||||||
predefinedCards: {
|
|
||||||
display: 'inline-block',
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
padding: '1rem 0.5rem',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
},
|
|
||||||
headerSize: {
|
|
||||||
fontSize: theme.spacing(2),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
// CSS For sort div as well as the icon
|
|
||||||
|
|
||||||
/*
|
|
||||||
sort: {
|
|
||||||
display: 'flex',
|
|
||||||
cursor: 'pointer',
|
|
||||||
},
|
|
||||||
sortIcon: {
|
|
||||||
width: theme.spacing(4),
|
|
||||||
marginRight: theme.spacing(1),
|
|
||||||
position: 'relative',
|
|
||||||
},
|
|
||||||
line: {
|
|
||||||
height: theme.spacing(0.3),
|
|
||||||
width: '100%',
|
|
||||||
margin: '0.3em 0',
|
|
||||||
background: theme.palette.primary.contrastText,
|
|
||||||
borderRadius: '0.5rem',
|
|
||||||
},
|
|
||||||
first: {
|
|
||||||
width: '90%',
|
|
||||||
},
|
|
||||||
second: {
|
|
||||||
width: '60%',
|
|
||||||
},
|
|
||||||
third: {
|
|
||||||
width: '30%',
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default useStyles;
|
|
|
@ -89,7 +89,7 @@ const TargetApplication: React.FC<TargetApplicationProp> = ({
|
||||||
typeof engineManifest.spec.annotationCheck === 'boolean'
|
typeof engineManifest.spec.annotationCheck === 'boolean'
|
||||||
? engineManifest.spec.annotationCheck
|
? engineManifest.spec.annotationCheck
|
||||||
: engineManifest.spec.annotationCheck === 'true',
|
: engineManifest.spec.annotationCheck === 'true',
|
||||||
jobCleanUpPolicy: engineManifest.spec.jobCleanUpPolicy,
|
jobCleanUpPolicy: engineManifest.spec.jobCleanUpPolicy ?? 'retain',
|
||||||
});
|
});
|
||||||
const [addNodeSelector, setAddNodeSelector] = useState<boolean>(
|
const [addNodeSelector, setAddNodeSelector] = useState<boolean>(
|
||||||
!!engineManifest.spec.experiments[0].spec.components['nodeSelectors']
|
!!engineManifest.spec.experiments[0].spec.components['nodeSelectors']
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
import { useQuery } from '@apollo/client';
|
import { useQuery } from '@apollo/client';
|
||||||
import {
|
import { AppBar, Backdrop, Typography } from '@material-ui/core';
|
||||||
Accordion,
|
import Tabs from '@material-ui/core/Tabs';
|
||||||
AccordionDetails,
|
|
||||||
AccordionSummary,
|
|
||||||
Backdrop,
|
|
||||||
Typography,
|
|
||||||
} from '@material-ui/core';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
|
||||||
|
import useTheme from '@material-ui/core/styles/useTheme';
|
||||||
|
import { StyledTab, TabPanel } from '../../../components/Tabs';
|
||||||
import Loader from '../../../components/Loader';
|
import Loader from '../../../components/Loader';
|
||||||
import Center from '../../../containers/layouts/Center';
|
import Center from '../../../containers/layouts/Center';
|
||||||
import Scaffold from '../../../containers/layouts/Scaffold';
|
import Scaffold from '../../../containers/layouts/Scaffold';
|
||||||
|
@ -44,6 +41,8 @@ const MyHub: React.FC = () => {
|
||||||
variables: { data: projectID },
|
variables: { data: projectID },
|
||||||
fetchPolicy: 'cache-and-network',
|
fetchPolicy: 'cache-and-network',
|
||||||
});
|
});
|
||||||
|
const theme = useTheme();
|
||||||
|
const [tabValue, setTabValue] = useState(1);
|
||||||
|
|
||||||
// Filter the selected MyHub
|
// Filter the selected MyHub
|
||||||
const UserHub = hubDetails?.getHubStatus.filter((myHub) => {
|
const UserHub = hubDetails?.getHubStatus.filter((myHub) => {
|
||||||
|
@ -99,12 +98,9 @@ const MyHub: React.FC = () => {
|
||||||
return 'Date not available';
|
return 'Date not available';
|
||||||
};
|
};
|
||||||
|
|
||||||
const [expanded, setExpanded] = React.useState<string | false>('panel2');
|
const handleTabChange = (event: React.ChangeEvent<{}>, newValue: number) => {
|
||||||
|
setTabValue(newValue);
|
||||||
const handleChange =
|
};
|
||||||
(panel: string) => (event: React.ChangeEvent<{}>, newExpanded: boolean) => {
|
|
||||||
setExpanded(newExpanded ? panel : false);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
|
@ -165,117 +161,99 @@ const MyHub: React.FC = () => {
|
||||||
</Typography>
|
</Typography>
|
||||||
{/* </div> */}
|
{/* </div> */}
|
||||||
</div>
|
</div>
|
||||||
<Accordion
|
<AppBar position="static" color="default" className={classes.appBar}>
|
||||||
square
|
<Tabs
|
||||||
classes={{
|
value={tabValue}
|
||||||
root: classes.MuiAccordionroot,
|
onChange={handleTabChange}
|
||||||
}}
|
TabIndicatorProps={{
|
||||||
expanded={expanded === 'panel1'}
|
style: {
|
||||||
onChange={handleChange('panel1')}
|
backgroundColor: theme.palette.highlight,
|
||||||
>
|
},
|
||||||
<AccordionSummary
|
}}
|
||||||
expandIcon={<ExpandMoreIcon />}
|
variant="fullWidth"
|
||||||
aria-controls="panel1d-content"
|
|
||||||
id="panel1d-header"
|
|
||||||
>
|
>
|
||||||
<Typography variant="h4">
|
<StyledTab
|
||||||
<strong>{t('myhub.myhubChart.preDefined')}</strong>
|
label={`${t('myhub.myhubChart.preDefined')}`}
|
||||||
</Typography>
|
data-cy="browseWorkflow"
|
||||||
</AccordionSummary>
|
/>
|
||||||
<AccordionDetails>
|
<StyledTab
|
||||||
<div className={classes.mainDiv}>
|
label={`${t('myhub.myhubChart.chaosCharts')}`}
|
||||||
<HeaderSection
|
data-cy="browseSchedule"
|
||||||
searchValue={searchPredefined}
|
/>
|
||||||
changeSearch={handlePreDefinedSearch}
|
</Tabs>
|
||||||
/>
|
</AppBar>
|
||||||
<div className={classes.chartsGroup}>
|
<TabPanel value={tabValue} index={0}>
|
||||||
{filteredWorkflow?.length > 0 ? (
|
<div className={classes.mainDiv}>
|
||||||
filteredWorkflow.map((expName: string) => {
|
<HeaderSection
|
||||||
return (
|
searchValue={searchPredefined}
|
||||||
<ChartCard
|
changeSearch={handlePreDefinedSearch}
|
||||||
key={expName}
|
/>
|
||||||
expName={{
|
<div className={classes.chartsGroup}>
|
||||||
ChaosName: 'predefined',
|
{filteredWorkflow?.length > 0 ? (
|
||||||
ExperimentName: expName,
|
filteredWorkflow.map((expName: string) => {
|
||||||
}}
|
return (
|
||||||
UserHub={UserHub}
|
<ChartCard
|
||||||
setSearch={setSearchPredefined}
|
key={expName}
|
||||||
projectID={projectID}
|
expName={{
|
||||||
userRole={getProjectRole()}
|
ChaosName: 'predefined',
|
||||||
isPredefined
|
ExperimentName: expName,
|
||||||
/>
|
}}
|
||||||
);
|
UserHub={UserHub}
|
||||||
})
|
setSearch={setSearchPredefined}
|
||||||
) : (
|
projectID={projectID}
|
||||||
<>
|
userRole={getProjectRole()}
|
||||||
<img
|
isPredefined
|
||||||
src="/icons/no-experiment-found.svg"
|
|
||||||
alt="no experiment"
|
|
||||||
width="80px"
|
|
||||||
height="80px"
|
|
||||||
/>
|
/>
|
||||||
<Typography variant="h5" className={classes.noExp}>
|
);
|
||||||
{t('myhub.myhubChart.noPredefinedExp')}
|
})
|
||||||
</Typography>
|
) : (
|
||||||
</>
|
<>
|
||||||
)}
|
<img
|
||||||
</div>
|
src="/icons/no-experiment-found.svg"
|
||||||
|
alt="no experiment"
|
||||||
|
className={classes.noExpImage}
|
||||||
|
/>
|
||||||
|
<Typography variant="h5" className={classes.noExp}>
|
||||||
|
{t('myhub.myhubChart.noPredefinedExp')}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</AccordionDetails>
|
</div>
|
||||||
</Accordion>
|
</TabPanel>
|
||||||
<Accordion
|
<TabPanel value={tabValue} index={1}>
|
||||||
square
|
<div className={classes.mainDiv}>
|
||||||
classes={{
|
<HeaderSection searchValue={search} changeSearch={changeSearch} />
|
||||||
root: classes.MuiAccordionroot,
|
<div className={classes.chartsGroup}>
|
||||||
}}
|
{filteredExperiment?.length > 0 ? (
|
||||||
expanded={expanded === 'panel2'}
|
filteredExperiment.map((expName: ChartName) => {
|
||||||
onChange={handleChange('panel2')}
|
return (
|
||||||
className={classes.chartAccordion}
|
<ChartCard
|
||||||
>
|
key={`${expName.ChaosName}-${expName.ExperimentName}`}
|
||||||
<AccordionSummary
|
expName={expName}
|
||||||
expandIcon={<ExpandMoreIcon />}
|
UserHub={UserHub}
|
||||||
aria-controls="panel2d-content"
|
setSearch={setSearch}
|
||||||
id="panel2d-header"
|
projectID={projectID}
|
||||||
>
|
userRole={getProjectRole()}
|
||||||
<Typography variant="h4">
|
isPredefined={false}
|
||||||
<strong>{t('myhub.myhubChart.chaosCharts')}</strong>
|
|
||||||
</Typography>
|
|
||||||
</AccordionSummary>
|
|
||||||
<AccordionDetails>
|
|
||||||
<div className={classes.mainDiv}>
|
|
||||||
<HeaderSection searchValue={search} changeSearch={changeSearch} />
|
|
||||||
<div className={classes.chartsGroup}>
|
|
||||||
{filteredExperiment?.length > 0 ? (
|
|
||||||
filteredExperiment.map((expName: ChartName) => {
|
|
||||||
return (
|
|
||||||
<ChartCard
|
|
||||||
key={`${expName.ChaosName}-${expName.ExperimentName}`}
|
|
||||||
expName={expName}
|
|
||||||
UserHub={UserHub}
|
|
||||||
setSearch={setSearch}
|
|
||||||
projectID={projectID}
|
|
||||||
userRole={getProjectRole()}
|
|
||||||
isPredefined={false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<img
|
|
||||||
src="/icons/no-experiment-found.svg"
|
|
||||||
alt="no experiment"
|
|
||||||
width="80px"
|
|
||||||
height="80px"
|
|
||||||
/>
|
/>
|
||||||
<Typography variant="h5" className={classes.noExp}>
|
);
|
||||||
{t('myhub.myhubChart.noExp')}
|
})
|
||||||
</Typography>
|
) : (
|
||||||
</>
|
<>
|
||||||
)}
|
<img
|
||||||
</div>
|
src="/icons/no-experiment-found.svg"
|
||||||
|
alt="no experiment"
|
||||||
|
className={classes.noExpImage}
|
||||||
|
/>
|
||||||
|
<Typography variant="h5" className={classes.noExp}>
|
||||||
|
{t('myhub.myhubChart.noExp')}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</AccordionDetails>
|
</div>
|
||||||
</Accordion>
|
</TabPanel>
|
||||||
</Scaffold>
|
</Scaffold>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,8 +35,6 @@ const useStyles = makeStyles((theme) => ({
|
||||||
alignContent: 'center',
|
alignContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
border: '0.0625rem solid',
|
|
||||||
borderColor: theme.palette.border.main,
|
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
|
@ -58,12 +56,10 @@ const useStyles = makeStyles((theme) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
border: '0.0625rem solid',
|
|
||||||
marginTop: theme.spacing(3),
|
marginTop: theme.spacing(3),
|
||||||
paddingTop: theme.spacing(2),
|
paddingTop: theme.spacing(2),
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderColor: theme.palette.border.main,
|
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
},
|
},
|
||||||
cardDiv: {
|
cardDiv: {
|
||||||
|
@ -112,6 +108,15 @@ const useStyles = makeStyles((theme) => ({
|
||||||
chartAccordion: {
|
chartAccordion: {
|
||||||
marginTop: theme.spacing(2.5),
|
marginTop: theme.spacing(2.5),
|
||||||
},
|
},
|
||||||
|
appBar: {
|
||||||
|
background: 'transparent',
|
||||||
|
boxShadow: 'none',
|
||||||
|
marginBottom: theme.spacing(1),
|
||||||
|
},
|
||||||
|
noExpImage: {
|
||||||
|
width: '5rem',
|
||||||
|
height: '5rem',
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useStyles;
|
export default useStyles;
|
||||||
|
|
Loading…
Reference in New Issue