chore(litmus-portal): Added pre-defined workflows in myhub and minor bug fix (#2837)
* Added pre-defined experiments in myhub and bug fix * Minor change in query name Signed-off-by: Amit Kumar Das <amit@chaosnative.com>
This commit is contained in:
parent
26d5bbb3c3
commit
fcdfecf8a1
|
@ -1,39 +1,7 @@
|
|||
<svg width="59" height="63" viewBox="0 0 59 63" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.8001 41.3007L42.1001 37.8008L56.8002 59.5007H2.90015L14.8001 41.3007Z" fill="url(#paint0_linear)"/>
|
||||
<path d="M38.9014 27.3728V3.69141H42.6619V0H16.3381V3.69141H20.0987V27.3728L1.74897 54.3915C0.592729 56.0939 0.485554 58.2719 1.46906 60.0758C2.45244 61.8795 4.35803 63 6.44225 63H52.5578C54.642 63 56.5476 61.8795 57.5311 60.0757C58.5146 58.2718 58.4073 56.0937 57.2512 54.3914L38.9014 27.3728ZM23.8592 28.4905V3.69141H35.1408V28.4905L39.9736 35.6064C39.0321 35.4304 38.0304 35.3145 37.0211 35.3145C32.8644 35.3145 28.8289 37.2716 28.6592 37.3549C27.7235 37.8142 24.6998 39.0059 21.9789 39.0059C20.2966 39.0059 18.5773 38.5684 17.3032 38.1437L23.8592 28.4905ZM54.2154 58.3339C54.0557 58.6269 53.5742 59.3086 52.5576 59.3086H6.44225C5.42578 59.3086 4.9443 58.6269 4.78448 58.3339C4.62478 58.0408 4.31391 57.2695 4.87774 56.4391L15.1552 41.3065C16.7371 41.9044 19.3325 42.6973 21.9789 42.6973C26.1356 42.6973 30.1711 40.7401 30.3409 40.6568C31.2764 40.1976 34.3001 39.0059 37.0211 39.0059C39.5961 39.0059 42.2589 40.0301 43.2734 40.4648L54.1223 56.439C54.686 57.2695 54.3752 58.0407 54.2154 58.3339Z" fill="white"/>
|
||||
<path d="M38.9014 27.3728V3.69141H42.6619V0H16.3381V3.69141H20.0987V27.3728L1.74897 54.3915C0.592729 56.0939 0.485554 58.2719 1.46906 60.0758C2.45244 61.8795 4.35803 63 6.44225 63H52.5578C54.642 63 56.5476 61.8795 57.5311 60.0757C58.5146 58.2718 58.4073 56.0937 57.2512 54.3914L38.9014 27.3728ZM23.8592 28.4905V3.69141H35.1408V28.4905L39.9736 35.6064C39.0321 35.4304 38.0304 35.3145 37.0211 35.3145C32.8644 35.3145 28.8289 37.2716 28.6592 37.3549C27.7235 37.8142 24.6998 39.0059 21.9789 39.0059C20.2966 39.0059 18.5773 38.5684 17.3032 38.1437L23.8592 28.4905ZM54.2154 58.3339C54.0557 58.6269 53.5742 59.3086 52.5576 59.3086H6.44225C5.42578 59.3086 4.9443 58.6269 4.78448 58.3339C4.62478 58.0408 4.31391 57.2695 4.87774 56.4391L15.1552 41.3065C16.7371 41.9044 19.3325 42.6973 21.9789 42.6973C26.1356 42.6973 30.1711 40.7401 30.3409 40.6568C31.2764 40.1976 34.3001 39.0059 37.0211 39.0059C39.5961 39.0059 42.2589 40.0301 43.2734 40.4648L54.1223 56.439C54.686 57.2695 54.3752 58.0407 54.2154 58.3339Z" fill="url(#paint1_linear)"/>
|
||||
<path d="M35.1409 44.543H38.9015V48.2344H35.1409V44.543Z" fill="white"/>
|
||||
<path d="M35.1409 44.543H38.9015V48.2344H35.1409V44.543Z" fill="url(#paint2_linear)"/>
|
||||
<path d="M27.6199 51.9258H31.3804V55.6172H27.6199V51.9258Z" fill="white"/>
|
||||
<path d="M27.6199 51.9258H31.3804V55.6172H27.6199V51.9258Z" fill="url(#paint3_linear)"/>
|
||||
<path d="M20.0988 48.2344H23.8593V51.9258H20.0988V48.2344Z" fill="white"/>
|
||||
<path d="M20.0988 48.2344H23.8593V51.9258H20.0988V48.2344Z" fill="url(#paint4_linear)"/>
|
||||
<path d="M27.6199 29.7773H31.3804V33.4687H27.6199V29.7773Z" fill="white"/>
|
||||
<path d="M27.6199 29.7773H31.3804V33.4687H27.6199V29.7773Z" fill="url(#paint5_linear)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="28.0002" y1="45.501" x2="29.8501" y2="59.5007" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#2DA660"/>
|
||||
<stop offset="1" stop-color="#52F995"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="29.5" y1="0" x2="29.5" y2="63" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="29.5" y1="0" x2="29.5" y2="63" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="29.5" y1="0" x2="29.5" y2="63" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="29.5" y1="0" x2="29.5" y2="63" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear" x1="29.5" y1="0" x2="29.5" y2="63" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<svg width="43" height="47" viewBox="0 0 43 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M28.5428 20.4209V2.75391H31.3599V0H11.64V2.75391H14.4571V20.4209L0.710864 40.5778C-0.155309 41.8478 -0.235597 43.4727 0.501176 44.8184C1.23786 46.1641 2.66539 47 4.22674 47H38.7732C40.3346 47 41.7621 46.1641 42.4989 44.8184C43.2356 43.4726 43.1552 41.8477 42.2892 40.5777L28.5428 20.4209ZM17.2743 21.2548V2.75391H25.7257V21.2548L29.3461 26.5635C28.6407 26.4322 27.8903 26.3457 27.1342 26.3457C24.0204 26.3457 20.9972 27.8058 20.8701 27.868C20.1692 28.2106 17.904 29.0996 15.8657 29.0996C14.6054 29.0996 13.3174 28.7733 12.363 28.4564L17.2743 21.2548ZM40.015 43.519C39.8954 43.7375 39.5347 44.2461 38.7731 44.2461H4.22674C3.46527 44.2461 3.10458 43.7375 2.98485 43.519C2.86522 43.3003 2.63234 42.7248 3.05472 42.1054L10.7538 30.8159C11.9389 31.262 13.8832 31.8535 15.8657 31.8535C18.9796 31.8535 22.0027 30.3934 22.1299 30.3312C22.8307 29.9887 25.0958 29.0996 27.1342 29.0996C29.0632 29.0996 31.058 29.8637 31.818 30.188L39.9452 42.1053C40.3675 42.7248 40.1347 43.3002 40.015 43.519Z" fill="#5B44BA"/>
|
||||
<path d="M25.7258 33.2305H28.5429V35.9844H25.7258V33.2305Z" fill="#5B44BA"/>
|
||||
<path d="M20.0915 38.7383H22.9086V41.4922H20.0915V38.7383Z" fill="#5B44BA"/>
|
||||
<path d="M14.4572 35.9844H17.2744V38.7383H14.4572V35.9844Z" fill="#5B44BA"/>
|
||||
<path d="M20.0915 22.2148H22.9086V24.9688H20.0915V22.2148Z" fill="#5B44BA"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,16 @@
|
|||
<svg width="46" height="50" viewBox="0 0 46 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M28.5428 20.4209V2.75391H31.3599V0H11.64V2.75391H14.4571V20.4209L0.710864 40.5778C-0.155309 41.8478 -0.235597 43.4727 0.501176 44.8184C1.23786 46.1641 2.66539 47 4.22674 47H38.7732C40.3346 47 41.7621 46.1641 42.4989 44.8184C43.2356 43.4726 43.1552 41.8477 42.2892 40.5777L28.5428 20.4209ZM17.2743 21.2548V2.75391H25.7257V21.2548L29.3461 26.5635C28.6407 26.4322 27.8903 26.3457 27.1342 26.3457C24.0204 26.3457 20.9972 27.8058 20.8701 27.868C20.1692 28.2106 17.904 29.0996 15.8657 29.0996C14.6054 29.0996 13.3174 28.7733 12.363 28.4564L17.2743 21.2548ZM40.015 43.519C39.8954 43.7375 39.5347 44.2461 38.7731 44.2461H4.22674C3.46527 44.2461 3.10458 43.7375 2.98485 43.519C2.86522 43.3003 2.63234 42.7248 3.05472 42.1054L10.7538 30.8159C11.9389 31.262 13.8832 31.8535 15.8657 31.8535C18.9796 31.8535 22.0027 30.3934 22.1299 30.3312C22.8307 29.9887 25.0958 29.0996 27.1342 29.0996C29.0632 29.0996 31.058 29.8637 31.818 30.188L39.9452 42.1053C40.3675 42.7248 40.1347 43.3002 40.015 43.519Z" fill="#CA2C2C"/>
|
||||
<path d="M25.7258 33.2305H28.5429V35.9844H25.7258V33.2305Z" fill="#CA2C2C"/>
|
||||
<path d="M20.0915 38.7383H22.9086V41.4922H20.0915V38.7383Z" fill="#CA2C2C"/>
|
||||
<path d="M14.4572 35.9844H17.2744V38.7383H14.4572V35.9844Z" fill="#CA2C2C"/>
|
||||
<path d="M20.0915 22.2148H22.9086V24.9688H20.0915V22.2148Z" fill="#CA2C2C"/>
|
||||
<rect x="30.5" y="34.5" width="15.0004" height="15.0004" rx="7.50021" fill="#CA2C2C" stroke="white"/>
|
||||
<g clip-path="url(#clip0)">
|
||||
<path d="M38.1635 43.2002L40.1063 45.143C40.321 45.3577 40.669 45.3577 40.8833 45.143L41.1423 44.884C41.357 44.6693 41.357 44.3213 41.1423 44.1069L39.1995 42.1642L41.1427 40.2213C41.3574 40.0067 41.3574 39.6587 41.1427 39.4443L40.8837 39.1849C40.669 38.9703 40.321 38.9703 40.1066 39.1849L38.1635 41.1281L36.2207 39.1853C36.006 38.9706 35.6579 38.9706 35.4436 39.1853L35.1846 39.4443C34.9699 39.659 34.9699 40.007 35.1846 40.2213L37.1274 42.1642L35.1846 44.1069C34.9699 44.3217 34.9699 44.6697 35.1846 44.884L35.4436 45.143C35.6583 45.3577 36.0064 45.3577 36.2207 45.143L38.1635 43.2002Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect width="7.67066" height="7.67066" fill="white" transform="translate(41.8545 38.1826) rotate(90)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -425,7 +425,7 @@ chaosWorkflows:
|
|||
experimentsPassed: 'Experiments Passed : '
|
||||
showExperiments: Show Experiments
|
||||
showTheWorkflow: Show the workflow
|
||||
showTheAnalytics: show the analytics
|
||||
showTheAnalytics: Show the analytics
|
||||
na: NA
|
||||
|
||||
analyticsDashboardViews:
|
||||
|
@ -754,7 +754,7 @@ createWorkflow:
|
|||
header: Adjust the weights of the experiments in the workflow
|
||||
info: You have selected
|
||||
infoNext: tests in the “Kubernetes conformance test” workflow. Successful outcome of each test carries a certain weight. We have pre-selected weights for each test for you. However, you may review and modify the weightage against.
|
||||
infoNextStrong: The weights are relative to each other.
|
||||
infoNextStrong: These weights are used to calculate the resiliency score at the end of test.
|
||||
testHeading: Kubernetes conformance test
|
||||
testInfo: Compare the importance of the items above and launch a demo version of Kubernetes conformance test to see how it works.
|
||||
button:
|
||||
|
@ -1068,6 +1068,11 @@ myhub:
|
|||
header: MyHub
|
||||
github: github.com/
|
||||
syncingRepo: Loading Charts, Please Wait...!
|
||||
preDefined: Pre-defined workflows
|
||||
chaosCharts: Chaos-charts
|
||||
noExp: No predefined workflows available with information in this Hub
|
||||
lastSynced: 'Last synced at: '
|
||||
repoLink: 'Repository Link: '
|
||||
connectHubPage:
|
||||
connectHub: Connect a new chaos hub
|
||||
editHub: Edit hub configuration
|
||||
|
@ -1104,6 +1109,8 @@ myhub:
|
|||
installRBACDesc: Create a service account using the following command
|
||||
installEngine: Sample Chaos Engine
|
||||
installEngineDesc: Copy and edit this sample Chaos Engine yaml according to your application needs
|
||||
checkPreDefined: Check the pre-defined workflow
|
||||
checkPreDefinedDesc: You can view the workflow details here
|
||||
editPage:
|
||||
edit: Edit the Hub
|
||||
click: Then click on the update button
|
||||
|
|
|
@ -9,17 +9,19 @@ interface InstallProps {
|
|||
title: string;
|
||||
description: string;
|
||||
yamlLink: string;
|
||||
isPredefined?: boolean;
|
||||
}
|
||||
|
||||
const InstallChaos: React.FC<InstallProps> = ({
|
||||
title,
|
||||
description,
|
||||
yamlLink,
|
||||
isPredefined,
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
const { t } = useTranslation();
|
||||
const [copying, setCopying] = useState(false);
|
||||
const yaml = `kubectl apply -f ${yamlLink}`;
|
||||
const yaml = isPredefined ? yamlLink : `kubectl apply -f ${yamlLink}`;
|
||||
|
||||
function copyTextToClipboard(text: string) {
|
||||
if (!navigator.clipboard) {
|
||||
|
@ -40,7 +42,7 @@ const InstallChaos: React.FC<InstallProps> = ({
|
|||
<div className={classes.description}>{description}</div>
|
||||
<div className={classes.linkBox}>
|
||||
<Typography variant="subtitle1" className={classes.yamlLink}>
|
||||
kubectl apply -f {yamlLink}
|
||||
{isPredefined ? yamlLink : `kubectl apply -f ${yamlLink}`}
|
||||
</Typography>
|
||||
|
||||
<div className={classes.buttonBox}>
|
||||
|
|
|
@ -46,7 +46,6 @@ const DashboardPage = lazy(() => import('../../pages/ApplicationDashboard'));
|
|||
const MyHub = lazy(() => import('../../pages/ChaosHub'));
|
||||
const ChaosChart = lazy(() => import('../../views/MyHub/MyHubCharts'));
|
||||
const MyHubExperiment = lazy(() => import('../../views/MyHub/MyHubExperiment'));
|
||||
const MyHubEdit = lazy(() => import('../../views/MyHub/MyHubEdit'));
|
||||
|
||||
const Routes: React.FC = () => {
|
||||
const baseRoute = window.location.pathname.split('/')[1];
|
||||
|
@ -217,7 +216,6 @@ const Routes: React.FC = () => {
|
|||
<Route exact path="/targets" component={Targets} />
|
||||
<Route exact path="/target-connect" component={ConnectTargets} />
|
||||
<Route exact path="/myhub" component={MyHub} />
|
||||
<Route exact path="/myhub/edit/:hubname" component={MyHubEdit} />
|
||||
<Route exact path="/myhub/:hubname" component={ChaosChart} />
|
||||
<Route
|
||||
exact
|
||||
|
|
|
@ -459,6 +459,12 @@ export const GET_TEMPLATE_BY_ID = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
export const GET_PREDEFINED_WORKFLOW_LIST = gql`
|
||||
query GetPredefinedWorkflowList($hubname: String!, $projectid: String!) {
|
||||
GetPredefinedWorkflowList(HubName: $hubname, projectID: $projectid)
|
||||
}
|
||||
`;
|
||||
|
||||
export const GET_PREDEFINED_EXPERIMENT_YAML = gql`
|
||||
query GetPredefinedExperimentYAML($experimentInput: ExperimentInput!) {
|
||||
GetPredefinedExperimentYAML(experimentInput: $experimentInput)
|
||||
|
|
|
@ -16,6 +16,7 @@ interface ChartCardProps {
|
|||
setSearch: React.Dispatch<React.SetStateAction<string>>;
|
||||
projectID: string;
|
||||
userRole: string;
|
||||
isPredefined?: boolean;
|
||||
}
|
||||
|
||||
const ChartCard: React.FC<ChartCardProps> = ({
|
||||
|
@ -24,6 +25,7 @@ const ChartCard: React.FC<ChartCardProps> = ({
|
|||
setSearch,
|
||||
projectID,
|
||||
userRole,
|
||||
isPredefined,
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
const experimentDefaultImagePath = `${config.grahqlEndpoint}/icon`;
|
||||
|
@ -31,7 +33,6 @@ const ChartCard: React.FC<ChartCardProps> = ({
|
|||
const [imageURL, setImageURL] = useState(
|
||||
`${experimentDefaultImagePath}/${projectID}/${UserHub?.HubName}/${expName.ChaosName}/${expName.ExperimentName}.png`
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card
|
||||
|
@ -61,7 +62,7 @@ const ChartCard: React.FC<ChartCardProps> = ({
|
|||
}}
|
||||
className={classes.categoryName}
|
||||
>
|
||||
{expName.ChaosName}/
|
||||
{!isPredefined && `${expName.ChaosName}/`}
|
||||
</Link>
|
||||
<Typography className={classes.expName} variant="h6" align="center">
|
||||
{expName.ExperimentName}
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
import { useQuery } from '@apollo/client';
|
||||
import { Backdrop, Typography } from '@material-ui/core';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Backdrop,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import moment from 'moment';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
import Loader from '../../../components/Loader';
|
||||
import Center from '../../../containers/layouts/Center';
|
||||
import Scaffold from '../../../containers/layouts/Scaffold';
|
||||
import { GET_CHARTS_DATA, GET_HUB_STATUS } from '../../../graphql';
|
||||
import {
|
||||
GET_CHARTS_DATA,
|
||||
GET_HUB_STATUS,
|
||||
GET_PREDEFINED_WORKFLOW_LIST,
|
||||
} from '../../../graphql';
|
||||
import { Chart, Charts, HubStatus } from '../../../models/redux/myhub';
|
||||
import { getProjectID, getProjectRole } from '../../../utils/getSearchParams';
|
||||
import ChartCard from './chartCard';
|
||||
import HeaderSection from './headerSection';
|
||||
import useStyles from './styles';
|
||||
import BackButton from '../../../components/Button/BackButton';
|
||||
|
||||
interface ChartName {
|
||||
ChaosName: string;
|
||||
|
@ -48,16 +60,34 @@ const MyHub: React.FC = () => {
|
|||
HubName: paramData.hubname,
|
||||
projectID,
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
const { data: predefinedData, loading: predefinedLoading } = useQuery(
|
||||
GET_PREDEFINED_WORKFLOW_LIST,
|
||||
{
|
||||
variables: {
|
||||
hubname: paramData.hubname,
|
||||
projectid: projectID,
|
||||
},
|
||||
fetchPolicy: 'network-only',
|
||||
}
|
||||
);
|
||||
|
||||
// State for searching charts
|
||||
const [search, setSearch] = useState('');
|
||||
const [searchPredefined, setSearchPredefined] = useState('');
|
||||
|
||||
const changeSearch = (
|
||||
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||
) => {
|
||||
setSearch(event.target.value as string);
|
||||
};
|
||||
const handlePreDefinedSearch = (
|
||||
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||
) => {
|
||||
setSearchPredefined(event.target.value as string);
|
||||
};
|
||||
const [totalExp, setTotalExperiment] = useState<ChartName[]>([]);
|
||||
const exp: ChartName[] = [];
|
||||
|
||||
|
@ -69,6 +99,15 @@ const MyHub: React.FC = () => {
|
|||
return 'Date not available';
|
||||
};
|
||||
|
||||
const [expanded, setExpanded] = React.useState<string | false>('panel2');
|
||||
|
||||
const handleChange = (panel: string) => (
|
||||
event: React.ChangeEvent<{}>,
|
||||
newExpanded: boolean
|
||||
) => {
|
||||
setExpanded(newExpanded ? panel : false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (data !== undefined) {
|
||||
const chartList = data.getCharts;
|
||||
|
@ -84,7 +123,7 @@ const MyHub: React.FC = () => {
|
|||
}
|
||||
}, [data]);
|
||||
|
||||
return loading ? (
|
||||
return loading || predefinedLoading ? (
|
||||
<Backdrop open className={classes.backdrop}>
|
||||
<Loader />
|
||||
<Center>
|
||||
|
@ -95,45 +134,131 @@ const MyHub: React.FC = () => {
|
|||
</Backdrop>
|
||||
) : (
|
||||
<Scaffold>
|
||||
<BackButton />
|
||||
<div className={classes.header}>
|
||||
<Typography variant="h3" gutterBottom>
|
||||
{UserHub?.HubName}
|
||||
</Typography>
|
||||
<Typography variant="h4">
|
||||
<Typography variant="h5">
|
||||
{t('myhub.myhubChart.repoLink')}
|
||||
<strong>
|
||||
{UserHub?.RepoURL}/{UserHub?.RepoBranch}
|
||||
</strong>
|
||||
</Typography>
|
||||
<Typography className={classes.lastSyncText}>
|
||||
Last synced at: {formatDate(UserHub ? UserHub.LastSyncedAt : '')}
|
||||
{t('myhub.myhubChart.lastSynced')}{' '}
|
||||
{formatDate(UserHub ? UserHub.LastSyncedAt : '')}
|
||||
</Typography>
|
||||
{/* </div> */}
|
||||
</div>
|
||||
<div className={classes.mainDiv}>
|
||||
<HeaderSection searchValue={search} changeSearch={changeSearch} />
|
||||
<div className={classes.chartsGroup}>
|
||||
{totalExp &&
|
||||
totalExp.length > 0 &&
|
||||
totalExp
|
||||
.filter(
|
||||
(data) =>
|
||||
data.ChaosName.toLowerCase().includes(search.trim()) ||
|
||||
data.ExperimentName.toLowerCase().includes(search.trim())
|
||||
)
|
||||
.map((expName: ChartName) => {
|
||||
return (
|
||||
<ChartCard
|
||||
key={`${expName.ChaosName}-${expName.ExperimentName}`}
|
||||
expName={expName}
|
||||
UserHub={UserHub}
|
||||
setSearch={setSearch}
|
||||
projectID={projectID}
|
||||
userRole={getProjectRole()}
|
||||
<Accordion
|
||||
square
|
||||
classes={{
|
||||
root: classes.MuiAccordionroot,
|
||||
}}
|
||||
expanded={expanded === 'panel1'}
|
||||
onChange={handleChange('panel1')}
|
||||
>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel1d-content"
|
||||
id="panel1d-header"
|
||||
>
|
||||
<Typography variant="h4">
|
||||
<strong>{t('myhub.myhubChart.preDefined')}</strong>
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<div className={classes.mainDiv}>
|
||||
<HeaderSection
|
||||
searchValue={searchPredefined}
|
||||
changeSearch={handlePreDefinedSearch}
|
||||
/>
|
||||
<div className={classes.chartsGroup}>
|
||||
{predefinedData?.GetPredefinedWorkflowList.length > 0 ? (
|
||||
predefinedData?.GetPredefinedWorkflowList.filter(
|
||||
(data: string) =>
|
||||
data.toLowerCase().includes(searchPredefined.trim())
|
||||
).map((expName: string) => {
|
||||
return (
|
||||
<ChartCard
|
||||
key={expName}
|
||||
expName={{
|
||||
ChaosName: 'predefined',
|
||||
ExperimentName: expName,
|
||||
}}
|
||||
UserHub={UserHub}
|
||||
setSearch={setSearchPredefined}
|
||||
projectID={projectID}
|
||||
userRole={getProjectRole()}
|
||||
isPredefined
|
||||
/>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<>
|
||||
<img
|
||||
src="/icons/no-experiment-found.svg"
|
||||
alt="no experiment"
|
||||
width="80px"
|
||||
height="80px"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<Typography variant="h5" className={classes.noExp}>
|
||||
{t('myhub.myhubChart.noExp')}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
square
|
||||
classes={{
|
||||
root: classes.MuiAccordionroot,
|
||||
}}
|
||||
expanded={expanded === 'panel2'}
|
||||
onChange={handleChange('panel2')}
|
||||
className={classes.chartAccordion}
|
||||
>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls="panel2d-content"
|
||||
id="panel2d-header"
|
||||
>
|
||||
<Typography variant="h4">
|
||||
<strong>{t('myhub.myhubChart.chaosCharts')}</strong>
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<div className={classes.mainDiv}>
|
||||
<HeaderSection searchValue={search} changeSearch={changeSearch} />
|
||||
<div className={classes.chartsGroup}>
|
||||
{totalExp &&
|
||||
totalExp.length > 0 &&
|
||||
totalExp
|
||||
.filter(
|
||||
(data) =>
|
||||
data.ChaosName.toLowerCase().includes(search.trim()) ||
|
||||
data.ExperimentName.toLowerCase().includes(search.trim())
|
||||
)
|
||||
.map((expName: ChartName) => {
|
||||
return (
|
||||
<ChartCard
|
||||
key={`${expName.ChaosName}-${expName.ExperimentName}`}
|
||||
expName={expName}
|
||||
UserHub={UserHub}
|
||||
setSearch={setSearch}
|
||||
projectID={projectID}
|
||||
userRole={getProjectRole()}
|
||||
isPredefined={false}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Scaffold>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -101,6 +101,17 @@ const useStyles = makeStyles((theme) => ({
|
|||
marginTop: theme.spacing(1.875),
|
||||
fontSize: '0.875rem',
|
||||
},
|
||||
MuiAccordionroot: {
|
||||
'&.MuiAccordion-root:before': {
|
||||
backgroundColor: theme.palette.common.white,
|
||||
},
|
||||
},
|
||||
noExp: {
|
||||
margin: theme.spacing(6),
|
||||
},
|
||||
chartAccordion: {
|
||||
marginTop: theme.spacing(2.5),
|
||||
},
|
||||
}));
|
||||
|
||||
export default useStyles;
|
||||
|
|
|
@ -1,509 +0,0 @@
|
|||
import { useMutation, useQuery } from '@apollo/client';
|
||||
import {
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import { Done } from '@material-ui/icons';
|
||||
import { ButtonFilled, ButtonOutlined, InputField, Modal } from 'litmus-ui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import BackButton from '../../../components/Button/BackButton';
|
||||
import GithubInputFields from '../../../components/GitHubComponents/GithubInputFields/GithubInputFields';
|
||||
import GitHubToggleButton from '../../../components/GitHubComponents/GitHubToggleButtons/GitHubToggleButton';
|
||||
import Loader from '../../../components/Loader';
|
||||
import { LocalQuickActionCard } from '../../../components/LocalQuickActionCard';
|
||||
import VideoCarousel from '../../../components/VideoCarousel';
|
||||
import Scaffold from '../../../containers/layouts/Scaffold';
|
||||
import { GENERATE_SSH, GET_HUB_STATUS, UPDATE_MY_HUB } from '../../../graphql';
|
||||
import {
|
||||
CreateMyHub,
|
||||
MyHubData,
|
||||
MyHubType,
|
||||
SSHKey,
|
||||
SSHKeys,
|
||||
} from '../../../models/graphql/user';
|
||||
import { HubStatus } from '../../../models/redux/myhub';
|
||||
import { history } from '../../../redux/configureStore';
|
||||
import { getProjectID, getProjectRole } from '../../../utils/getSearchParams';
|
||||
import {
|
||||
isValidWebUrl,
|
||||
validateStartEmptySpacing,
|
||||
} from '../../../utils/validate';
|
||||
import useStyles from './styles';
|
||||
|
||||
interface MyHubParams {
|
||||
hubname: string;
|
||||
}
|
||||
|
||||
interface GitHub {
|
||||
HubName: string;
|
||||
GitURL: string;
|
||||
GitBranch: string;
|
||||
}
|
||||
|
||||
interface MyHubToggleProps {
|
||||
isPublicToggled: boolean;
|
||||
isPrivateToggled: boolean;
|
||||
}
|
||||
|
||||
const MyHub: React.FC = () => {
|
||||
const classes = useStyles();
|
||||
const { t } = useTranslation();
|
||||
const projectID = getProjectID();
|
||||
const userRole = getProjectRole();
|
||||
const params: MyHubParams = useParams();
|
||||
const { data, loading } = useQuery<HubStatus>(GET_HUB_STATUS, {
|
||||
variables: { data: projectID },
|
||||
fetchPolicy: 'cache-and-network',
|
||||
});
|
||||
const hubData = data?.getHubStatus.filter(
|
||||
(hubs) => hubs.HubName === params.hubname
|
||||
)[0];
|
||||
|
||||
const [gitHub, setGitHub] = useState<GitHub>({
|
||||
HubName: '',
|
||||
GitURL: '',
|
||||
GitBranch: '',
|
||||
});
|
||||
const [error, setError] = useState('');
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [cloningRepo, setCloningRepo] = useState(false);
|
||||
const [isToggled, setIsToggled] = React.useState<MyHubToggleProps>({
|
||||
isPublicToggled: true,
|
||||
isPrivateToggled: false,
|
||||
});
|
||||
const [privateHub, setPrivateHub] = useState('token');
|
||||
const [accessToken, setAccessToken] = useState('');
|
||||
const [sshKey, setSshKey] = useState<SSHKey>({
|
||||
privateKey: '',
|
||||
publicKey: '',
|
||||
});
|
||||
const [copying, setCopying] = useState(false);
|
||||
|
||||
const [updateMyHub] = useMutation<MyHubData, CreateMyHub>(UPDATE_MY_HUB, {
|
||||
onCompleted: () => {
|
||||
setCloningRepo(false);
|
||||
},
|
||||
onError: (error) => {
|
||||
setCloningRepo(false);
|
||||
setError(error.message);
|
||||
},
|
||||
});
|
||||
|
||||
// Mutation to generate SSH key
|
||||
const [generateSSHKey, { loading: sshLoading }] = useMutation<SSHKeys>(
|
||||
GENERATE_SSH,
|
||||
{
|
||||
onCompleted: (data) => {
|
||||
setSshKey({
|
||||
privateKey: data.generaterSSHKey.privateKey,
|
||||
publicKey: data.generaterSSHKey.publicKey,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (hubData !== undefined) {
|
||||
setGitHub({
|
||||
HubName: hubData.HubName,
|
||||
GitURL: hubData.RepoURL,
|
||||
GitBranch: hubData.RepoBranch,
|
||||
});
|
||||
if (hubData.IsPrivate) {
|
||||
setIsToggled({
|
||||
isPublicToggled: false,
|
||||
isPrivateToggled: true,
|
||||
});
|
||||
} else {
|
||||
setIsToggled({
|
||||
isPublicToggled: true,
|
||||
isPrivateToggled: false,
|
||||
});
|
||||
}
|
||||
if (hubData.AuthType === MyHubType.token) {
|
||||
setPrivateHub('token');
|
||||
setAccessToken(hubData.Token);
|
||||
} else if (hubData.AuthType === MyHubType.ssh) {
|
||||
setPrivateHub('ssh');
|
||||
setSshKey({
|
||||
privateKey: hubData.SSHPrivateKey,
|
||||
publicKey: hubData.SSHPublicKey,
|
||||
});
|
||||
} else {
|
||||
setPrivateHub('token');
|
||||
}
|
||||
}
|
||||
}, [hubData]);
|
||||
|
||||
const handleGitURL = (
|
||||
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||
) => {
|
||||
setGitHub({
|
||||
HubName: gitHub.HubName,
|
||||
GitURL: event.target.value,
|
||||
GitBranch: gitHub.GitBranch,
|
||||
});
|
||||
};
|
||||
|
||||
const handleGitBranch = (
|
||||
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||
) => {
|
||||
setGitHub({
|
||||
HubName: gitHub.HubName,
|
||||
GitURL: gitHub.GitURL,
|
||||
GitBranch: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
updateMyHub({
|
||||
variables: {
|
||||
MyHubDetails: {
|
||||
id: hubData?.id,
|
||||
HubName: gitHub.HubName.trim(),
|
||||
RepoURL: gitHub.GitURL,
|
||||
RepoBranch: gitHub.GitBranch,
|
||||
IsPrivate: isToggled.isPublicToggled
|
||||
? false
|
||||
: !!isToggled.isPrivateToggled,
|
||||
AuthType: isToggled.isPublicToggled
|
||||
? MyHubType.basic
|
||||
: privateHub === 'token'
|
||||
? MyHubType.token
|
||||
: privateHub === 'ssh'
|
||||
? MyHubType.ssh
|
||||
: MyHubType.basic,
|
||||
Token: accessToken,
|
||||
UserName: 'user',
|
||||
Password: 'user',
|
||||
SSHPrivateKey: sshKey.privateKey,
|
||||
SSHPublicKey: sshKey.publicKey,
|
||||
},
|
||||
projectID,
|
||||
},
|
||||
});
|
||||
setCloningRepo(true);
|
||||
setIsOpen(true);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setIsOpen(false);
|
||||
history.push({
|
||||
pathname: '/myhub',
|
||||
search: `?projectID=${projectID}&projectRole=${userRole}`,
|
||||
});
|
||||
};
|
||||
|
||||
// Function to copy the SSH key
|
||||
const copyTextToClipboard = (text: string) => {
|
||||
if (!navigator.clipboard) {
|
||||
console.error('Oops Could not copy text: ');
|
||||
return;
|
||||
}
|
||||
setCopying(true);
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.catch((err) => console.error('Async: Could not copy text: ', err));
|
||||
setTimeout(() => setCopying(false), 3000);
|
||||
};
|
||||
return (
|
||||
<Scaffold>
|
||||
<div className={classes.header}>
|
||||
<div className={classes.backBtnDiv}>
|
||||
<BackButton />
|
||||
</div>
|
||||
<Typography variant="h3" gutterBottom>
|
||||
{t('myhub.editPage.edit')}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className={classes.mainDiv}>
|
||||
{loading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<div className={classes.detailsDiv}>
|
||||
<Typography variant="h4" gutterBottom />
|
||||
<Typography className={classes.enterInfoText}>
|
||||
<strong>{t('myhub.connectHubPage.enterInfo')}</strong>
|
||||
</Typography>
|
||||
<Typography className={classes.connectText}>
|
||||
{t('myhub.editPage.click')}
|
||||
</Typography>
|
||||
<form id="login-form" autoComplete="on" onSubmit={handleSubmit}>
|
||||
<div className={classes.inputDiv}>
|
||||
<div className={classes.inputField}>
|
||||
<InputField
|
||||
label="Hub Name"
|
||||
value={gitHub.HubName}
|
||||
helperText={
|
||||
validateStartEmptySpacing(gitHub.HubName)
|
||||
? t('myhub.validationEmptySpace')
|
||||
: ''
|
||||
}
|
||||
variant={
|
||||
validateStartEmptySpacing(gitHub.HubName)
|
||||
? 'error'
|
||||
: 'primary'
|
||||
}
|
||||
required
|
||||
onChange={(e) =>
|
||||
setGitHub({
|
||||
HubName: e.target.value,
|
||||
GitURL: gitHub.GitURL,
|
||||
GitBranch: gitHub.GitBranch,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={classes.mainPrivateRepo}>
|
||||
<div className={classes.privateRepoDiv}>
|
||||
<GitHubToggleButton
|
||||
isToggled={isToggled}
|
||||
setIsToggled={setIsToggled}
|
||||
/>
|
||||
</div>
|
||||
{/* If Public Repo is clicked */}
|
||||
{isToggled.isPublicToggled ? (
|
||||
<div className={classes.inputFieldDiv}>
|
||||
<GithubInputFields
|
||||
gitURL={gitHub.GitURL}
|
||||
gitBranch={gitHub.GitBranch}
|
||||
setGitURL={handleGitURL}
|
||||
setGitBranch={handleGitBranch}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{/* If Private Repo is Clicked */}
|
||||
{isToggled.isPrivateToggled ? (
|
||||
<div className={classes.privateToggleDiv}>
|
||||
<div className={classes.privateRepoDetails}>
|
||||
<GithubInputFields
|
||||
gitURL={gitHub.GitURL}
|
||||
gitBranch={gitHub.GitBranch}
|
||||
setGitURL={handleGitURL}
|
||||
setGitBranch={handleGitBranch}
|
||||
/>
|
||||
</div>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
className={classes.formControl}
|
||||
>
|
||||
<RadioGroup
|
||||
aria-label="privateHub"
|
||||
name="privateHub"
|
||||
value={privateHub}
|
||||
onChange={(e) => {
|
||||
if (e.target.value === 'ssh') {
|
||||
generateSSHKey();
|
||||
}
|
||||
if (e.target.value === 'token') {
|
||||
setSshKey({
|
||||
privateKey: '',
|
||||
publicKey: '',
|
||||
});
|
||||
}
|
||||
setPrivateHub(e.target.value);
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="token"
|
||||
control={
|
||||
<Radio
|
||||
classes={{
|
||||
root: classes.radio,
|
||||
checked: classes.checked,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography>
|
||||
{t('myhub.connectHubPage.accessToken')}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{privateHub === 'token' ? (
|
||||
<InputField
|
||||
label="Access Token"
|
||||
value={accessToken}
|
||||
helperText={
|
||||
validateStartEmptySpacing(accessToken)
|
||||
? t('myhub.validationEmptySpace')
|
||||
: ''
|
||||
}
|
||||
variant={
|
||||
validateStartEmptySpacing(accessToken)
|
||||
? 'error'
|
||||
: 'primary'
|
||||
}
|
||||
onChange={(e) => setAccessToken(e.target.value)}
|
||||
/>
|
||||
) : null}
|
||||
<FormControlLabel
|
||||
className={classes.sshRadioBtn}
|
||||
value="ssh"
|
||||
control={
|
||||
<Radio
|
||||
classes={{
|
||||
root: classes.radio,
|
||||
checked: classes.checked,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography>
|
||||
{t('myhub.connectHubPage.ssh')}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{privateHub === 'ssh' ? (
|
||||
<div className={classes.sshDiv}>
|
||||
<Typography className={classes.sshAlert}>
|
||||
{t('myhub.connectHubPage.sshAlert')}
|
||||
</Typography>
|
||||
<Typography className={classes.alertText}>
|
||||
{t('myhub.connectHubPage.sshText')}
|
||||
</Typography>
|
||||
<div className={classes.sshDataDiv}>
|
||||
{sshLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<>
|
||||
<Typography className={classes.sshText}>
|
||||
{sshKey.publicKey}
|
||||
</Typography>
|
||||
<div className={classes.copyBtn}>
|
||||
<ButtonOutlined
|
||||
onClick={() =>
|
||||
copyTextToClipboard(
|
||||
sshKey.publicKey
|
||||
)
|
||||
}
|
||||
>
|
||||
{!copying ? (
|
||||
<div className={classes.rowDiv}>
|
||||
<img
|
||||
src="/icons/copy.svg"
|
||||
className={classes.copyBtnImg}
|
||||
alt="copy"
|
||||
/>
|
||||
<Typography>
|
||||
{t('myhub.installChaos.copy')}
|
||||
</Typography>
|
||||
</div>
|
||||
) : (
|
||||
<div className={classes.rowDiv}>
|
||||
<Done className={classes.done} />
|
||||
<Typography>
|
||||
{t('myhub.installChaos.copied')}
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
</ButtonOutlined>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.submitBtnDiv}>
|
||||
<ButtonFilled
|
||||
variant="success"
|
||||
type="submit"
|
||||
disabled={
|
||||
!isValidWebUrl(gitHub.GitURL) ||
|
||||
validateStartEmptySpacing(gitHub.GitBranch)
|
||||
}
|
||||
>
|
||||
{t('myhub.editPage.submit')}
|
||||
</ButtonFilled>
|
||||
</div>
|
||||
<Modal
|
||||
open={isOpen}
|
||||
onClose={handleClose}
|
||||
modalActions={
|
||||
<ButtonOutlined onClick={handleClose}>
|
||||
✕
|
||||
</ButtonOutlined>
|
||||
}
|
||||
>
|
||||
<div className={classes.modalDiv}>
|
||||
{cloningRepo ? (
|
||||
<div>
|
||||
<Loader />
|
||||
<Typography className={classes.modalDesc}>
|
||||
{t('myhub.editPage.wait')}
|
||||
</Typography>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
{error.length ? (
|
||||
<div>
|
||||
<Typography
|
||||
gutterBottom
|
||||
className={classes.modalHeading}
|
||||
>
|
||||
<strong>{t('myhub.editPage.error')}</strong>{' '}
|
||||
</Typography>
|
||||
<Typography className={classes.modalDesc}>
|
||||
Error: {error}
|
||||
</Typography>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<img
|
||||
src="/icons/checkmark.svg"
|
||||
alt="checkmark"
|
||||
className={classes.checkImg}
|
||||
/>
|
||||
<Typography
|
||||
gutterBottom
|
||||
className={classes.modalHeading}
|
||||
>
|
||||
{t('myhub.editPage.success')}
|
||||
</Typography>
|
||||
<Typography className={classes.modalDesc}>
|
||||
{t('myhub.editPage.desc')}
|
||||
</Typography>
|
||||
<ButtonFilled
|
||||
variant="success"
|
||||
onClick={handleClose}
|
||||
>
|
||||
{t('myhub.connectHubPage.myHub')}
|
||||
</ButtonFilled>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)}
|
||||
<div className={classes.root}>
|
||||
<VideoCarousel />
|
||||
<Typography className={classes.videoDescription}>
|
||||
{t('myhub.connectHubPage.videoDesc')}
|
||||
</Typography>
|
||||
<div className={classes.quickActionDiv}>
|
||||
<LocalQuickActionCard variant="homePage" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Scaffold>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyHub;
|
|
@ -1,194 +0,0 @@
|
|||
import { makeStyles } from '@material-ui/core';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
mainDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
marginTop: theme.spacing(3),
|
||||
},
|
||||
root: {
|
||||
minWidth: '28.125rem',
|
||||
marginLeft: 'auto',
|
||||
},
|
||||
header: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
color: theme.palette.text.primary,
|
||||
margin: theme.spacing(4.5, 1.5, 2.5, 1.5),
|
||||
},
|
||||
detailsDiv: {
|
||||
flexGrow: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.palette.border.main}`,
|
||||
padding: theme.spacing(2.5),
|
||||
},
|
||||
connectText: {
|
||||
fontSize: '0.875rem',
|
||||
marginTop: theme.spacing(1.25),
|
||||
},
|
||||
inputDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginTop: theme.spacing(2.5),
|
||||
marginLeft: theme.spacing(-1.25),
|
||||
},
|
||||
inputField: {
|
||||
marginBottom: theme.spacing(2.5),
|
||||
marginLeft: theme.spacing(2),
|
||||
},
|
||||
inputFieldBranch: {
|
||||
marginBottom: theme.spacing(2.5),
|
||||
width: '10rem',
|
||||
marginRight: theme.spacing(2.5),
|
||||
},
|
||||
modalDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '25rem',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
modalHeading: {
|
||||
fontSize: '2.25rem',
|
||||
},
|
||||
modalDesc: {
|
||||
fontSize: '1rem',
|
||||
width: '21.875',
|
||||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
videoDescription: {
|
||||
marginTop: theme.spacing(-6.25),
|
||||
marginLeft: theme.spacing(5.625),
|
||||
width: '18.75rem',
|
||||
marginBottom: theme.spacing(5),
|
||||
fontSize: '1rem',
|
||||
},
|
||||
backBtnDiv: {
|
||||
marginLeft: theme.spacing(-1),
|
||||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
submitBtnDiv: {
|
||||
marginLeft: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
enterInfoText: {
|
||||
fontSize: '1.5rem',
|
||||
},
|
||||
checkImg: {
|
||||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
quickActionDiv: {
|
||||
marginLeft: theme.spacing(5.625),
|
||||
},
|
||||
rowDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
|
||||
copyBtnImg: {
|
||||
paddingRight: '0.625rem',
|
||||
},
|
||||
done: {
|
||||
color: theme.palette.text.secondary,
|
||||
paddingRight: theme.spacing(0.625),
|
||||
},
|
||||
mainPrivateRepo: {
|
||||
border: `1px solid ${theme.palette.border.main}`,
|
||||
padding: theme.spacing(2.5),
|
||||
margin: theme.spacing(2.5, 3.75, 2.5, 2),
|
||||
borderRadius: 4,
|
||||
width: 'fit-content',
|
||||
},
|
||||
privateRepoDiv: {
|
||||
width: 'fit-content',
|
||||
marginTop: theme.spacing(-6.25),
|
||||
padding: theme.spacing(1.25),
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
inputFieldDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
marginTop: theme.spacing(2.5),
|
||||
},
|
||||
privateRepoDetails: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
marginTop: theme.spacing(2.5),
|
||||
},
|
||||
formControl: {
|
||||
marginLeft: theme.spacing(3.125),
|
||||
},
|
||||
sshDiv: {
|
||||
backgroundColor: theme.palette.disabledBackground,
|
||||
padding: theme.spacing(2.5),
|
||||
},
|
||||
sshAlert: {
|
||||
color: theme.palette.error.main,
|
||||
fontSize: '0.75rem',
|
||||
},
|
||||
alertText: {
|
||||
marginBottom: theme.spacing(2.5),
|
||||
fontSize: '0.75rem',
|
||||
color: theme.palette.common.black,
|
||||
opacity: 0.4,
|
||||
},
|
||||
sshDataDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
backgroundColor: theme.palette.cards.background,
|
||||
padding: theme.spacing(2.5),
|
||||
borderRadius: 4,
|
||||
},
|
||||
sshText: {
|
||||
wordBreak: 'break-all',
|
||||
},
|
||||
copyBtn: {
|
||||
margin: 'auto',
|
||||
marginLeft: theme.spacing(2.5),
|
||||
borderLeft: `1px solid ${theme.palette.secondary.main}`,
|
||||
paddingLeft: theme.spacing(2.5),
|
||||
},
|
||||
privateToggleDiv: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
sshRadioBtn: {
|
||||
marginTop: theme.spacing(1.25),
|
||||
},
|
||||
toggleActive: {
|
||||
height: '2.25rem',
|
||||
backgroundColor: theme.palette.text.secondary,
|
||||
color: theme.palette.common.black,
|
||||
width: '6.25rem',
|
||||
textTransform: 'none',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.text.secondary,
|
||||
},
|
||||
},
|
||||
toggleInactive: {
|
||||
height: '2.25rem',
|
||||
backgroundColor: theme.palette.primary.dark,
|
||||
color: theme.palette.cards.background,
|
||||
width: '6.25rem',
|
||||
textTransform: 'none',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.primary.dark,
|
||||
},
|
||||
},
|
||||
toggleFont: {
|
||||
fontSize: '0.875rem',
|
||||
},
|
||||
radio: {
|
||||
color: theme.palette.primary.main,
|
||||
'&$checked': {
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
},
|
||||
checked: {},
|
||||
}));
|
||||
|
||||
export default useStyles;
|
|
@ -85,13 +85,15 @@ const MyHub = () => {
|
|||
</div>
|
||||
</div>
|
||||
{/* Developer Guide Component */}
|
||||
<div className={classes.developerDiv}>
|
||||
<DeveloperGuide
|
||||
expAvailable
|
||||
header={t('myhub.experimentPage.congrats')}
|
||||
description=""
|
||||
/>
|
||||
</div>
|
||||
{paramData.chart.toLowerCase() !== 'predefined' && (
|
||||
<div className={classes.developerDiv}>
|
||||
<DeveloperGuide
|
||||
expAvailable
|
||||
header={t('myhub.experimentPage.congrats')}
|
||||
description=""
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{/* Experiment Info */}
|
||||
<div className={classes.detailDiv}>
|
||||
<div className={classes.expInfo}>
|
||||
|
@ -128,23 +130,34 @@ const MyHub = () => {
|
|||
</div>
|
||||
</div>
|
||||
{/* Install Chaos Section */}
|
||||
<div className={classes.installLinks}>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.installExp')}
|
||||
description={t('myhub.experimentPage.installExpDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/charts/${paramData.chart}/${paramData.experiment}/experiment.yaml`}
|
||||
/>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.installRBAC')}
|
||||
description={t('myhub.experimentPage.installRBACDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/charts/${paramData.chart}/${paramData.experiment}/rbac.yaml`}
|
||||
/>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.installEngine')}
|
||||
description={t('myhub.experimentPage.installEngineDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/charts/${paramData.chart}/${paramData.experiment}/engine.yaml`}
|
||||
/>
|
||||
</div>
|
||||
{paramData.chart.toLowerCase() !== 'predefined' ? (
|
||||
<div className={classes.installLinks}>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.installExp')}
|
||||
description={t('myhub.experimentPage.installExpDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/charts/${paramData.chart}/${paramData.experiment}/experiment.yaml`}
|
||||
/>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.installRBAC')}
|
||||
description={t('myhub.experimentPage.installRBACDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/charts/${paramData.chart}/${paramData.experiment}/rbac.yaml`}
|
||||
/>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.installEngine')}
|
||||
description={t('myhub.experimentPage.installEngineDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/charts/${paramData.chart}/${paramData.experiment}/engine.yaml`}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<InstallChaos
|
||||
title={t('myhub.experimentPage.checkPreDefined')}
|
||||
description={t('myhub.experimentPage.checkPreDefinedDesc')}
|
||||
yamlLink={`${UserHub?.RepoURL}/raw/${UserHub?.RepoBranch}/workflows/${paramData.experiment}`}
|
||||
isPredefined
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -41,13 +41,14 @@ const useStyles = makeStyles((theme) => ({
|
|||
},
|
||||
expMain: {
|
||||
marginLeft: theme.spacing(1.25),
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
linkText: {
|
||||
fontSize: '1rem',
|
||||
},
|
||||
developerDiv: {
|
||||
marginLeft: theme.spacing(2.5),
|
||||
marginTop: theme.spacing(6.25),
|
||||
marginTop: theme.spacing(4.25),
|
||||
},
|
||||
detailDiv: {
|
||||
backgroundColor: theme.palette.common.white,
|
||||
|
|
|
@ -328,8 +328,8 @@ type ComplexityRoot struct {
|
|||
GetHubExperiment func(childComplexity int, experimentInput model.ExperimentInput) int
|
||||
GetHubStatus func(childComplexity int, projectID string) int
|
||||
GetImageRegistry func(childComplexity int, imageRegistryID string, projectID string) int
|
||||
GetPredefinedExperimentList func(childComplexity int, hubName string, projectID string) int
|
||||
GetPredefinedExperimentYaml func(childComplexity int, experimentInput model.ExperimentInput) int
|
||||
GetPredefinedWorkflowList func(childComplexity int, hubName string, projectID string) int
|
||||
GetProject func(childComplexity int, projectID string) int
|
||||
GetPromLabelNamesAndValues func(childComplexity int, series *model.PromSeriesInput) int
|
||||
GetPromQuery func(childComplexity int, query *model.PromInput) int
|
||||
|
@ -618,7 +618,7 @@ type QueryResolver interface {
|
|||
GetHubExperiment(ctx context.Context, experimentInput model.ExperimentInput) (*model.Chart, error)
|
||||
GetHubStatus(ctx context.Context, projectID string) ([]*model.MyHubStatus, error)
|
||||
GetYAMLData(ctx context.Context, experimentInput model.ExperimentInput) (string, error)
|
||||
GetPredefinedExperimentList(ctx context.Context, hubName string, projectID string) ([]string, error)
|
||||
GetPredefinedWorkflowList(ctx context.Context, hubName string, projectID string) ([]string, error)
|
||||
GetPredefinedExperimentYaml(ctx context.Context, experimentInput model.ExperimentInput) (string, error)
|
||||
ListDataSource(ctx context.Context, projectID string) ([]*model.DSResponse, error)
|
||||
GetPromQuery(ctx context.Context, query *model.PromInput) (*model.PromResponse, error)
|
||||
|
@ -2303,18 +2303,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Query.GetImageRegistry(childComplexity, args["image_registry_id"].(string), args["project_id"].(string)), true
|
||||
|
||||
case "Query.GetPredefinedExperimentList":
|
||||
if e.complexity.Query.GetPredefinedExperimentList == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Query_GetPredefinedExperimentList_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Query.GetPredefinedExperimentList(childComplexity, args["HubName"].(string), args["projectID"].(string)), true
|
||||
|
||||
case "Query.GetPredefinedExperimentYAML":
|
||||
if e.complexity.Query.GetPredefinedExperimentYaml == nil {
|
||||
break
|
||||
|
@ -2327,6 +2315,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Query.GetPredefinedExperimentYaml(childComplexity, args["experimentInput"].(model.ExperimentInput)), true
|
||||
|
||||
case "Query.GetPredefinedWorkflowList":
|
||||
if e.complexity.Query.GetPredefinedWorkflowList == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Query_GetPredefinedWorkflowList_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Query.GetPredefinedWorkflowList(childComplexity, args["HubName"].(string), args["projectID"].(string)), true
|
||||
|
||||
case "Query.getProject":
|
||||
if e.complexity.Query.GetProject == nil {
|
||||
break
|
||||
|
@ -4336,7 +4336,7 @@ type Query {
|
|||
|
||||
getYAMLData(experimentInput: ExperimentInput!): String!
|
||||
|
||||
GetPredefinedExperimentList(HubName: String!, projectID: String!): [String!]!
|
||||
GetPredefinedWorkflowList(HubName: String!, projectID: String!): [String!]!
|
||||
|
||||
GetPredefinedExperimentYAML(experimentInput: ExperimentInput!): String!
|
||||
|
||||
|
@ -5186,7 +5186,21 @@ func (ec *executionContext) field_Query_GetImageRegistry_args(ctx context.Contex
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_GetPredefinedExperimentList_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
func (ec *executionContext) field_Query_GetPredefinedExperimentYAML_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 model.ExperimentInput
|
||||
if tmp, ok := rawArgs["experimentInput"]; ok {
|
||||
arg0, err = ec.unmarshalNExperimentInput2githubᚗcomᚋlitmuschaosᚋlitmusᚋlitmusᚑportalᚋgraphqlᚑserverᚋgraphᚋmodelᚐExperimentInput(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["experimentInput"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_GetPredefinedWorkflowList_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 string
|
||||
|
@ -5208,20 +5222,6 @@ func (ec *executionContext) field_Query_GetPredefinedExperimentList_args(ctx con
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_GetPredefinedExperimentYAML_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 model.ExperimentInput
|
||||
if tmp, ok := rawArgs["experimentInput"]; ok {
|
||||
arg0, err = ec.unmarshalNExperimentInput2githubᚗcomᚋlitmuschaosᚋlitmusᚋlitmusᚑportalᚋgraphqlᚑserverᚋgraphᚋmodelᚐExperimentInput(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["experimentInput"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query_GetPromLabelNamesAndValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
|
@ -13863,7 +13863,7 @@ func (ec *executionContext) _Query_getYAMLData(ctx context.Context, field graphq
|
|||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_GetPredefinedExperimentList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
func (ec *executionContext) _Query_GetPredefinedWorkflowList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
|
@ -13879,7 +13879,7 @@ func (ec *executionContext) _Query_GetPredefinedExperimentList(ctx context.Conte
|
|||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.field_Query_GetPredefinedExperimentList_args(ctx, rawArgs)
|
||||
args, err := ec.field_Query_GetPredefinedWorkflowList_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
|
@ -13887,7 +13887,7 @@ func (ec *executionContext) _Query_GetPredefinedExperimentList(ctx context.Conte
|
|||
fc.Args = args
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Query().GetPredefinedExperimentList(rctx, args["HubName"].(string), args["projectID"].(string))
|
||||
return ec.resolvers.Query().GetPredefinedWorkflowList(rctx, args["HubName"].(string), args["projectID"].(string))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
|
@ -23539,7 +23539,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
|||
}
|
||||
return res
|
||||
})
|
||||
case "GetPredefinedExperimentList":
|
||||
case "GetPredefinedWorkflowList":
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
|
@ -23547,7 +23547,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
|||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._Query_GetPredefinedExperimentList(ctx, field)
|
||||
res = ec._Query_GetPredefinedWorkflowList(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ type Query {
|
|||
|
||||
getYAMLData(experimentInput: ExperimentInput!): String!
|
||||
|
||||
GetPredefinedExperimentList(HubName: String!, projectID: String!): [String!]!
|
||||
GetPredefinedWorkflowList(HubName: String!, projectID: String!): [String!]!
|
||||
|
||||
GetPredefinedExperimentYAML(experimentInput: ExperimentInput!): String!
|
||||
|
||||
|
|
|
@ -381,8 +381,8 @@ func (r *queryResolver) GetYAMLData(ctx context.Context, experimentInput model.E
|
|||
return myhub.GetYAMLData(ctx, experimentInput)
|
||||
}
|
||||
|
||||
func (r *queryResolver) GetPredefinedExperimentList(ctx context.Context, hubName string, projectID string) ([]string, error) {
|
||||
return myhub.GetPredefinedExperiementList(hubName, projectID)
|
||||
func (r *queryResolver) GetPredefinedWorkflowList(ctx context.Context, hubName string, projectID string) ([]string, error) {
|
||||
return myhub.GetPredefinedWorkflowList(hubName, projectID)
|
||||
}
|
||||
|
||||
func (r *queryResolver) GetPredefinedExperimentYaml(ctx context.Context, experimentInput model.ExperimentInput) (string, error) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
|
@ -104,6 +105,15 @@ func GetExperimentChartsVersionYamlPath(ctx context.Context, experimentInput mod
|
|||
return ExperimentPath
|
||||
}
|
||||
|
||||
// GetPredefinedWorkflowCSVPath is used to construct path for given chartsversion.yaml for pre-defined workflow.
|
||||
func GetPreDefinedWorkflowCSVPath(ctx context.Context, experimentInput model.ExperimentInput) string {
|
||||
ProjectID := experimentInput.ProjectID
|
||||
HubName := experimentInput.HubName
|
||||
experimentName := experimentInput.ExperimentName
|
||||
ExperimentPath := defaultPath + ProjectID + "/" + HubName + "/workflows/" + experimentName + "/" + experimentName + ".chartserviceversion.yaml"
|
||||
return ExperimentPath
|
||||
}
|
||||
|
||||
// GetExperimentYAMLPath is used to construct path for given experiment/engine.
|
||||
func GetExperimentYAMLPath(ctx context.Context, experimentInput model.ExperimentInput) string {
|
||||
ProjectID := experimentInput.ProjectID
|
||||
|
@ -179,7 +189,7 @@ func ReadExperimentYAMLFile(path string) (string, error) {
|
|||
}
|
||||
|
||||
// GetPredefinedExperimentFileList reads the workflow directory for all the predefined experiments
|
||||
func GetPredefinedExperimentFileList(hubname string, projectID string) ([]string, error) {
|
||||
func GetPredefinedWorkflowFileList(hubname string, projectID string) ([]string, error) {
|
||||
ExperimentsPath := defaultPath + projectID + "/" + hubname + "/workflows"
|
||||
var expNames []string
|
||||
files, err := ioutil.ReadDir(ExperimentsPath)
|
||||
|
@ -187,7 +197,20 @@ func GetPredefinedExperimentFileList(hubname string, projectID string) ([]string
|
|||
return nil, err
|
||||
}
|
||||
for _, file := range files {
|
||||
expNames = append(expNames, file.Name())
|
||||
isExist, _ := IsFileExisting(ExperimentsPath + "/" + file.Name() + "/" + file.Name() + ".chartserviceversion.yaml")
|
||||
if isExist {
|
||||
expNames = append(expNames, file.Name())
|
||||
}
|
||||
}
|
||||
return expNames, nil
|
||||
}
|
||||
|
||||
func IsFileExisting(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -231,13 +232,16 @@ func GetCharts(ctx context.Context, hubName string, projectID string) ([]*model.
|
|||
|
||||
// GetExperiment is used for getting details of a given experiment using chartserviceversion.yaml.
|
||||
func GetExperiment(ctx context.Context, experimentInput model.ExperimentInput) (*model.Chart, error) {
|
||||
|
||||
ExperimentPath := handler.GetExperimentChartsVersionYamlPath(ctx, experimentInput)
|
||||
var ExperimentPath string
|
||||
if strings.ToLower(experimentInput.ChartName) == "predefined" {
|
||||
ExperimentPath = handler.GetPreDefinedWorkflowCSVPath(ctx, experimentInput)
|
||||
} else {
|
||||
ExperimentPath = handler.GetExperimentChartsVersionYamlPath(ctx, experimentInput)
|
||||
}
|
||||
ExperimentData, err := handler.GetExperimentData(ExperimentPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ExperimentData, nil
|
||||
}
|
||||
|
||||
|
@ -394,11 +398,23 @@ func DeleteMyHub(ctx context.Context, hubID string) (bool, error) {
|
|||
// GetIconHandler ...
|
||||
var GetIconHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
img, err := os.Open("/tmp/version/" + vars["ProjectID"] + "/" + vars["HubName"] + "/charts/" + vars["ChartName"] + "/icons/" + vars["IconName"])
|
||||
responseStatusCode := 200
|
||||
if err != nil {
|
||||
responseStatusCode = 500
|
||||
fmt.Fprint(w, "icon cannot be fetched, err : "+err.Error())
|
||||
var img *os.File
|
||||
var err error
|
||||
var responseStatusCode int
|
||||
if strings.ToLower(vars["ChartName"]) == "predefined" {
|
||||
img, err = os.Open("/tmp/version/" + vars["ProjectID"] + "/" + vars["HubName"] + "/workflows/icons/" + vars["IconName"])
|
||||
responseStatusCode = 200
|
||||
if err != nil {
|
||||
responseStatusCode = 500
|
||||
fmt.Fprint(w, "icon cannot be fetched, err : "+err.Error())
|
||||
}
|
||||
} else {
|
||||
img, err = os.Open("/tmp/version/" + vars["ProjectID"] + "/" + vars["HubName"] + "/charts/" + vars["ChartName"] + "/icons/" + vars["IconName"])
|
||||
responseStatusCode = 200
|
||||
if err != nil {
|
||||
responseStatusCode = 500
|
||||
fmt.Fprint(w, "icon cannot be fetched, err : "+err.Error())
|
||||
}
|
||||
}
|
||||
defer img.Close()
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
|
@ -436,8 +452,8 @@ func RecurringHubSync() {
|
|||
}
|
||||
}
|
||||
|
||||
func GetPredefinedExperiementList(hubname string, projectID string) ([]string, error) {
|
||||
expList, err := handler.GetPredefinedExperimentFileList(hubname, projectID)
|
||||
func GetPredefinedWorkflowList(hubname string, projectID string) ([]string, error) {
|
||||
expList, err := handler.GetPredefinedWorkflowFileList(hubname, projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue