Skip to content
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

Merged
merged 35 commits into from Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8b20eda
Add labels column to workflows list
rbreeze Jun 1, 2020
736cd00
feat(ui): add ability to filter workflows by label by clicking on a l…
rbreeze Jun 1, 2020
6af5d5d
Refactor labels column into its own component. Add show / hide button…
rbreeze Jun 1, 2020
0b4cf34
fix(ui): linting issue with FontAwesome tags not being self closing
rbreeze Jun 1, 2020
5001871
Fix no new line at EOF issue
rbreeze Jun 1, 2020
e88cd10
Linted
rbreeze Jun 2, 2020
b61ca97
Remove text-decoration from SHOW / HIDE buttons and remove async / aw…
rbreeze Jun 2, 2020
58e61f4
Merge branch 'master' of github.com:argoproj/argo into label-filtering
rbreeze Jun 2, 2020
9a7b5dc
Resize workflows list columns for better visibility.
rbreeze Jun 2, 2020
a7a7c02
Change variable name of workflow to match convention
rbreeze Jun 2, 2020
376d96f
Linted
rbreeze Jun 2, 2020
7186409
Refactor workflows list by separating out rows into an independent co…
rbreeze Jun 2, 2020
27db356
Merge branch 'master' of github.com:argoproj/argo into label-filtering
rbreeze Jun 2, 2020
85e115a
Style labels to emphasize which row they belong to
rbreeze Jun 2, 2020
c0b630f
Fix colors of label drawer for better contrast
rbreeze Jun 2, 2020
1a5031f
feat(ui): Add more details to workflow labels drawer: message, resour…
rbreeze Jun 3, 2020
d85d192
Linted
rbreeze Jun 3, 2020
45eab5d
Resolve merge conflicts
rbreeze Jun 3, 2020
b24ee90
Fix format of labels
rbreeze Jun 3, 2020
251f89f
Linted
rbreeze Jun 3, 2020
7ec9961
Add lazy loading for workflows list drawer
rbreeze Jun 3, 2020
59c21b0
Merge branch 'master' of github.com:argoproj/argo into info-drawer
rbreeze Jun 3, 2020
ae73519
fix(server): Allow for field selection for workflow-event endpoint. F…
rbreeze Jun 3, 2020
084f923
Fix lazy loading referencing prop instead of state
rbreeze Jun 3, 2020
1017094
Codegen
simster7 Jun 4, 2020
161c3cb
Merge branch 'master' into HEAD
simster7 Jun 4, 2020
42155c3
Revert go.mod and go.sum changes
simster7 Jun 4, 2020
f209bdb
Swagger
simster7 Jun 4, 2020
e572625
Reorder display of info in drawer, small refactor of Workflows Row co…
rbreeze Jun 4, 2020
6c686d8
Merge branch 'master' of github.com:argoproj/argo into info-drawer
rbreeze Jun 4, 2020
7d9cbe0
Remove changes from #3165
rbreeze Jun 4, 2020
0231220
Reformat drawer to better display workflow conditions
rbreeze Jun 4, 2020
2720473
Revert generated file to older version
rbreeze Jun 4, 2020
dce8c0d
Change how conditions are displayed in workflow drawer
rbreeze Jun 4, 2020
57fb2d3
Lint
simster7 Jun 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 11 additions & 4 deletions ui/src/app/shared/conditions-panel.tsx
Expand Up @@ -26,13 +26,18 @@ export function hasWarningConditionBadge(conditions: Condition[]): boolean {
}

function getConditionIcon(condition: ConditionType): JSX.Element {
let icon;
if (WarningConditions.includes(condition as ConditionType)) {
return <span className={'fa fa-exclamation-triangle'} style={{color: '#d7b700'}} />;
icon = <span className={'fa fa-exclamation-triangle'} style={{color: '#d7b700'}} />;
}
if (ErrorConditions.includes(condition as ConditionType)) {
return <span className={'fa fa-exclamation-circle'} style={{color: '#d70022'}} />;
icon = <span className={'fa fa-exclamation-circle'} style={{color: '#d70022'}} />;
}
if (!icon) {
return <span />;
} else {
return <>{icon}&nbsp;</>;
}
return <span />;
}

