chore(litmus-portal): Added env tunables, date range for usage stats and fixed logs issue (#2958)

* Added env tunables, date range for usage stats and fixed logs issues
* Minor theme change
* Minor translations fix

Signed-off-by: Amit Kumar Das <amit@chaosnative.com>
This commit is contained in:
Amit Kumar Das 2021-07-02 17:17:54 +05:30 committed by GitHub
parent 5bc3896171
commit 9c38833287
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 498 additions and 103 deletions

View File

@ -25,7 +25,6 @@ getStarted:
sidebar:
title: Litmus
version: "Version: 1.13"
header:
projectDropdown:
@ -34,7 +33,7 @@ header:
otherProjects: Other Projects
noProjectsOther: You are not part of any projects not owned by you
profileDropdown:
signedIn: "Signed in as:"
signedIn: 'Signed in as:'
emailUnset: Email not set
emailSet: Set up your email
switchProject: Please switch to a project you own to access settings
@ -89,7 +88,7 @@ workflowStepper:
back: Back
editor:
status: "YAML Status:"
status: 'YAML Status:'
######################################
############ Pages #############
@ -107,14 +106,14 @@ login:
tooltipText: You need to contact your admin to reset your password.
schedule:
heading: "Schedule a workflow"
headingDesc: "Click on test to see detailed log of your workflow"
headingText: "Schedule details:"
description: "Choose the right time to schedule your first workflow. Below you can find some options that may be convenient for you."
save: "Save Changes"
heading: 'Schedule a workflow'
headingDesc: 'Click on test to see detailed log of your workflow'
headingText: 'Schedule details:'
description: 'Choose the right time to schedule your first workflow. Below you can find some options that may be convenient for you.'
save: 'Save Changes'
scheduleNow: Schedule now
scheduleAfter: Schedule after some time
scheduleAfterSometime: "Choose the minutes, hours, or days when you want to start workflow"
scheduleAfterSometime: 'Choose the minutes, hours, or days when you want to start workflow'
scheduleSpecificTime: Schedule at a specific time
scheduleFuture: Select date and time to start workflow in future
scheduleRecurring: Recurring Schedule
@ -122,7 +121,7 @@ schedule:
after: After
at: at
At: At
scheduleOn: "On"
scheduleOn: 'On'
missingPerm: Missing sufficient permissions :(
requiredPerm: Looks like you do not have the required permission to create a new workflow on this project.
contact: Contact portal administrator to upgrade your permission.
@ -143,11 +142,11 @@ editSchedule:
successfullyCreated: is successfully created
community:
title: "Community"
heading: "Litmus Insights"
headingDesc: "Stats for the Litmus community"
analyticDesc: "Periodic growth of Litmus"
statsHeading: "Litmus users around the world:"
title: 'Community'
heading: 'Litmus Insights'
headingDesc: 'Stats for the Litmus community'
analyticDesc: 'Periodic growth of Litmus'
statsHeading: 'Litmus users around the world:'
litmusChaos: Litmuschaos
follow: Follow
@ -158,8 +157,8 @@ analytics:
comingSoon: Analytics Coming Soon !
waitingMessage: Waiting for workflow to start running !
chaosCompleteWaitingMessage: Waiting for chaos experiment to finish !
highestScore: "Highest Score:"
lowestScore: "Lowest Score:"
highestScore: 'Highest Score:'
lowestScore: 'Lowest Score:'
exportPDF: Export PDF
compareWorkflows: Compare workflows
targetCluster: Target cluster
@ -443,7 +442,7 @@ analyticsDashboard:
warning:
text: Unexpected bad things will happen if you dont read this!
info: The data source seems to be connected to following Application dashboards. Dashboards will be unable to show metrics if the data source is deleted.
connectedDashboards: "Connected Dashboards :"
connectedDashboards: 'Connected Dashboards :'
showLess: Show Less Dashboards
dashboards: Dashboards
deletionSuccess: Successfully deleted the data source
@ -547,8 +546,8 @@ homeViews:
recentWorkflowRuns:
workflowRunCard:
cardTitle: Browse workflow
resilienceRate: "Overall resilience rate:"
lastRun: "Last Run:"
resilienceRate: 'Overall resilience rate:'
lastRun: 'Last Run:'
showAnalytics: Show the analytics
downloadManifest: Download manifest
heading: Recent Workflow runs
@ -591,7 +590,7 @@ chaosWorkflows:
disableSchedule: Disable Schedule
enableSchedule: Enable Schedule
saveTemplate: Save Template
updateEngine: "Note: Make sure to update the chaos engine names"
updateEngine: 'Note: Make sure to update the chaos engine names'
saveChanges: Save Changes
savedSuccessfully: Successfully saved template.
cancel: Cancel
@ -613,8 +612,8 @@ chaosWorkflows:
sync: Sync Workflow
terminate: Terminate Workflow
tableData:
overallRR: "Overall RR : "
experimentsPassed: "Experiments Passed : "
overallRR: 'Overall RR : '
experimentsPassed: 'Experiments Passed : '
showExperiments: Show Experiments
showTheWorkflow: Show the workflow
showTheAnalytics: Show the analytics
@ -803,7 +802,7 @@ settings:
disconnect: Are you sure you want to disconnect?
save: Save Locally
repo: Git Repository
desc: "* Any existing or active workflows saved locally will not be synced into the git repository"
desc: '* Any existing or active workflows saved locally will not be synced into the git repository'
connect: Connect
branch: Branch
URL: Git URL
@ -818,11 +817,11 @@ settings:
headingDesc: Your image registry for the workflow manifest
defaultValues: Use the default values
defaultText: All YAML files use these default values provided by Litmus. The values cannot be changed.
registry: "Registry : "
repo: "Repository : "
repoType: "Registry Type : "
dockerio: "docker.io"
litmus: "litmuschaos"
registry: 'Registry : '
repo: 'Repository : '
repoType: 'Registry Type : '
dockerio: 'docker.io'
litmus: 'litmuschaos'
public: Public
private: Private
defaultReg: Use Default Registry
@ -854,12 +853,12 @@ workflowDetailsView:
Completed: Completed
runTime:
runTimeHeader: Run Time
startTime: "Start Time :"
endTime: "End Time :"
startTime: 'Start Time :'
endTime: 'End Time :'
targets:
targetsHeader: Target
cluster: "Cluster :"
namespace: "Workflow Namespace :"
cluster: 'Cluster :'
namespace: 'Workflow Namespace :'
workflowNodeInfo:
name: Name
type: Type
@ -914,8 +913,8 @@ createWorkflow:
revertSchedule: Revert Schedule
noTemplates: No template available.
addTemplate: You can add a template from the scheduled workflows table.
trueValue: "True"
falseValue: "False"
trueValue: 'True'
falseValue: 'False'
table:
head1: Sequence
head2: Name
@ -1010,8 +1009,8 @@ createWorkflow:
myHubInfo: Experiment details
annotationInfo: Provide target application details where you want to induce the chaos.
annotation: Annotation Check
true: "True"
false: "False"
true: 'True'
false: 'False'
annotationDesc: The target application does not have an annotation “Chaos=true”. Ideally, you cannot run this experiment unless the annotation is patched to the application. However, this service account has the privileges to disable the enforcement of annotation checks. Mark the annotation as false to proceed.
appkind: appKind
deployment: Deployment
@ -1020,7 +1019,7 @@ createWorkflow:
deploymentconfig: Deploymentconfig
rollout: Rollout
nodeselector: NodeSelector
selector: "kubernetes.io/hostname :"
selector: 'kubernetes.io/hostname :'
nsError: Namespace not available
labelError: Label not available in the resource or namespace
deleteExp: Delete the experiment
@ -1034,9 +1033,16 @@ createWorkflow:
showDetails: Show Details
showProp: Show Properties
addProbe: Please add probes to see the data
addNewProbe: "+ Add a new Probe"
addNewProbe: '+ Add a new Probe'
back: Back
finish: Finish
env:
envHeading: Tune the environment variables of the experiment
showMoreEnv: Show more environment variables
showLessEnv: Show less environment variables
key: Key Tunables
addKey: Add a key-value pair
finish: Finish
addProbe:
heading: Add
headingStrong: Probe
@ -1216,7 +1222,7 @@ browseTemplate:
#########################################
internetIssues:
fetchData: "Fetching the data..."
fetchData: 'Fetching the data...'
connectionError: It seems you have no internet connection, Please try again When connectivity resumes.
######################################
@ -1226,14 +1232,14 @@ myhub:
title: MyHubs
connectTarget: Connect the target
viewMyHub: View My Hub
error: "[Error: could not connect]"
error: '[Error: could not connect]'
view: View
validationEmptySpace: Should not start with an empty space
validURL: Enter a valid URL
edit: Edit Hub
refresh: Refresh Hub
disconnect: Disconnect Hub
lastSync: "Last synced at:"
lastSync: 'Last synced at:'
mainPage:
header: ChaosHubs
github: github.com/
@ -1261,9 +1267,9 @@ myhub:
chaosCharts: Chaos-charts
noPredefinedExp: No predefined workflows available with information in this Hub
noExp: No experiments found
lastSynced: "Last synced at: "
repoLink: "Repository Link: "
repoBranch: "Repository Branch: "
lastSynced: 'Last synced at: '
repoLink: 'Repository Link: '
repoBranch: 'Repository Branch: '
connectHubPage:
connectHub: Connect a new chaos hub
editHub: Edit hub configuration
@ -1281,7 +1287,7 @@ myhub:
accessToken: Access Token
ssh: SSH
sshText: Please enable read / write access on the above git repository for the following key
sshAlert: "*Make sure to provide the SSH link of the Git Repository"
sshAlert: '*Make sure to provide the SSH link of the Git Repository'
saveLater: Save for later
updateHub: Update the MyHub with correct details from the MyHubs section
cancel: Cancel

View File

@ -0,0 +1,90 @@
import React, { useState } from 'react';
import { Button, IconButton, Popover, Typography } from '@material-ui/core';
import { useTheme } from '@material-ui/core/styles';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
import { DateRangePicker } from 'react-date-range';
import 'react-date-range/dist/styles.css'; // main css file
import 'react-date-range/dist/theme/default.css'; // theme css file
import useStyles from './styles';
interface UsageRangePickerProps {
isOpen: boolean;
popAnchorEl: HTMLElement | null;
displayDate: string;
popOverClick: (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => void;
popOverClose: (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => void;
selectDate: (selectFromDate: string, selectToDate: string) => void;
}
const UsageRangePicker: React.FC<UsageRangePickerProps> = ({
isOpen,
popAnchorEl,
displayDate,
popOverClick,
popOverClose,
selectDate,
}) => {
const classes = useStyles();
const { palette } = useTheme();
const [state, setState] = useState([
{
startDate: new Date(new Date().getFullYear(), new Date().getMonth(), 1),
endDate: new Date(),
key: 'selection',
},
]);
return (
<div className={classes.dateRangeDiv}>
<Button className={classes.selectDate} onClick={popOverClick}>
<Typography className={classes.displayDate}>
{displayDate}
<IconButton className={classes.dateRangeIcon}>
{isOpen ? <KeyboardArrowDownIcon /> : <ChevronRightIcon />}
</IconButton>
</Typography>
</Button>
<Popover
open={isOpen}
anchorEl={popAnchorEl}
onClose={popOverClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
style={{
marginTop: 10,
}}
>
<DateRangePicker
onChange={(item) => {
setState([(item as any).selection]);
selectDate(
`${(item as any).selection.startDate}`,
`${(item as any).selection.endDate}`
);
}}
showSelectionPreview
moveRangeOnFirstSelection={false}
months={1}
ranges={state}
direction="vertical"
editableDateInputs
rangeColors={[palette.primary.dark]}
showMonthAndYearPickers
/>
</Popover>
</div>
);
};
export default UsageRangePicker;

View File

@ -1,28 +1,93 @@
import { Typography } from '@material-ui/core';
import React from 'react';
import { useTranslation } from 'react-i18next';
import moment from 'moment';
import Scaffold from '../../containers/layouts/Scaffold';
import UsageStats from '../../views/UsageStatistics/UsageStats';
import UsageTable from '../../views/UsageStatistics/UsageTable';
import UsageRangePicker from './datePicker';
import useStyles from './styles';
interface DateRange {
start_date: string;
end_date: string;
}
const UsageStatistics = () => {
const classes = useStyles();
const { t } = useTranslation();
const [popAnchorEl, setPopAnchorEl] = React.useState<null | HTMLElement>(
null
);
/**
* State variable to set date in UNIX format
*/
const [dates, setDates] = React.useState<DateRange>({
start_date: Math.trunc(
new Date(new Date().getFullYear(), new Date().getMonth(), 1).getTime() /
1000
).toString(),
end_date: Math.trunc(new Date().getTime() / 1000).toString(),
});
/**
* State variable for displaying dates
*/
const [displayDate, setDisplayDate] = React.useState<string>(
`${moment(parseInt(dates.start_date, 10) * 1000).format(
'DD.MM.YY'
)}-${moment(parseInt(dates.end_date, 10) * 1000).format('DD.MM.YY')}`
);
const isOpen = Boolean(popAnchorEl);
const handlePopOverClose = () => {
setPopAnchorEl(null);
};
const handlePopOverClick = (event: React.MouseEvent<HTMLElement>) => {
setPopAnchorEl(event.currentTarget);
};
const dateChange = (selectStartDate: string, selectEndDate: string) => {
// Change the display value of date range
setDisplayDate(
`${moment(selectStartDate).format('DD.MM.YYYY').toString()}-${moment(
selectEndDate
)
.format('DD.MM.YYYY')
.toString()}`
);
setDates({
start_date: moment(selectStartDate).unix().toString(),
end_date: moment(selectEndDate).unix().toString(),
});
};
return (
<Scaffold>
<Typography variant="h3">{t('usage.usageHeader')}</Typography>
<div style={{ display: 'flex' }}>
<Typography className={classes.description}>
{t('usage.usageSubtitle')}
</Typography>
<UsageStats />
<UsageRangePicker
popOverClick={handlePopOverClick}
popOverClose={handlePopOverClose}
isOpen={isOpen}
popAnchorEl={popAnchorEl}
displayDate={displayDate}
selectDate={dateChange}
/>
</div>
<UsageStats start_time={dates.start_date} end_time={dates.end_date} />
<br />
<br />
<Typography variant="h4">{t('usage.projectStatistics')}</Typography>
<Typography className={classes.description}>
{t('usage.projectSubtitle')}
</Typography>
<UsageTable />
<UsageTable start_time={dates.start_date} end_time={dates.end_date} />
</Scaffold>
);
};

View File

@ -10,5 +10,26 @@ const useStyles = makeStyles((theme: Theme) => ({
margin: theme.spacing(3, 0),
color: theme.palette.text.hint,
},
selectDate: {
display: 'flex',
flexDirection: 'row',
height: '2.5rem',
minWidth: '9rem',
border: '0.125rem solid',
marginRight: theme.spacing(3.75),
textTransform: 'none',
borderColor: theme.palette.primary.main,
},
displayDate: {
marginLeft: theme.spacing(1),
width: '100%',
},
dateRangeDiv: {
marginLeft: 'auto',
},
dateRangeIcon: {
width: '0.625rem',
height: '0.625rem',
},
}));
export default useStyles;

View File

@ -8,6 +8,7 @@ import { ButtonOutlined } from 'litmus-ui';
import General from '../TuneWorkflowSteps/General';
import SteadyState from '../TuneWorkflowSteps/SteadyState';
import TargetApplication from '../TuneWorkflowSteps/TargetApplication';
import EnvironmentVariables from '../TuneWorkflowSteps/EnvironmentVariables';
import useStyles from './styles';
interface ConfigurationStepperProps {
@ -29,12 +30,12 @@ function getStepContent(
case 0:
return <General isCustom={isCustom} gotoStep={gotoStep} />;
case 1:
return (
<TargetApplication engineIndex={engineIndex} gotoStep={gotoStep} />
);
return <TargetApplication gotoStep={gotoStep} />;
case 2:
return <SteadyState gotoStep={gotoStep} />;
case 3:
return (
<SteadyState
<EnvironmentVariables
engineIndex={engineIndex}
gotoStep={gotoStep}
closeStepper={closeStepper}
@ -60,6 +61,7 @@ const ConfigurationStepper: React.FC<ConfigurationStepperProps> = ({
'General',
'Target Application',
'Define the steady state for this application',
'Tune Experiment',
];
const gotoStep = (page: number) => {

View File

@ -0,0 +1,210 @@
import { Button, Typography } from '@material-ui/core';
import { ButtonFilled, InputField } from 'litmus-ui';
import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import YAML from 'yaml';
import AddIcon from '@material-ui/icons/Add';
import { WorkflowManifest } from '../../../../models/redux/workflow';
import useActions from '../../../../redux/actions';
import * as WorkflowActions from '../../../../redux/actions/workflow';
import { RootState } from '../../../../redux/reducers';
import useStyles from './styles';
interface EnvVariableProps {
engineIndex: number;
gotoStep: (page: number) => void;
closeStepper: () => void;
}
interface EnvValues {
name: string;
value: string;
}
const EnvironmentVariables: React.FC<EnvVariableProps> = ({
gotoStep,
engineIndex,
closeStepper,
}) => {
const { t } = useTranslation();
const classes = useStyles();
const workflow = useActions(WorkflowActions);
const manifest: WorkflowManifest = useSelector(
(state: RootState) => state.workflowManifest
);
/**
* State variable for managing the additional key-value pair
*/
const [addEnv, setAddEnv] = useState<EnvValues>({
name: '',
value: '',
});
/**
* State variable to display Show More / Show Less
*/
const [showMore, setShowMore] = useState(false);
const engine = useSelector(
(state: RootState) => state.workflowManifest.engineYAML
);
const engineYAML = YAML.parse(engine);
/**
* State variable to store all the env varaibles from the engine
*/
const [env, setEnvs] = useState<EnvValues[]>(
engineYAML.spec.experiments[0].spec.components.env
);
/**
* getShowMoreItems functions returns all the envs
* if showMore is true, else this returns maximum of
* 3 envs.
*/
const getShowMoreItems = (env: EnvValues[]) => {
if (showMore) {
return env;
}
return env.slice(0, 3);
};
/**
* handleMainYAMLChange funtion makes the changes
* in the engine YAML and then adds the engine manifest
* to the overall workflow YAML
*/
const handleMainYAMLChange = () => {
engineYAML.spec.experiments[0].spec.components.env = env;
const mainManifest = YAML.parse(manifest.manifest);
mainManifest.spec.templates[engineIndex].inputs.artifacts[0].raw.data =
YAML.stringify(engineYAML);
workflow.setWorkflowManifest({
manifest: YAML.stringify(mainManifest),
engineYAML: YAML.stringify(engineYAML),
});
closeStepper();
};
return (
<div>
<Typography>{t('createWorkflow.tuneWorkflow.env.envHeading')}</Typography>
<br />
<div className={classes.inputDiv}>
{getShowMoreItems(env).map((data, index) => {
return (
<>
<InputField
width="auto"
label={data.name}
value={env[index].value}
onChange={(event) => {
env[index].value = event.target.value;
setEnvs([...env]);
}}
/>
<br />
</>
);
})}
<div>
{env.length > 3 && !showMore ? (
<ButtonFilled
className={classes.showMoreBtn}
onClick={() => {
setShowMore(true);
}}
>
<ArrowDownwardIcon />
<Typography>
{t('createWorkflow.tuneWorkflow.env.showMoreEnv')}
</Typography>
</ButtonFilled>
) : showMore ? (
<ButtonFilled
className={classes.showMoreBtn}
onClick={() => {
setShowMore(false);
}}
>
<ArrowUpwardIcon />
<Typography>
{t('createWorkflow.tuneWorkflow.env.showLessEnv')}
</Typography>
</ButtonFilled>
) : (
<></>
)}
</div>
<div>
<Typography className={classes.keyText}>
{t('createWorkflow.tuneWorkflow.env.key')}
</Typography>
<br />
<div style={{ display: 'flex' }}>
<InputField
label="Add Key"
value={addEnv.name}
onChange={(event) => {
setAddEnv({
...addEnv,
name: event.target.value,
});
}}
width="20"
className={classes.addKeyInput}
/>
<InputField
label="Add Value"
value={addEnv.value}
onChange={(event) => {
setAddEnv({
...addEnv,
value: event.target.value,
});
}}
width="20"
/>
</div>
<ButtonFilled
className={classes.addKeyValue}
onClick={() => {
env[env.length] = {
name: addEnv.name,
value: addEnv.value,
};
setEnvs(env);
setAddEnv({
name: '',
value: '',
});
}}
disabled={addEnv.name.trim() === '' || addEnv.value.trim() === ''}
>
<AddIcon /> {t('createWorkflow.tuneWorkflow.env.addKey')}
</ButtonFilled>
</div>
</div>
<div>
<Button onClick={() => gotoStep(2)} className={classes.button}>
{t('workflowStepper.back')}
</Button>
<Button
variant="contained"
color="primary"
onClick={() => handleMainYAMLChange()}
className={classes.button}
>
{t('createWorkflow.tuneWorkflow.env.finish')}
</Button>
</div>
</div>
);
};
export default EnvironmentVariables;

View File

@ -24,16 +24,10 @@ import AddProbe from '../AddProbe';
import useStyles from './styles';
interface SteadyStateProps {
engineIndex: number;
gotoStep: (page: number) => void;
closeStepper: () => void;
}
const SteadyState: React.FC<SteadyStateProps> = ({
engineIndex,
gotoStep,
closeStepper,
}) => {
const SteadyState: React.FC<SteadyStateProps> = ({ gotoStep }) => {
const classes = useStyles();
const { t } = useTranslation();
const workflow = useActions(WorkflowActions);
@ -55,14 +49,9 @@ const SteadyState: React.FC<SteadyStateProps> = ({
setAddProbe(false);
};
// handleManiYAMLChange allows to update the main manifest
// with the changes in individual Chaos Engines
// handleManiYAMLChange allows to update the changes in individual Chaos Engines
const handleMainYAMLChange = () => {
const mainManifest = YAML.parse(manifest.manifest);
mainManifest.spec.templates[engineIndex].inputs.artifacts[0].raw.data =
YAML.stringify(chaosEngine);
workflow.setWorkflowManifest({
manifest: YAML.stringify(mainManifest),
engineYAML: YAML.stringify(chaosEngine),
});
};
@ -103,10 +92,10 @@ const SteadyState: React.FC<SteadyStateProps> = ({
setAddProbe(false);
};
const handleStepperClose = () => {
const handleNext = () => {
chaosEngine.spec.experiments[0].spec.probe = probesData;
handleMainYAMLChange();
return closeStepper();
gotoStep(3);
};
return (
@ -269,10 +258,10 @@ const SteadyState: React.FC<SteadyStateProps> = ({
<Button
variant="contained"
color="primary"
onClick={() => handleStepperClose()}
onClick={() => handleNext()}
className={classes.button}
>
{t('createWorkflow.tuneWorkflow.steadyState.finish')}
Next
</Button>
</div>
</div>

View File

@ -51,14 +51,10 @@ interface TargetApplicationData {
}
interface TargetApplicationProp {
engineIndex: number;
gotoStep: (page: number) => void;
}
const TargetApplication: React.FC<TargetApplicationProp> = ({
engineIndex,
gotoStep,
}) => {
const TargetApplication: React.FC<TargetApplicationProp> = ({ gotoStep }) => {
const { t } = useTranslation();
/**
* State Variables to manage theme changes
@ -152,9 +148,7 @@ const TargetApplication: React.FC<TargetApplicationProp> = ({
];
}
engineManifest.spec.jobCleanUpPolicy = targetApp.jobCleanUpPolicy;
const mainManifest = YAML.parse(manifest.manifest);
mainManifest.spec.templates[engineIndex].inputs.artifacts[0].raw.data =
YAML.stringify(engineManifest);
workflow.setWorkflowManifest({
engineYAML: YAML.stringify(engineManifest),
});

View File

@ -10,6 +10,13 @@ const useStyles = makeStyles((theme: Theme) => ({
marginTop: theme.spacing(1),
marginRight: theme.spacing(1),
},
showMoreBtn: {
display: 'flex',
color: theme.palette.primary.main,
backgroundColor: 'transparent !important',
cursor: 'pointer',
marginBottom: theme.spacing(2.5),
},
actionsContainer: {
marginBottom: theme.spacing(2),
},
@ -20,7 +27,12 @@ const useStyles = makeStyles((theme: Theme) => ({
border: 'none !important',
color: theme.palette.primary.main,
},
keyText: {
fontSize: '1rem',
},
addKeyInput: {
marginRight: theme.spacing(2.25),
},
// General Component
generalContainer: {
display: 'flex',
@ -33,6 +45,14 @@ const useStyles = makeStyles((theme: Theme) => ({
flexDirection: 'column',
maxWidth: '25rem',
},
addKeyValue: {
backgroundColor: 'transparent !important',
color: theme.palette.primary.main,
marginTop: theme.spacing(1.25),
marginBottom: theme.spacing(2.25),
},
annotation: {
fontSize: '0.875rem',
margin: theme.spacing(0.6, 2, 0, 0),

View File

@ -6,7 +6,12 @@ import { GET_GLOBAL_STATS } from '../../../graphql';
import Card from './Cards';
import useStyles from './styles';
const UsageStats = () => {
interface TimeRange {
start_time: string;
end_time: string;
}
const UsageStats: React.FC<TimeRange> = ({ start_time, end_time }) => {
const classes = useStyles();
const { t } = useTranslation();
const [usageQuery, { loading, data }] = useLazyQuery(GET_GLOBAL_STATS);
@ -16,19 +21,13 @@ const UsageStats = () => {
variables: {
query: {
DateRange: {
start_date: Math.trunc(
new Date(
new Date().getFullYear(),
new Date().getMonth(),
1
).getTime() / 1000
).toString(),
end_date: Math.trunc(new Date().getTime() / 1000).toString(),
start_date: start_time,
end_date: end_time,
},
},
},
});
}, []);
}, [start_time, end_time]);
return (
<div className={classes.cardDiv}>

View File

@ -33,7 +33,12 @@ interface SortInput {
Descending?: boolean;
}
const UsageTable = () => {
interface TimeRange {
start_time: string;
end_time: string;
}
const UsageTable: React.FC<TimeRange> = ({ start_time, end_time }) => {
const classes = useStyles();
const { t } = useTranslation();
const [paginationData, setPaginationData] = useState<Pagination>({
@ -46,21 +51,15 @@ const UsageTable = () => {
});
const [search, setSearch] = useState<string>('');
const [usageQuery, { loading, data }] = useLazyQuery(GLOBAL_PROJECT_DATA, {});
const [usageQuery, { loading, data }] = useLazyQuery(GLOBAL_PROJECT_DATA);
useEffect(() => {
usageQuery({
variables: {
query: {
DateRange: {
start_date: Math.trunc(
new Date(
new Date().getFullYear(),
new Date().getMonth(),
1
).getTime() / 1000
).toString(),
end_date: Math.trunc(new Date().getTime() / 1000).toString(),
start_date: start_time,
end_date: end_time,
},
Pagination: {
page: paginationData.page,
@ -71,7 +70,7 @@ const UsageTable = () => {
},
},
});
}, [paginationData, search, sortData]);
}, [paginationData, search, sortData, start_time, end_time]);
return (
<div className={classes.table}>

View File

@ -87,7 +87,7 @@ const LogsSwitcher: React.FC<LogsSwitcherProps> = ({
chaos_namespace: '',
});
}
}, [workflow_data]);
}, [workflow_data, pod_name]);
const [chaosResult, setChaosResult] = useState('');