chore(litmus-portal): Added validation in probes modal and minor fix (#2842)
* Added validation in probes modal and minor fix * Minor change in directory structure and fixed template graph not rendering issue * Minor regex change for validating ssh links Signed-off-by: Amit Kumar Das <amit@chaosnative.com>
This commit is contained in:
parent
cd72a7a40a
commit
c638304960
|
@ -855,6 +855,7 @@ createWorkflow:
|
|||
addProbe:
|
||||
heading: Add
|
||||
headingStrong: Probe
|
||||
validate: Probe name already exists
|
||||
labels:
|
||||
probeName: Probe Name
|
||||
probeType: Probe Type
|
||||
|
|
|
@ -84,6 +84,7 @@ export interface ListManifestTemplateArray {
|
|||
project_name: string;
|
||||
template_description: string;
|
||||
template_name: string;
|
||||
isCustomWorkflow: boolean;
|
||||
}
|
||||
|
||||
export interface ListManifestTemplate {
|
||||
|
|
|
@ -41,6 +41,18 @@ export const validateWorkflowName = (value: string) => {
|
|||
return false;
|
||||
};
|
||||
|
||||
export const validateProbeName = (allProbe: any, probeName: string) => {
|
||||
if (allProbe.length) {
|
||||
const filteredProbes = allProbe.filter(
|
||||
(probe: any) => probe.name.toLowerCase() === probeName
|
||||
);
|
||||
if (filteredProbes.length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const validatePassword = (value: string) => {
|
||||
const passValid = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,20}$/;
|
||||
if (value.length > 0) {
|
||||
|
@ -77,7 +89,7 @@ export const isValidWebUrl = (value: string) => {
|
|||
const regExLocal = /^http:\/\/localhost:([0-9]){1,4}$/g;
|
||||
const regExIpv4 = /^http:\/\/(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]):([0-9]){1,4}$/g;
|
||||
const regExIpv6 = /^http:\/\/((([0-9a-fA-F]){1,4})\\:){7}([0-9a-fA-F]){1,4}:([0-9]){1,4}$/g;
|
||||
const sshRegEx = /^([A-Za-z0-9]+@|http(|s)\:\/\/)([A-Za-z0-9.]+(:\d+)?)(?::|\/)([\d\/\w.-]+?)(\.git)?$/i;
|
||||
const sshRegEx = /^([A-Za-z0-9]+@|http(|s)\:\/\/)([-a-zA-Z0-9@:%._\+~#=]+(:\d+)?)(?::|\/)([\d\/\w.-]+?)(\.git)?$/i;
|
||||
if (
|
||||
value.match(regEx) ||
|
||||
value.match(regExLocal) ||
|
||||
|
|
|
@ -19,7 +19,9 @@ import {
|
|||
ListManifestTemplateArray,
|
||||
} from '../../../models/graphql/workflowListData';
|
||||
import { getProjectID } from '../../../utils/getSearchParams';
|
||||
import * as WorkflowActions from '../../../redux/actions/workflow';
|
||||
import useStyles from './styles';
|
||||
import useActions from '../../../redux/actions';
|
||||
|
||||
interface ChooseWorkflowRadio {
|
||||
selected: string;
|
||||
|
@ -33,7 +35,7 @@ const ChooseWorkflowFromExisting = () => {
|
|||
// Local States
|
||||
const [search, setSearch] = useState<string | null>(null);
|
||||
const [selected, setSelected] = useState<string>('');
|
||||
|
||||
const workflowAction = useActions(WorkflowActions);
|
||||
const { data: templateData } = useQuery<ListManifestTemplate>(
|
||||
LIST_MANIFEST_TEMPLATE,
|
||||
{
|
||||
|
@ -74,7 +76,9 @@ const ChooseWorkflowFromExisting = () => {
|
|||
const templateData = filteredExistingWorkflows.filter((workflow) => {
|
||||
return workflow.template_id === event.target.value;
|
||||
})[0];
|
||||
|
||||
workflowAction.setWorkflowManifest({
|
||||
isCustomWorkflow: templateData.isCustomWorkflow,
|
||||
});
|
||||
localforage.setItem('selectedScheduleOption', selection);
|
||||
localforage.setItem('workflow', {
|
||||
name: templateData.template_name.toLowerCase(),
|
||||
|
|
|
@ -37,7 +37,7 @@ const ProbeDetails: React.FC<ProbeDetailsProps> = ({
|
|||
| { name?: string | undefined; value: unknown }
|
||||
>
|
||||
) => {
|
||||
if (e.target.name === 'url' || e.target.name === 'responseTimeout') {
|
||||
if (e.target.name === 'url') {
|
||||
setProbeData({
|
||||
...probeData,
|
||||
'httpProbe/inputs': {
|
||||
|
@ -46,6 +46,15 @@ const ProbeDetails: React.FC<ProbeDetailsProps> = ({
|
|||
},
|
||||
});
|
||||
}
|
||||
if (e.target.name === 'responseTimeout') {
|
||||
setProbeData({
|
||||
...probeData,
|
||||
'httpProbe/inputs': {
|
||||
...probeData['httpProbe/inputs'],
|
||||
[e.target.name]: parseInt(e.target.value as string, 10),
|
||||
},
|
||||
});
|
||||
}
|
||||
if (e.target.name === 'insecureSkipVerify') {
|
||||
setProbeData({
|
||||
...probeData,
|
||||
|
@ -185,7 +194,7 @@ const ProbeDetails: React.FC<ProbeDetailsProps> = ({
|
|||
width="50%"
|
||||
id="responseTimeout"
|
||||
name="responseTimeout"
|
||||
type="text"
|
||||
type="number"
|
||||
value={probeData['httpProbe/inputs']?.responseTimeout}
|
||||
onChange={handleHttp}
|
||||
/>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|||
import React from 'react';
|
||||
import useStyles from './styles';
|
||||
import ProbeDetails from './ProbeDetails';
|
||||
import { validateProbeName } from '../../../../utils/validate';
|
||||
|
||||
interface AddProbeProps {
|
||||
probesValue: any;
|
||||
|
@ -153,12 +154,21 @@ const AddProbe: React.FC<AddProbeProps> = ({
|
|||
{t('createWorkflow.tuneWorkflow.addProbe.labels.probeName')}
|
||||
</InputLabel>
|
||||
<InputField
|
||||
variant="primary"
|
||||
id="name"
|
||||
name="name"
|
||||
type="text"
|
||||
required
|
||||
value={probeData.name}
|
||||
helperText={
|
||||
validateProbeName(allProbes, probeData.name)
|
||||
? t('createWorkflow.tuneWorkflow.addProbe.validate')
|
||||
: ''
|
||||
}
|
||||
variant={
|
||||
validateProbeName(allProbes, probeData.name)
|
||||
? 'error'
|
||||
: 'primary'
|
||||
}
|
||||
onChange={(e) =>
|
||||
setProbeData({ ...probeData, name: e.target.value })
|
||||
}
|
||||
|
@ -328,7 +338,13 @@ const AddProbe: React.FC<AddProbeProps> = ({
|
|||
>
|
||||
{t('createWorkflow.tuneWorkflow.addProbe.button.cancel')}
|
||||
</ButtonOutlined>
|
||||
<ButtonFilled type="submit">
|
||||
<ButtonFilled
|
||||
type="submit"
|
||||
disabled={
|
||||
validateProbeName(allProbes, probeData.name) ||
|
||||
probeData.name.trim().length === 0
|
||||
}
|
||||
>
|
||||
{t('createWorkflow.tuneWorkflow.addProbe.button.addProbe')}
|
||||
</ButtonFilled>
|
||||
</div>
|
||||
|
|
|
@ -30,6 +30,7 @@ import useStyles from './styles';
|
|||
|
||||
interface WorkflowTableProps {
|
||||
isCustom: boolean | undefined;
|
||||
namespace: string;
|
||||
}
|
||||
|
||||
interface ChaosCRDTable {
|
||||
|
@ -41,7 +42,8 @@ interface ChaosCRDTable {
|
|||
ChaosEngine: string;
|
||||
}
|
||||
|
||||
const WorkflowTable = forwardRef(({ isCustom }: WorkflowTableProps, ref) => {
|
||||
const WorkflowTable = forwardRef(
|
||||
({ isCustom, namespace }: WorkflowTableProps, ref) => {
|
||||
const classes = useStyles();
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
@ -85,7 +87,11 @@ const WorkflowTable = forwardRef(({ isCustom }: WorkflowTableProps, ref) => {
|
|||
expData.push({
|
||||
StepIndex: index,
|
||||
Name: chaosEngine.metadata.generateName,
|
||||
Namespace: chaosEngine.spec.appinfo?.appns ?? '',
|
||||
Namespace:
|
||||
chaosEngine.spec.appinfo?.appns ===
|
||||
'{{workflow.parameters.adminModeNamespace}}'
|
||||
? namespace
|
||||
: chaosEngine.spec.appinfo?.appns ?? '',
|
||||
Application: chaosEngine.spec.appinfo?.applabel ?? '',
|
||||
Probes: chaosEngine.spec.experiments[0].spec.probe?.length ?? 0,
|
||||
ChaosEngine: artifact.raw.data,
|
||||
|
@ -178,7 +184,10 @@ const WorkflowTable = forwardRef(({ isCustom }: WorkflowTableProps, ref) => {
|
|||
};
|
||||
}
|
||||
|
||||
const updatedManifest = updateManifestImage(parsedYAML, imageRegistryData);
|
||||
const updatedManifest = updateManifestImage(
|
||||
parsedYAML,
|
||||
imageRegistryData
|
||||
);
|
||||
workflow.setWorkflowManifest({
|
||||
manifest: updatedManifest,
|
||||
});
|
||||
|
@ -269,7 +278,9 @@ const WorkflowTable = forwardRef(({ isCustom }: WorkflowTableProps, ref) => {
|
|||
{index + 1}
|
||||
</TableCell>
|
||||
<TableCell align="left">{experiment.Name}</TableCell>
|
||||
<TableCell align="left">{experiment.Namespace}</TableCell>
|
||||
<TableCell align="left">
|
||||
{experiment.Namespace}
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
{experiment.Application}
|
||||
</TableCell>
|
||||
|
@ -346,6 +357,7 @@ const WorkflowTable = forwardRef(({ isCustom }: WorkflowTableProps, ref) => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export default WorkflowTable;
|
||||
|
|
|
@ -788,7 +788,11 @@ const TuneWorkflow = forwardRef((_, ref) => {
|
|||
</Width>
|
||||
{/* Workflow Table */}
|
||||
<Width width="70%">
|
||||
<WorkflowTable ref={childRef} isCustom={isCustomWorkflow} />
|
||||
<WorkflowTable
|
||||
ref={childRef}
|
||||
isCustom={isCustomWorkflow}
|
||||
namespace={namespace}
|
||||
/>
|
||||
</Width>
|
||||
</Row>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import DeveloperGuide from '../../../components/DeveloperGuide';
|
||||
import ExperimentHeader from '../../../components/ExperimentHeader';
|
||||
import ExperimentHeader from '../ExperimentHeader';
|
||||
import ExperimentInfo from '../../../components/ExperimentInfo';
|
||||
import InstallChaos from '../../../components/InstallChaos';
|
||||
import Loader from '../../../components/Loader';
|
||||
|
|
Loading…
Reference in New Issue