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 drawer with more details for each workflow in Workflow List #3151
Changes from 28 commits
8b20eda
736cd00
6af5d5d
0b4cf34
5001871
e88cd10
b61ca97
58e61f4
9a7b5dc
a7a7c02
376d96f
7186409
27db356
85e115a
c0b630f
1a5031f
d85d192
45eab5d
b24ee90
251f89f
7ec9961
59c21b0
ae73519
084f923
1017094
161c3cb
42155c3
f209bdb
e572625
6c686d8
7d9cbe0
0231220
2720473
dce8c0d
57fb2d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,7 +32,11 @@ export class WorkflowsService { | |
} | ||
|
||
public watch(filter: {namespace?: string; name?: string; phases?: Array<string>; labels?: Array<string>}): Observable<models.kubernetes.WatchEvent<Workflow>> { | ||
const url = `api/v1/workflow-events/${filter.namespace || ''}?${this.queryParams(filter).join('&')}`; | ||
const params = this.queryParams(filter); | ||
params.push( | ||
`fields=result.object.metadata.name,result.object.metadata.namespace,result.object.status.finishedAt,result.object.status.startedAt,result.object.status.phase` | ||
); | ||
const url = `api/v1/workflow-events/${filter.namespace || ''}?${params.join('&')}`; | ||
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. This seems to be fixing the |
||
|
||
return requests.loadEventSource(url, true).map(data => JSON.parse(data).result as models.kubernetes.WatchEvent<Workflow>); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
@import 'node_modules/argo-ui/src/styles/config'; | ||
|
||
.workflow-drawer { | ||
height: 100%; | ||
font-size: .8125em; | ||
background-color: $argo-color-gray-1; | ||
margin-top: -8px; | ||
padding: 1.5em 15px; | ||
border-radius: 0 0 3px 3px; | ||
|
||
&__section { | ||
padding: 1em 0; | ||
box-sizing: border-box; | ||
border-top: 2px solid $argo-color-gray-3; | ||
|
||
&:first-child { | ||
padding-top: 0; | ||
} | ||
|
||
&:last-child { | ||
padding-bottom: 0; | ||
} | ||
|
||
&:only-child { | ||
padding: 0; | ||
} | ||
} | ||
|
||
&__message { | ||
|
||
&--label { | ||
margin-bottom: 1em; | ||
} | ||
|
||
&--content { | ||
font-weight: 600; | ||
} | ||
|
||
} | ||
|
||
&__labels { | ||
border-top: none; | ||
&--list { | ||
margin-top: 0.5em; | ||
} | ||
} | ||
|
||
.tag { | ||
line-height: normal; | ||
background-color: $argo-color-gray-3; | ||
border-radius: 3px; | ||
height: auto; | ||
margin: 0.5em 0; | ||
margin-right: 10px; | ||
display: flex; | ||
overflow: hidden; | ||
cursor: pointer; | ||
|
||
&:hover { | ||
.key { | ||
color: $argo-color-teal-5; | ||
} | ||
.value { | ||
color: $argo-color-gray-3; | ||
} | ||
} | ||
|
||
.key, .value { | ||
padding: 0.5em 8px; | ||
} | ||
|
||
.key { | ||
color: $argo-color-gray-6; | ||
} | ||
|
||
.value { | ||
color: white; | ||
background-color: $argo-color-teal-5; | ||
} | ||
} | ||
|
||
&__resourcesDuration { | ||
display: flex; | ||
align-items: center; | ||
|
||
$gutter: 2em; | ||
|
||
&--label { | ||
margin-left: 0.5em; | ||
} | ||
|
||
&--value { | ||
font-weight: 600; | ||
} | ||
|
||
&--container { | ||
padding-left: $gutter / 2; | ||
margin-left: $gutter / 2; | ||
border-left: 1px solid $argo-color-gray-3; | ||
} | ||
|
||
} | ||
|
||
&__conditions { | ||
display: flex; | ||
margin-top: 0.5em; | ||
|
||
.tag { | ||
cursor: default; | ||
&:hover { | ||
|
||
.key { | ||
color: $argo-color-gray-6; | ||
} | ||
|
||
.value { | ||
color: white; | ||
} | ||
|
||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import * as React from 'react'; | ||
import * as models from '../../../../models'; | ||
|
||
import {WorkflowLabels} from '../workflow-labels/workflow-labels'; | ||
|
||
require('./workflow-drawer.scss'); | ||
|
||
interface WorkflowDrawerProps { | ||
workflow: models.Workflow; | ||
onChange: (key: string) => void; | ||
} | ||
|
||
export class WorkflowDrawer extends React.Component<WorkflowDrawerProps, {}> { | ||
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 would change the ordering things are displayed here to be
|
||
public render() { | ||
const wf = this.props.workflow; | ||
return ( | ||
<div className='workflow-drawer'> | ||
<div className='workflow-drawer__section workflow-drawer__labels'> | ||
<div className='workflow-drawer__title'>LABELS</div> | ||
<div className='workflow-drawer__labels--list'> | ||
<WorkflowLabels | ||
workflow={wf} | ||
onChange={key => { | ||
this.props.onChange(key); | ||
}} | ||
/> | ||
</div> | ||
</div> | ||
{!wf.status.message ? null : ( | ||
<div className='workflow-drawer__section workflow-drawer__message'> | ||
<div className='workflow-drawer__title workflow-drawer__message--label'>MESSAGE</div> | ||
<div className='workflow-drawer__message--content'>{wf.status.message}</div> | ||
</div> | ||
)} | ||
{!wf.status.resourcesDuration ? null : ( | ||
<div className='workflow-drawer__section'> | ||
<div className='workflow-drawer__resourcesDuration'> | ||
<div className='workflow-drawer__title'> | ||
RESOURCES DURATION | ||
<a href='https://github.com/argoproj/argo/blob/master/docs/resource-duration.md' target='_blank'> | ||
<i className='fas fa-info-circle' /> | ||
</a> | ||
</div> | ||
<div className='workflow-drawer__resourcesDuration--container'> | ||
<div> | ||
<span className='workflow-drawer__resourcesDuration--value'>{wf.status.resourcesDuration.cpu} sec</span> | ||
<span className='workflow-drawer__resourcesDuration--label'>(*1 CPU)</span> | ||
</div> | ||
<div> | ||
<span className='workflow-drawer__resourcesDuration--value'>{wf.status.resourcesDuration.memory} sec</span> | ||
<span className='workflow-drawer__resourcesDuration--label'>(*100Mi Memory)</span> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
)} | ||
{!wf.status.conditions ? null : ( | ||
<div className='workflow-drawer__section'> | ||
<div className='workflow-drawer__title'>CONDITIONS</div> | ||
<div className='workflow-drawer__conditions'> | ||
{wf.status.conditions.map(condition => { | ||
return ( | ||
<div className='tag' key={`${wf.metadata.namespace}-${wf.metadata.name}-${condition.type}-${condition.status}`}> | ||
<div className='key'>{condition.type}</div> | ||
<div className='value'>{condition.status}</div> | ||
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. With So I'm not sure the 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. Ah I see. With context, I agree - when I first saw that example, I thought that the SpecWarning portion was not itself a condition, but a constant warning displayed for every workflow. |
||
</div> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,20 +6,25 @@ import {uiUrl} from '../../../shared/base'; | |
import {PhaseIcon} from '../../../shared/components/phase-icon'; | ||
import {Timestamp} from '../../../shared/components/timestamp'; | ||
import {formatDuration, wfDuration} from '../../../shared/duration'; | ||
import {WorkflowLabels} from '../workflow-labels/workflow-labels'; | ||
import {services} from '../../../shared/services'; | ||
import {WorkflowDrawer} from '../workflow-drawer/workflow-drawer'; | ||
|
||
interface WorkflowsRowProps { | ||
workflow: models.Workflow; | ||
onChange: (key: string) => void; | ||
} | ||
export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideLabels: boolean}> { | ||
|
||
export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideDrawer: boolean; workflow: models.Workflow}> { | ||
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. Can we make interface WorkflowRowState {
...
} |
||
constructor(props: WorkflowsRowProps) { | ||
super(props); | ||
this.state = {hideLabels: true}; | ||
this.state = { | ||
workflow: this.props.workflow, | ||
hideDrawer: true | ||
}; | ||
} | ||
|
||
public render() { | ||
const wf = this.props.workflow; | ||
const wf = this.state.workflow; | ||
return ( | ||
<div className='workflows-list__row-container'> | ||
<Link className='row argo-table-list__row' to={uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)}> | ||
|
@@ -42,10 +47,11 @@ export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideLabels | |
<div | ||
onClick={e => { | ||
e.preventDefault(); | ||
this.setState({hideLabels: !this.state.hideLabels}); | ||
this.fetchWorkflow(); | ||
this.setState({hideDrawer: !this.state.hideDrawer}); | ||
}} | ||
className={`workflows-row__action workflows-row__action--${this.state.hideLabels ? 'show' : 'hide'}`}> | ||
{this.state.hideLabels ? ( | ||
className={`workflows-row__action workflows-row__action--${this.state.hideDrawer ? 'show' : 'hide'}`}> | ||
{this.state.hideDrawer ? ( | ||
<span> | ||
SHOW <i className='fas fa-caret-down' />{' '} | ||
</span> | ||
|
@@ -58,19 +64,23 @@ export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideLabels | |
</div> | ||
</div> | ||
</Link> | ||
{this.state.hideLabels ? ( | ||
{this.state.hideDrawer ? ( | ||
<span /> | ||
) : ( | ||
<div> | ||
<WorkflowLabels | ||
workflow={wf} | ||
onChange={key => { | ||
this.props.onChange(key); | ||
}} | ||
/> | ||
</div> | ||
<WorkflowDrawer | ||
workflow={wf} | ||
onChange={key => { | ||
this.props.onChange(key); | ||
}} | ||
/> | ||
)} | ||
</div> | ||
); | ||
} | ||
|
||
private fetchWorkflow(): void { | ||
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. Nice. I would call this |
||
services.workflows.get(this.props.workflow.metadata.namespace, this.props.workflow.metadata.name).then(wf => { | ||
this.setState({workflow: wf}); | ||
}); | ||
} | ||
} |
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.
Likewise here. Shouldn't this be done in #3165 instead?
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.
This was due to a gap in my understanding of git - my commits from the #3165 branch were added to this branch. I was trying to debug this enhancement with the changes I made in #3165 without considering that accordingly those changes would be added to this branch.
To resolve this, should I simply delete the lines in question and recommit?
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.
No worries. Yes, I would simply delete these lines and make sure that they are reverted exactly to what they were before by making sure they didn't change with
git diff master