-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ui): Add cost optimisation nudges. #3089
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import * as React from 'react'; | ||
import {Notice} from './notice'; | ||
|
||
interface Props { | ||
name: string; | ||
} | ||
interface State { | ||
closed: boolean; | ||
} | ||
|
||
export class CostOptimisationNudge extends React.Component<Props, State> { | ||
constructor(props: Readonly<Props>) { | ||
super(props); | ||
this.state = {closed: localStorage.getItem(this.key) !== null}; | ||
} | ||
|
||
public render() { | ||
return ( | ||
!this.state.closed && ( | ||
<Notice> | ||
<i className='fa fa-money-bill-alt status-icon--pending' /> {this.props.children}{' '} | ||
<a href='https://github.com/argoproj/argo/blob/master/docs/cost-optimisation.md'>Learn more</a> | ||
<span className='fa-pull-right'> | ||
<a onClick={() => this.close()}> | ||
<i className='fa fa-times' /> | ||
</a>{' '} | ||
</span> | ||
</Notice> | ||
) | ||
); | ||
} | ||
|
||
private get key() { | ||
return 'cost-optimization-nude/' + this.props.name; | ||
} | ||
|
||
private close() { | ||
this.setState({closed: true}); | ||
localStorage.setItem(this.key, '{}'); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as React from 'react'; | ||
|
||
export class Notice extends React.Component { | ||
public render() { | ||
return ( | ||
<div style={{marginTop: 20, marginBottom: 20}}> | ||
<div className='white-box' style={{padding: 20}}> | ||
{this.props.children} | ||
</div> | ||
</div> | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ import {uiUrl} from '../../../shared/base'; | |
import {services} from '../../../shared/services'; | ||
|
||
import {WorkflowArtifacts, WorkflowDag, WorkflowLogsViewer, WorkflowNodeInfo, WorkflowSummaryPanel, WorkflowTimeline, WorkflowYamlViewer} from '..'; | ||
import {CostOptimisationNudge} from '../../../shared/components/cost-optimisation-nudge'; | ||
import {hasWarningConditionBadge} from '../../../shared/conditions-panel'; | ||
import {Consumer, ContextApis} from '../../../shared/context'; | ||
import {Utils} from '../../../shared/utils'; | ||
|
@@ -360,6 +361,27 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W | |
this.appContext.router.history.push(`${this.props.match.url}?${params.toString()}`); | ||
} | ||
|
||
private renderCostOptimisations() { | ||
const recommendations: string[] = []; | ||
if (!this.state.workflow.spec.activeDeadlineSeconds) { | ||
recommendations.push('activeDeadlineSeconds'); | ||
} | ||
if (!this.state.workflow.spec.ttlStrategy) { | ||
recommendations.push('ttlStrategy'); | ||
} | ||
if (!this.state.workflow.spec.podGC) { | ||
recommendations.push('podGC'); | ||
} | ||
if (recommendations.length === 0) { | ||
return; | ||
} | ||
return ( | ||
<CostOptimisationNudge name='workflow'> | ||
You do not have {recommendations.join('/')} enabled for this workflow. Enabling these will reduce your costs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a link to the cost optimization docs here would be invaluable. I think we should wait until #2972 is merged and add the permalink to the doc here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. contains that - so this PR depends on that PR |
||
</CostOptimisationNudge> | ||
); | ||
} | ||
|
||
private renderSummaryTab() { | ||
if (!this.state.workflow) { | ||
return <div>Loading...</div>; | ||
|
@@ -368,6 +390,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W | |
<div className='argo-container'> | ||
<div className='workflow-details__content'> | ||
<WorkflowSummaryPanel workflow={this.state.workflow} /> | ||
{this.renderCostOptimisations()} | ||
{this.state.workflow.spec.arguments && this.state.workflow.spec.arguments.parameters && ( | ||
<React.Fragment> | ||
<h6>Parameters</h6> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, was curious as to how you would persist the closure.