type(bugfix): Fixed Radio Button selection issue at Choose Workflow Screen 🐛 (#2933)
* Fixed Radio Button selection issue at Choose Workflow Screen Signed-off-by: Sayan Mondal <sayan@chaosnative.com> * Fixed Issues with workflow localforage state and persistence Signed-off-by: Sayan Mondal <sayan@chaosnative.com>
This commit is contained in:
parent
b7db9f42cb
commit
c9ac99b947
|
@ -1,4 +1,11 @@
|
||||||
import { Paper, Step, StepLabel, Stepper, Typography } from '@material-ui/core';
|
import {
|
||||||
|
Paper,
|
||||||
|
Step,
|
||||||
|
StepLabel,
|
||||||
|
Stepper,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
} from '@material-ui/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { ButtonFilled, ButtonOutlined } from 'litmus-ui';
|
import { ButtonFilled, ButtonOutlined } from 'litmus-ui';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -77,11 +84,23 @@ const LitmusStepper: React.FC<LitmusStepperProps> = ({
|
||||||
|
|
||||||
{/* Stepper Actions */}
|
{/* Stepper Actions */}
|
||||||
<div className={classes.stepperActions}>
|
<div className={classes.stepperActions}>
|
||||||
{activeStep > 0 && (
|
{activeStep === 2 ? (
|
||||||
|
<Tooltip
|
||||||
|
title="All selected Workflow Data will be lost"
|
||||||
|
placement="top"
|
||||||
|
leaveDelay={300}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<ButtonOutlined onClick={handleBack}>
|
||||||
|
<Typography>{t('workflowStepper.back')}</Typography>
|
||||||
|
</ButtonOutlined>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
) : activeStep > 0 ? (
|
||||||
<ButtonOutlined onClick={handleBack}>
|
<ButtonOutlined onClick={handleBack}>
|
||||||
<Typography>{t('workflowStepper.back')}</Typography>
|
<Typography>{t('workflowStepper.back')}</Typography>
|
||||||
</ButtonOutlined>
|
</ButtonOutlined>
|
||||||
)}
|
) : null}
|
||||||
{moreStepperActions}
|
{moreStepperActions}
|
||||||
<div className={classes.endAction}>
|
<div className={classes.endAction}>
|
||||||
{activeStep !== steps.length - 1 ? (
|
{activeStep !== steps.length - 1 ? (
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { Tooltip } from '@material-ui/core';
|
||||||
import Snackbar from '@material-ui/core/Snackbar';
|
import Snackbar from '@material-ui/core/Snackbar';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import MuiAlert, { AlertProps } from '@material-ui/lab/Alert';
|
import MuiAlert, { AlertProps } from '@material-ui/lab/Alert';
|
||||||
|
@ -145,6 +146,26 @@ const WorkflowStepper = () => {
|
||||||
Finish
|
Finish
|
||||||
</ButtonFilled>
|
</ButtonFilled>
|
||||||
)
|
)
|
||||||
|
) : activeStep === 2 ? (
|
||||||
|
<div className={classes.headerButtonWrapper} aria-label="buttons">
|
||||||
|
<Tooltip
|
||||||
|
title="All selected Workflow Data will be lost"
|
||||||
|
placement="top"
|
||||||
|
leaveDelay={300}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<ButtonOutlined
|
||||||
|
className={classes.btn}
|
||||||
|
onClick={() => handleBack()}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</ButtonOutlined>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
<ButtonFilled className={classes.btn} onClick={() => handleNext()}>
|
||||||
|
Next
|
||||||
|
</ButtonFilled>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
// Apply headerButtonWrapper style for top button's div
|
// Apply headerButtonWrapper style for top button's div
|
||||||
<div className={classes.headerButtonWrapper} aria-label="buttons">
|
<div className={classes.headerButtonWrapper} aria-label="buttons">
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
import { LitmusCard, RadioButton, Search } from 'litmus-ui';
|
import { LitmusCard, RadioButton, Search } from 'litmus-ui';
|
||||||
import localforage from 'localforage';
|
import localforage from 'localforage';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
DELETE_WORKFLOW_TEMPLATE,
|
DELETE_WORKFLOW_TEMPLATE,
|
||||||
|
@ -18,17 +18,23 @@ import {
|
||||||
ListManifestTemplate,
|
ListManifestTemplate,
|
||||||
ListManifestTemplateArray,
|
ListManifestTemplateArray,
|
||||||
} from '../../../models/graphql/workflowListData';
|
} 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';
|
import useActions from '../../../redux/actions';
|
||||||
|
import * as WorkflowActions from '../../../redux/actions/workflow';
|
||||||
|
import { getProjectID } from '../../../utils/getSearchParams';
|
||||||
|
import useStyles from './styles';
|
||||||
|
|
||||||
interface ChooseWorkflowRadio {
|
interface ChooseWorkflowRadio {
|
||||||
selected: string;
|
selected: string;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChooseWorkflowFromExisting = () => {
|
interface ChooseWorkflowFromExistingProps {
|
||||||
|
selectedExp: (expID: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChooseWorkflowFromExisting: React.FC<ChooseWorkflowFromExistingProps> = ({
|
||||||
|
selectedExp,
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { palette } = useTheme();
|
const { palette } = useTheme();
|
||||||
|
@ -73,6 +79,7 @@ const ChooseWorkflowFromExisting = () => {
|
||||||
selected: 'B',
|
selected: 'B',
|
||||||
id: event.target.value,
|
id: event.target.value,
|
||||||
};
|
};
|
||||||
|
selectedExp(selection.id);
|
||||||
const templateData = filteredExistingWorkflows.filter((workflow) => {
|
const templateData = filteredExistingWorkflows.filter((workflow) => {
|
||||||
return workflow.template_id === event.target.value;
|
return workflow.template_id === event.target.value;
|
||||||
})[0];
|
})[0];
|
||||||
|
@ -83,17 +90,6 @@ const ChooseWorkflowFromExisting = () => {
|
||||||
localforage.setItem('hasSetWorkflowData', false);
|
localforage.setItem('hasSetWorkflowData', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selects Option B -> Sub Experiment Options which was already selected by the user
|
|
||||||
useEffect(() => {
|
|
||||||
localforage
|
|
||||||
.getItem('selectedScheduleOption')
|
|
||||||
.then((value) =>
|
|
||||||
value !== null
|
|
||||||
? setSelected((value as ChooseWorkflowRadio).id)
|
|
||||||
: setSelected('')
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
{/* Wrapping content inside the Accordion to take full width */}
|
{/* Wrapping content inside the Accordion to take full width */}
|
||||||
|
|
|
@ -25,234 +25,229 @@ interface ChooseWorkflowRadio {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChoosePreDefinedExperiments = () => {
|
interface ChoosePreDefinedExperimentsProps {
|
||||||
const { t } = useTranslation();
|
selectedExp: (expID: string) => void;
|
||||||
const classes = useStyles();
|
}
|
||||||
const { palette } = useTheme();
|
|
||||||
|
|
||||||
// Local States
|
const ChoosePreDefinedExperiments: React.FC<ChoosePreDefinedExperimentsProps> =
|
||||||
const [search, setSearch] = useState<string | null>(null);
|
({ selectedExp }) => {
|
||||||
const [selected, setSelected] = useState<string>('');
|
const { t } = useTranslation();
|
||||||
|
const classes = useStyles();
|
||||||
|
const { palette } = useTheme();
|
||||||
|
|
||||||
const selectedProjectID = getProjectID();
|
// Local States
|
||||||
const [selectedHub, setSelectedHub] = useState('');
|
const [search, setSearch] = useState<string | null>(null);
|
||||||
const [availableHubs, setAvailableHubs] = useState<MyHubDetail[]>([]);
|
const [selected, setSelected] = useState<string>('');
|
||||||
const [workflowList, setWorkflowlist] = useState([]);
|
|
||||||
|
|
||||||
// Get all MyHubs with status
|
const selectedProjectID = getProjectID();
|
||||||
const { data, loading } = useQuery<HubStatus>(GET_HUB_STATUS, {
|
const [selectedHub, setSelectedHub] = useState('');
|
||||||
variables: { data: selectedProjectID },
|
const [availableHubs, setAvailableHubs] = useState<MyHubDetail[]>([]);
|
||||||
fetchPolicy: 'cache-and-network',
|
const [workflowList, setWorkflowlist] = useState([]);
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
// Get all MyHubs with status
|
||||||
* Query to get the list of Pre-defined workflows
|
const { data, loading } = useQuery<HubStatus>(GET_HUB_STATUS, {
|
||||||
*/
|
variables: { data: selectedProjectID },
|
||||||
const [getPredefinedWorkflow] = useLazyQuery(GET_PREDEFINED_WORKFLOW_LIST, {
|
fetchPolicy: 'cache-and-network',
|
||||||
fetchPolicy: 'network-only',
|
});
|
||||||
onCompleted: (data) => {
|
|
||||||
if (data.GetPredefinedWorkflowList !== undefined) {
|
|
||||||
setWorkflowlist(data.GetPredefinedWorkflowList);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onError: () => {
|
|
||||||
setWorkflowlist([]);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to handle changes in Radio Buttons
|
* Query to get the list of Pre-defined workflows
|
||||||
*/
|
*/
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const [getPredefinedWorkflow] = useLazyQuery(GET_PREDEFINED_WORKFLOW_LIST, {
|
||||||
setSelected(event.target.value);
|
fetchPolicy: 'network-only',
|
||||||
const selection: ChooseWorkflowRadio = {
|
onCompleted: (data) => {
|
||||||
selected: 'A',
|
if (data.GetPredefinedWorkflowList !== undefined) {
|
||||||
id: event.target.value,
|
setWorkflowlist(data.GetPredefinedWorkflowList);
|
||||||
};
|
}
|
||||||
localforage.setItem('selectedScheduleOption', selection);
|
},
|
||||||
localforage.setItem('hasSetWorkflowData', false);
|
onError: () => {
|
||||||
};
|
setWorkflowlist([]);
|
||||||
|
|
||||||
const filteredPreDefinedWorkflows = workflowList.filter((w: string) => {
|
|
||||||
if (search === null) return w;
|
|
||||||
if (w.toLowerCase().includes(search.toLowerCase())) return w;
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to handle change in MyHub dropdown
|
|
||||||
*/
|
|
||||||
const handleMyHubChange = (
|
|
||||||
event: React.ChangeEvent<{
|
|
||||||
name?: string | undefined;
|
|
||||||
value: unknown;
|
|
||||||
}>
|
|
||||||
) => {
|
|
||||||
setSelectedHub(event.target.value as string);
|
|
||||||
getPredefinedWorkflow({
|
|
||||||
variables: {
|
|
||||||
hubname: event.target.value as string,
|
|
||||||
projectid: selectedProjectID,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
localforage.setItem('selectedHub', event.target.value as string);
|
|
||||||
|
/**
|
||||||
|
* Function to handle changes in Radio Buttons
|
||||||
|
*/
|
||||||
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setSelected(event.target.value);
|
||||||
|
const selection: ChooseWorkflowRadio = {
|
||||||
|
selected: 'A',
|
||||||
|
id: event.target.value,
|
||||||
|
};
|
||||||
|
selectedExp(selection.id);
|
||||||
|
localforage.setItem('selectedScheduleOption', selection);
|
||||||
|
localforage.setItem('hasSetWorkflowData', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const filteredPreDefinedWorkflows = workflowList.filter((w: string) => {
|
||||||
|
if (search === null) return w;
|
||||||
|
if (w.toLowerCase().includes(search.toLowerCase())) return w;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to handle change in MyHub dropdown
|
||||||
|
*/
|
||||||
|
const handleMyHubChange = (
|
||||||
|
event: React.ChangeEvent<{
|
||||||
|
name?: string | undefined;
|
||||||
|
value: unknown;
|
||||||
|
}>
|
||||||
|
) => {
|
||||||
|
setSelectedHub(event.target.value as string);
|
||||||
|
getPredefinedWorkflow({
|
||||||
|
variables: {
|
||||||
|
hubname: event.target.value as string,
|
||||||
|
projectid: selectedProjectID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
localforage.setItem('selectedHub', event.target.value as string);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UseEffect to check if Chaos Hub exists and if exists
|
||||||
|
* fetch the pre-defined workflows
|
||||||
|
*/
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.getHubStatus !== undefined) {
|
||||||
|
if (data.getHubStatus.length) {
|
||||||
|
setAvailableHubs([...data.getHubStatus]);
|
||||||
|
}
|
||||||
|
data.getHubStatus.forEach((hubData) => {
|
||||||
|
if (hubData.HubName.toLowerCase() === 'chaos hub') {
|
||||||
|
setSelectedHub('Chaos Hub');
|
||||||
|
localforage.setItem('selectedHub', 'Chaos Hub');
|
||||||
|
getPredefinedWorkflow({
|
||||||
|
variables: {
|
||||||
|
hubname: 'Chaos Hub',
|
||||||
|
projectid: selectedProjectID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [loading]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccordionDetails>
|
||||||
|
{/* Wrapping content inside the Accordion to take full width */}
|
||||||
|
<div style={{ width: '100%' }}>
|
||||||
|
<div style={{ display: 'flex' }}>
|
||||||
|
<div className={classes.inputMyHubDiv}>
|
||||||
|
<FormControl variant="outlined" className={classes.formControl}>
|
||||||
|
<InputLabel className={classes.label}>
|
||||||
|
{t('createWorkflow.chooseWorkflow.selectMyHub')}
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
data-cy="selectPreDefinedMyHub"
|
||||||
|
value={selectedHub}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleMyHubChange(e);
|
||||||
|
}}
|
||||||
|
label="Select MyHub"
|
||||||
|
MenuProps={MenuProps}
|
||||||
|
>
|
||||||
|
{availableHubs.map((hubs) => (
|
||||||
|
<MenuItem key={hubs.HubName} value={hubs.HubName}>
|
||||||
|
<Typography data-cy="PreDefinedHubOption">
|
||||||
|
{hubs.HubName}
|
||||||
|
</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</div>
|
||||||
|
<div className={classes.searchDiv}>
|
||||||
|
<Search
|
||||||
|
data-cy="agentSearch"
|
||||||
|
id="input-with-icon-textfield"
|
||||||
|
placeholder="Search"
|
||||||
|
value={search}
|
||||||
|
onChange={(event) => setSearch(event.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Leaving some space between the search and pre-defined workflow cards */}
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{/* List of Pre-defined workflows */}
|
||||||
|
<div className={classes.predefinedWorkflowDiv}>
|
||||||
|
{selectedHub === '' ? (
|
||||||
|
<div className={classes.noTemplatesDiv}>
|
||||||
|
<Typography className={classes.noTemplatesText}>
|
||||||
|
<strong>{t('createWorkflow.chooseWorkflow.noMyHub')}</strong>
|
||||||
|
</Typography>
|
||||||
|
<Typography className={classes.noTemplatesDesc}>
|
||||||
|
{t('createWorkflow.chooseWorkflow.selectHub')}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
) : workflowList.length === 0 ? (
|
||||||
|
<div className={classes.noTemplatesDiv}>
|
||||||
|
<Typography className={classes.noTemplatesText}>
|
||||||
|
<strong>
|
||||||
|
{t('createWorkflow.chooseWorkflow.noPredefined')}
|
||||||
|
</strong>
|
||||||
|
</Typography>
|
||||||
|
<Typography className={classes.noTemplatesDesc}>
|
||||||
|
{t('createWorkflow.chooseWorkflow.addPredefined')}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<RadioGroup
|
||||||
|
value={selected}
|
||||||
|
data-cy="PredefinedWorkflowsRadioGroup"
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
{filteredPreDefinedWorkflows?.length > 0 ? (
|
||||||
|
filteredPreDefinedWorkflows?.map((wfData) => (
|
||||||
|
<LitmusCard
|
||||||
|
width="100%"
|
||||||
|
height="5rem"
|
||||||
|
key={wfData}
|
||||||
|
borderColor={palette.border.main}
|
||||||
|
className={classes.predefinedWorkflowCard}
|
||||||
|
>
|
||||||
|
<RadioButton value={wfData}>
|
||||||
|
{/* Wrap the entire body with 100% width to divide into 40-60 */}
|
||||||
|
<div id="body">
|
||||||
|
{/* Left Div => Icon + Name of Workflow */}
|
||||||
|
<div id="left-div">
|
||||||
|
<img
|
||||||
|
className={classes.experimentIcon}
|
||||||
|
src={`${config.grahqlEndpoint}/icon/${selectedProjectID}/${selectedHub}/predefined/${wfData}.png`}
|
||||||
|
alt="Experiment Icon"
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
className={classes.predefinedWorkflowName}
|
||||||
|
>
|
||||||
|
{wfData}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</RadioButton>
|
||||||
|
</LitmusCard>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className={classes.noTemplatesDiv}>
|
||||||
|
<Typography className={classes.noTemplatesText}>
|
||||||
|
<strong>
|
||||||
|
{t('createWorkflow.chooseWorkflow.noPredefined')}
|
||||||
|
</strong>
|
||||||
|
</Typography>
|
||||||
|
<Typography className={classes.noTemplatesDesc}>
|
||||||
|
{t('createWorkflow.chooseWorkflow.searchTerm')}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</RadioGroup>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/* Bottom Blur */}
|
||||||
|
<div className={classes.blur} />
|
||||||
|
</div>
|
||||||
|
</AccordionDetails>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selects Option A -> Sub Experiment Options which was already selected by the user
|
|
||||||
useEffect(() => {
|
|
||||||
localforage
|
|
||||||
.getItem('selectedScheduleOption')
|
|
||||||
.then((value) =>
|
|
||||||
value !== null
|
|
||||||
? setSelected((value as ChooseWorkflowRadio).id)
|
|
||||||
: setSelected('')
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UseEffect to check if Chaos Hub exists and if exists
|
|
||||||
* fetch the pre-defined workflows
|
|
||||||
*/
|
|
||||||
useEffect(() => {
|
|
||||||
if (data?.getHubStatus !== undefined) {
|
|
||||||
if (data.getHubStatus.length) {
|
|
||||||
setAvailableHubs([...data.getHubStatus]);
|
|
||||||
}
|
|
||||||
data.getHubStatus.forEach((hubData) => {
|
|
||||||
if (hubData.HubName.toLowerCase() === 'chaos hub') {
|
|
||||||
setSelectedHub('Chaos Hub');
|
|
||||||
localforage.setItem('selectedHub', 'Chaos Hub');
|
|
||||||
getPredefinedWorkflow({
|
|
||||||
variables: {
|
|
||||||
hubname: 'Chaos Hub',
|
|
||||||
projectid: selectedProjectID,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [loading]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AccordionDetails>
|
|
||||||
{/* Wrapping content inside the Accordion to take full width */}
|
|
||||||
<div style={{ width: '100%' }}>
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<div className={classes.inputMyHubDiv}>
|
|
||||||
<FormControl variant="outlined" className={classes.formControl}>
|
|
||||||
<InputLabel className={classes.label}>
|
|
||||||
{t('createWorkflow.chooseWorkflow.selectMyHub')}
|
|
||||||
</InputLabel>
|
|
||||||
<Select
|
|
||||||
data-cy="selectPreDefinedMyHub"
|
|
||||||
value={selectedHub}
|
|
||||||
onChange={(e) => {
|
|
||||||
handleMyHubChange(e);
|
|
||||||
}}
|
|
||||||
label="Select MyHub"
|
|
||||||
MenuProps={MenuProps}
|
|
||||||
>
|
|
||||||
{availableHubs.map((hubs) => (
|
|
||||||
<MenuItem key={hubs.HubName} value={hubs.HubName}>
|
|
||||||
<Typography data-cy="PreDefinedHubOption">
|
|
||||||
{hubs.HubName}
|
|
||||||
</Typography>
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
<div className={classes.searchDiv}>
|
|
||||||
<Search
|
|
||||||
data-cy="agentSearch"
|
|
||||||
id="input-with-icon-textfield"
|
|
||||||
placeholder="Search"
|
|
||||||
value={search}
|
|
||||||
onChange={(event) => setSearch(event.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Leaving some space between the search and pre-defined workflow cards */}
|
|
||||||
<br />
|
|
||||||
|
|
||||||
{/* List of Pre-defined workflows */}
|
|
||||||
<div className={classes.predefinedWorkflowDiv}>
|
|
||||||
{selectedHub === '' ? (
|
|
||||||
<div className={classes.noTemplatesDiv}>
|
|
||||||
<Typography className={classes.noTemplatesText}>
|
|
||||||
<strong>{t('createWorkflow.chooseWorkflow.noMyHub')}</strong>
|
|
||||||
</Typography>
|
|
||||||
<Typography className={classes.noTemplatesDesc}>
|
|
||||||
{t('createWorkflow.chooseWorkflow.selectHub')}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
) : workflowList.length === 0 ? (
|
|
||||||
<div className={classes.noTemplatesDiv}>
|
|
||||||
<Typography className={classes.noTemplatesText}>
|
|
||||||
<strong>
|
|
||||||
{t('createWorkflow.chooseWorkflow.noPredefined')}
|
|
||||||
</strong>
|
|
||||||
</Typography>
|
|
||||||
<Typography className={classes.noTemplatesDesc}>
|
|
||||||
{t('createWorkflow.chooseWorkflow.addPredefined')}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<RadioGroup
|
|
||||||
value={selected}
|
|
||||||
data-cy="PredefinedWorkflowsRadioGroup"
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
{filteredPreDefinedWorkflows?.length > 0 ? (
|
|
||||||
filteredPreDefinedWorkflows?.map((wfData) => (
|
|
||||||
<LitmusCard
|
|
||||||
width="100%"
|
|
||||||
height="5rem"
|
|
||||||
key={wfData}
|
|
||||||
borderColor={palette.border.main}
|
|
||||||
className={classes.predefinedWorkflowCard}
|
|
||||||
>
|
|
||||||
<RadioButton value={wfData}>
|
|
||||||
{/* Wrap the entire body with 100% width to divide into 40-60 */}
|
|
||||||
<div id="body">
|
|
||||||
{/* Left Div => Icon + Name of Workflow */}
|
|
||||||
<div id="left-div">
|
|
||||||
<img
|
|
||||||
className={classes.experimentIcon}
|
|
||||||
src={`${config.grahqlEndpoint}/icon/${selectedProjectID}/${selectedHub}/predefined/${wfData}.png`}
|
|
||||||
alt="Experiment Icon"
|
|
||||||
/>
|
|
||||||
<Typography
|
|
||||||
className={classes.predefinedWorkflowName}
|
|
||||||
>
|
|
||||||
{wfData}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</RadioButton>
|
|
||||||
</LitmusCard>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<div className={classes.noTemplatesDiv}>
|
|
||||||
<Typography className={classes.noTemplatesText}>
|
|
||||||
<strong>
|
|
||||||
{t('createWorkflow.chooseWorkflow.noPredefined')}
|
|
||||||
</strong>
|
|
||||||
</Typography>
|
|
||||||
<Typography className={classes.noTemplatesDesc}>
|
|
||||||
{t('createWorkflow.chooseWorkflow.searchTerm')}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</RadioGroup>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{/* Bottom Blur */}
|
|
||||||
<div className={classes.blur} />
|
|
||||||
</div>
|
|
||||||
</AccordionDetails>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ChoosePreDefinedExperiments;
|
export default ChoosePreDefinedExperiments;
|
||||||
|
|
|
@ -14,7 +14,6 @@ import React, {
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { ChooseWorkflowRadio } from '../../../models/localforage/radioButton';
|
|
||||||
import useActions from '../../../redux/actions';
|
import useActions from '../../../redux/actions';
|
||||||
import * as AlertActions from '../../../redux/actions/alert';
|
import * as AlertActions from '../../../redux/actions/alert';
|
||||||
import * as WorkflowActions from '../../../redux/actions/workflow';
|
import * as WorkflowActions from '../../../redux/actions/workflow';
|
||||||
|
@ -30,6 +29,7 @@ const ChooseWorkflow = forwardRef((_, ref) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const alert = useActions(AlertActions);
|
const alert = useActions(AlertActions);
|
||||||
const [selected, setSelected] = useState<string>('');
|
const [selected, setSelected] = useState<string>('');
|
||||||
|
const [id, setSelectedID] = useState<string | undefined>(undefined);
|
||||||
const workflowDetails = useSelector(
|
const workflowDetails = useSelector(
|
||||||
(state: RootState) => state.workflowManifest.manifest
|
(state: RootState) => state.workflowManifest.manifest
|
||||||
);
|
);
|
||||||
|
@ -50,11 +50,21 @@ const ChooseWorkflow = forwardRef((_, ref) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
workflowAction.setWorkflowManifest({ manifest: '' });
|
||||||
|
}, []);
|
||||||
|
|
||||||
function onNext() {
|
function onNext() {
|
||||||
if (selected === '') {
|
if (selected === '') {
|
||||||
alert.changeAlertState(true); // No Workflow Type has been selected and user clicked on Next
|
alert.changeAlertState(true); // No Workflow Type has been selected and user clicked on Next
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (selected === 'A' || selected === 'B') {
|
||||||
|
if (id === undefined) {
|
||||||
|
alert.changeAlertState(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (selected === 'D' && workflowDetails === '') {
|
if (selected === 'D' && workflowDetails === '') {
|
||||||
alert.changeAlertState(true);
|
alert.changeAlertState(true);
|
||||||
return false;
|
return false;
|
||||||
|
@ -63,20 +73,9 @@ const ChooseWorkflow = forwardRef((_, ref) => {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
const pickedExperiment = (subExpNumber: string) => {
|
||||||
localforage.getItem('selectedScheduleOption').then((value) => {
|
setSelectedID(subExpNumber);
|
||||||
if (value) {
|
};
|
||||||
setSelected((value as ChooseWorkflowRadio).selected);
|
|
||||||
} else setSelected('');
|
|
||||||
});
|
|
||||||
workflowAction.setWorkflowManifest({
|
|
||||||
manifest: '',
|
|
||||||
});
|
|
||||||
/**
|
|
||||||
* Removes the workflow details if already present
|
|
||||||
*/
|
|
||||||
localforage.removeItem('workflow');
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
onNext,
|
onNext,
|
||||||
|
@ -120,7 +119,7 @@ const ChooseWorkflow = forwardRef((_, ref) => {
|
||||||
</span>
|
</span>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<ChoosePreDefinedExperiments />
|
<ChoosePreDefinedExperiments selectedExp={pickedExperiment} />
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion
|
<Accordion
|
||||||
|
@ -141,7 +140,7 @@ const ChooseWorkflow = forwardRef((_, ref) => {
|
||||||
</span>
|
</span>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<ChooseWorkflowFromExisting />
|
<ChooseWorkflowFromExisting selectedExp={pickedExperiment} />
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion
|
<Accordion
|
||||||
|
|
|
@ -272,13 +272,13 @@ const TuneWorkflow = forwardRef((_, ref) => {
|
||||||
* Index DB Fetching for extracting selected Button and Workflow Details
|
* Index DB Fetching for extracting selected Button and Workflow Details
|
||||||
*/
|
*/
|
||||||
const getSelectedWorkflowDetails = () => {
|
const getSelectedWorkflowDetails = () => {
|
||||||
localforage.getItem('workflow').then((workflow) =>
|
localforage.getItem('workflow').then((workflow) => {
|
||||||
setWorkflow({
|
setWorkflow({
|
||||||
name: (workflow as WorkflowDetailsProps).name,
|
name: (workflow as WorkflowDetailsProps).name,
|
||||||
crd: (workflow as WorkflowDetailsProps).CRDLink,
|
crd: (workflow as WorkflowDetailsProps).CRDLink,
|
||||||
description: (workflow as WorkflowDetailsProps).description,
|
description: (workflow as WorkflowDetailsProps).description,
|
||||||
})
|
});
|
||||||
);
|
});
|
||||||
localforage.getItem('selectedScheduleOption').then((value) => {
|
localforage.getItem('selectedScheduleOption').then((value) => {
|
||||||
/**
|
/**
|
||||||
* Setting default data when MyHub is selected
|
* Setting default data when MyHub is selected
|
||||||
|
@ -331,7 +331,7 @@ const TuneWorkflow = forwardRef((_, ref) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getSelectedWorkflowDetails();
|
getSelectedWorkflowDetails();
|
||||||
}, []);
|
}, [manifest]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Graphql Query for fetching Engine YAML
|
* Graphql Query for fetching Engine YAML
|
||||||
|
|
|
@ -241,11 +241,7 @@ const VerifyCommit = forwardRef(
|
||||||
isLoading(loading);
|
isLoading(loading);
|
||||||
|
|
||||||
const handleMutation = () => {
|
const handleMutation = () => {
|
||||||
if (
|
if (workflow.name.length !== 0 && weights.length !== 0) {
|
||||||
workflow.name.length !== 0 &&
|
|
||||||
workflow.description.length !== 0 &&
|
|
||||||
weights.length !== 0
|
|
||||||
) {
|
|
||||||
const weightData: WeightMap[] = [];
|
const weightData: WeightMap[] = [];
|
||||||
|
|
||||||
weights.forEach((data) => {
|
weights.forEach((data) => {
|
||||||
|
|
|
@ -130,6 +130,7 @@ const WorkflowSettings = forwardRef((_, ref) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
workflowAction.setWorkflowManifest({ manifest: '' });
|
||||||
}
|
}
|
||||||
if ((value as ChooseWorkflowRadio).selected === 'B') {
|
if ((value as ChooseWorkflowRadio).selected === 'B') {
|
||||||
getSavedTemplateDetails({
|
getSavedTemplateDetails({
|
||||||
|
|
Loading…
Reference in New Issue