Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added validation in probes modal and fixed the type issue while probe creation #2738

Merged
merged 2 commits into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions litmus-portal/frontend/public/icons/delete-exp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions litmus-portal/frontend/public/locales/en/translation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,10 @@ createWorkflow:
rollout: Rollout
nodeselector: NodeSelector
selector: 'kubernetes.io/hostname :'
nsError: Namespace not available
labelError: Label not available in the resource or namespace
deleteExp: Delete the experiment
editExp: Edit the experiment
addProbe:
heading: Add
headingStrong: Probe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ const ProbeDetails: React.FC<ProbeDetailsProps> = ({
| { name?: string | undefined; value: unknown }
>
) => {
if (
e.target.name === 'url' ||
e.target.name === 'insecureSkipVerify' ||
e.target.name === 'responseTimeout'
) {
if (e.target.name === 'url' || e.target.name === 'responseTimeout') {
setProbeData({
...probeData,
'httpProbe/inputs': {
Expand All @@ -50,6 +46,15 @@ const ProbeDetails: React.FC<ProbeDetailsProps> = ({
},
});
}
if (e.target.name === 'insecureSkipVerify') {
setProbeData({
...probeData,
'httpProbe/inputs': {
...probeData['httpProbe/inputs'],
[e.target.name]: e.target.value === 'true',
},
});
}
};

const handleCmd = (
Expand Down Expand Up @@ -150,7 +155,12 @@ const ProbeDetails: React.FC<ProbeDetailsProps> = ({
{t('createWorkflow.tuneWorkflow.addProbe.inputLabels.insecure')}
</InputLabel>
<Select
value={probeData['httpProbe/inputs']?.insecureSkipVerify}
value={
typeof probeData['httpProbe/inputs']?.insecureSkipVerify ===
'boolean'
? probeData['httpProbe/inputs']?.insecureSkipVerify.toString()
: probeData['httpProbe/inputs']?.insecureSkipVerify
}
className={classes.inputSelect}
variant="outlined"
onChange={handleHttp}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import { Modal, ButtonOutlined, ButtonFilled, InputField } from 'litmus-ui';
import { MenuItem, Select, InputLabel } from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import React, { useEffect } from 'react';
import React from 'react';
import useStyles from './styles';
import ProbeDetails from './ProbeDetails';

interface AddProbeProps {
probesValue: any;
setProbesValue: React.Dispatch<any>;
addProbe: () => void;
addProbe: (probes: any) => void;
handleClose: () => void;
open: boolean;
}

interface RunProperties {
probeTimeout: string;
retry: string;
interval: string;
probePollingInterval?: string;
initialDelaySeconds?: string;
}

const AddProbe: React.FC<AddProbeProps> = ({
probesValue,
setProbesValue,
addProbe,
handleClose,
open,
Expand All @@ -27,28 +33,26 @@ const AddProbe: React.FC<AddProbeProps> = ({
probesValue && probesValue.length ? probesValue : []
);
const [probeType, setProbeType] = React.useState('httpProbe/inputs');
const [runProperties, setRunProperties] = React.useState<RunProperties>({
probeTimeout: '',
retry: '',
interval: '',
probePollingInterval: '',
initialDelaySeconds: '',
});
const [probeData, setProbeData] = React.useState({
name: '',
type: 'httpProbe',
mode: 'Continuous',
runProperties: {
probeTimeout: '',
retry: '',
interval: '',
probePollingInterval: '',
initialDelaySeconds: '',
},
runProperties: {},
'httpProbe/inputs': {},
});
const handleRunProps = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setProbeData({
...probeData,
runProperties: {
...probeData.runProperties,
[e.target.name]: e.target.value,
},
setRunProperties({
...runProperties,
[e.target.name]: parseInt(e.target.value, 10),
});
};

Expand Down Expand Up @@ -76,15 +80,23 @@ const AddProbe: React.FC<AddProbeProps> = ({
};

const handleAddProbe = () => {
allProbes.push(probeData);
const properties = runProperties;
if (Number.isNaN(parseInt(properties.initialDelaySeconds as string, 10))) {
delete properties.initialDelaySeconds;
}
if (Number.isNaN(parseInt(properties.probePollingInterval as string, 10))) {
delete properties.probePollingInterval;
}
allProbes.push({
...probeData,
runProperties: {
...properties,
},
});
setAllProbes(allProbes);
addProbe();
addProbe(allProbes);
};

useEffect(() => {
setProbesValue(allProbes);
}, [allProbes]);

return (
<Modal
open={open}
Expand Down Expand Up @@ -117,6 +129,7 @@ const AddProbe: React.FC<AddProbeProps> = ({
id="name"
name="name"
type="text"
required
value={probeData.name}
onChange={(e) =>
setProbeData({ ...probeData, name: e.target.value })
Expand Down Expand Up @@ -203,8 +216,9 @@ const AddProbe: React.FC<AddProbeProps> = ({
width="50%"
id="timeout"
name="probeTimeout"
required
type="number"
value={probeData.runProperties.probeTimeout}
value={runProperties.probeTimeout}
onChange={handleRunProps}
/>
</div>
Expand All @@ -217,8 +231,9 @@ const AddProbe: React.FC<AddProbeProps> = ({
width="50%"
id="retry"
name="retry"
required
type="number"
value={probeData.runProperties.retry}
value={runProperties.retry}
onChange={handleRunProps}
/>
</div>
Expand All @@ -232,9 +247,10 @@ const AddProbe: React.FC<AddProbeProps> = ({
variant="primary"
width="50%"
id="interval"
required
name="interval"
type="number"
value={probeData.runProperties.interval}
value={runProperties.interval}
onChange={handleRunProps}
/>
</div>
Expand All @@ -248,7 +264,7 @@ const AddProbe: React.FC<AddProbeProps> = ({
id="polling"
name="probePollingInterval"
type="number"
value={probeData.runProperties.probePollingInterval}
value={runProperties.probePollingInterval}
onChange={handleRunProps}
/>
</div>
Expand All @@ -263,7 +279,7 @@ const AddProbe: React.FC<AddProbeProps> = ({
id="initial-delay"
name="initialDelaySeconds"
type="number"
value={probeData.runProperties.initialDelaySeconds}
value={runProperties.initialDelaySeconds}
onChange={handleRunProps}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ import StepLabel from '@material-ui/core/StepLabel';
import StepContent from '@material-ui/core/StepContent';
import Typography from '@material-ui/core/Typography';
import { ButtonOutlined } from 'litmus-ui';
import { useSelector } from 'react-redux';
import YAML from 'yaml';
import { useTranslation } from 'react-i18next';
import General from '../TuneWorkflowSteps/General';
import SteadyState from '../TuneWorkflowSteps/SteadyState';
import TargetApplication from '../TuneWorkflowSteps/TargetApplication';
import useStyles from './styles';
import * as WorkflowActions from '../../../../redux/actions/workflow';
import { WorkflowManifest } from '../../../../models/redux/workflow';
import { RootState } from '../../../../redux/reducers';
import useActions from '../../../../redux/actions';

interface ConfigurationStepperProps {
experimentIndex: number;
Expand Down Expand Up @@ -85,6 +92,7 @@ const ConfigurationStepper: React.FC<ConfigurationStepperProps> = ({
closeStepper,
isCustom,
}) => {
const { t } = useTranslation();
const classes = useStyles();

// State variable to handle Stepper Steps
Expand All @@ -102,6 +110,76 @@ const ConfigurationStepper: React.FC<ConfigurationStepperProps> = ({
const gotoStep = (page: number) => {
setActiveStep(page);
};
const workflow = useActions(WorkflowActions);
const manifest: WorkflowManifest = useSelector(
(state: RootState) => state.workflowManifest
);

const deleteExperiment = () => {
/**
* Workflow manifest saved in redux state
*/
const wfManifest = YAML.parse(manifest.manifest);

/**
* Get template name according to the experiment index
*/
const templateName = wfManifest.spec.templates[experimentIndex].name;

/**
* Get the workflow name according to the experiment index
*/
const wfName = YAML.parse(manifest.engineYAML).metadata.name;

/**
* if the template is a revert-chaos template
* the engine name is removed from the
* revert-chaos template args
*/
if (
wfManifest.spec.templates[
wfManifest.spec.templates.length - 1
].name.includes('revert-')
) {
const argument = wfManifest.spec.templates[
wfManifest.spec.templates.length - 1
].container.args[0].replace(wfName, '');
wfManifest.spec.templates[
wfManifest.spec.templates.length - 1
].container.args[0] = argument;
}

/**
* Remove the experiment name from steps
*/
wfManifest.spec.templates[0].steps.forEach(
(data: any, stepIndex: number) => {
data.forEach((step: any, index: number) => {
if (step.name === templateName) {
data.splice(index, 1);
}
});
if (data.length === 0) {
wfManifest.spec.templates[0].steps.splice(stepIndex, 1);
}
}
);

/**
* Remove the chaos engine from the overall manifest
* according to the experiment index
*/
wfManifest.spec.templates.splice(experimentIndex, 1);

/**
* Set the updated manifest to redux state
*/
workflow.setWorkflowManifest({
manifest: YAML.stringify(wfManifest),
engineYAML: '',
});
closeStepper();
};

return (
<div className={classes.root}>
Expand All @@ -110,6 +188,26 @@ const ConfigurationStepper: React.FC<ConfigurationStepperProps> = ({
&#x2715;
</ButtonOutlined>
</div>
<div className={classes.deleteExpDiv}>
<Typography className={classes.editExpText}>
{t('createWorkflow.tuneWorkflow.verticalStepper.editExp')}
</Typography>
<ButtonOutlined
onClick={() => {
deleteExperiment();
}}
className={classes.deleteBtn}
>
<img
src="./icons/delete-exp.svg"
alt="delete"
className={classes.deleteIcon}
/>
<Typography color="error" className={classes.deleteExpText}>
{t('createWorkflow.tuneWorkflow.verticalStepper.deleteExp')}
</Typography>
</ButtonOutlined>
</div>
<Stepper activeStep={activeStep} orientation="vertical">
{steps.map((label, index) => (
<Step key={label}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,35 @@ const useStyles = makeStyles((theme: Theme) => ({
maxWidth: '25rem',
},
annotationToggleBtn: {
width: 72,
height: 35,
width: '4.5rem',
height: '2.1875rem',
},

// Delete experiment
deleteExpDiv: {
display: 'flex',
marginTop: theme.spacing(10),
marginRight: theme.spacing(10),
marginLeft: theme.spacing(3.125),
justifyContent: 'space-between',
},

editExpText: {
fontSize: '1.5rem',
},

deleteBtn: {
border: `1px solid ${theme.palette.error.main}`,
},

deleteIcon: {
marginRight: theme.spacing(1.25),
height: '1.25rem',
width: '1.25rem',
},

deleteExpText: {
marginTop: theme.spacing(0.625),
},

// Stepper styles
Expand Down
Loading