export class ConditionsPanel extends React.Component<Props> {
Expand All @@ -43,7 +48,9 @@ export class ConditionsPanel extends React.Component<Props> {
Object.entries(this.props.conditions).map(([_, condition]) => {
return (
<div key={condition.type} style={{lineHeight: '120%', marginTop: '16px'}}>
{getConditionIcon(condition.type)} {condition.type + ': ' + (condition.message || condition.status)}
{getConditionIcon(condition.type)}
<span className='condition-panel__type'>{condition.type}</span>
{': ' + (condition.message || condition.status)}
</div>
);
})}
Expand Down
119 changes: 119 additions & 0 deletions ui/src/app/workflows/components/workflow-drawer/workflow-drawer.scss
@@ -0,0 +1,119 @@
@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;
border-top: none;
}

&:last-child {
padding-bottom: 0;
}

&:only-child {
padding: 0;
}
}

&__message {

&--label {
margin-bottom: 1em;
}

&--content {
font-weight: 600;
}

}

&__labels {
&--list {
margin-top: 0.5em;
}
}

&__message {
border-top: none;
}

.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 {
margin-top: 0.5em;

.condition-panel__type {
font-weight: 600;
}

.type {
font-weight: 600;
}
}
}
@@ -0,0 +1,69 @@
import * as React from 'react';
import * as models from '../../../../models';

import {ConditionsPanel} from '../../../shared/conditions-panel';
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, {}> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change the ordering things are displayed here to be

  1. Message
  2. Conditions
  3. Resource Durations
  4. Labels

public render() {
const wf = this.props.workflow;
return (
<div className='workflow-drawer'>
{!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.conditions ? null : (
<div className='workflow-drawer__section'>
<div className='workflow-drawer__title'>CONDITIONS</div>
<div className='workflow-drawer__conditions'>
<ConditionsPanel conditions={wf.status.conditions} />
</div>
</div>
)}
{!wf.status.resourcesDuration ? null : (
<div className='workflow-drawer__section'>
<div className='workflow-drawer__resourcesDuration'>
<div className='workflow-drawer__title'>
RESOURCES DURATION&nbsp;
<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>
)}
<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>
</div>
);
}
}
Expand Up @@ -5,12 +5,9 @@
flex-wrap: wrap;
align-items: center;
height: 100%;
padding: 0.25em 0;
$gutter: 0.5em;
font-size: .8125em;
background-color: $argo-color-gray-1;
margin-top: -8px;
padding: 0.5em 15px;
border-radius: 0 0 3px 3px;

.tag {
Expand Down
Expand Up @@ -265,7 +265,7 @@ export class WorkflowsList extends BasePage<RouteComponentProps<any>, State> {
<div className='columns small-2'>STARTED</div>
<div className='columns small-2'>FINISHED</div>
<div className='columns small-1'>DURATION</div>
<div className='columns small-1'>LABELS</div>
<div className='columns small-1'>DETAILS</div>
</div>
{this.state.workflows.map(wf => {
return (
Expand Down
47 changes: 31 additions & 16 deletions ui/src/app/workflows/components/workflows-row/workflows-row.tsx
Expand Up @@ -6,20 +6,30 @@ 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}> {

interface WorkflowRowState {
hideDrawer: boolean;
workflow: models.Workflow;
}

export class WorkflowsRow extends React.Component<WorkflowsRowProps, 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}`)}>
Expand All @@ -42,10 +52,11 @@ export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideLabels
<div
onClick={e => {
e.preventDefault();
this.setState({hideLabels: !this.state.hideLabels});
this.fetchFullWorkflow();
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>
Expand All @@ -58,19 +69,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 fetchFullWorkflow(): void {
services.workflows.get(this.props.workflow.metadata.namespace, this.props.workflow.metadata.name).then(wf => {
this.setState({workflow: wf});
});
}
}