Skip to content

Commit

Permalink
feat(ui): Add a YAML panel to view the workflow manifest. (#2700)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexec authored Apr 15, 2020
1 parent 65d413e commit b4fd447
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
WorkflowYamlViewer
} from '../../../workflows/components';
import {WorkflowDagRenderOptionsPanel} from '../../../workflows/components/workflow-dag/workflow-dag-render-options-panel';
import {WorkflowYamlPanel} from '../../../workflows/components/workflow-details/workflow-yaml-panel';

require('../../../workflows/components/workflow-details/workflow-details.scss');

Expand Down Expand Up @@ -161,6 +162,7 @@ export class ArchivedWorkflowDetails extends BasePage<RouteComponentProps<any>,
)}
<h6>Artifacts</h6>
<WorkflowArtifacts workflow={this.state.workflow} archived={true} />
<WorkflowYamlPanel workflow={this.state.workflow} />
</div>
</div>
) : (
Expand Down
13 changes: 7 additions & 6 deletions ui/src/app/workflows/components/workflow-dag/workflow-dag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ export class WorkflowDag extends React.Component<WorkflowDagProps> {
const node = graph.node(id) as models.NodeStatus & dagre.Node;
const small = this.filterNode(node);
return (
<>
<div key={`node/${id}`}>
<div
key={id}
key='label'
title={node.label}
className={classNames(
'workflow-dag__node',
Expand All @@ -135,6 +135,7 @@ export class WorkflowDag extends React.Component<WorkflowDagProps> {
/>
{!small && (
<div
key='title'
className='workflow-dag__node-title'
style={{
position: 'absolute',
Expand All @@ -148,20 +149,20 @@ export class WorkflowDag extends React.Component<WorkflowDagProps> {
{node.label}
</div>
)}
</>
</div>
);
})}
{edges.map(edge => (
<div key={`${edge.from}-${edge.to}`} className='workflow-dag__edge'>
{edge.lines.map((line, i) => {
<div key={`edge/${edge.from},${edge.to}`} className='workflow-dag__edge'>
{edge.lines.map(line => {
const distance = Math.sqrt(Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2));
const xMid = (line.x1 + line.x2) / 2;
const yMid = (line.y1 + line.y2) / 2;
const angle = (Math.atan2(line.y1 - line.y2, line.x1 - line.x2) * 180) / Math.PI;
return (
<div
className={classNames('workflow-dag__line', {'workflow-dag__line--no-arrow': line.noArrow})}
key={i}
key={`line/${line.x1},line-${line.x2}->${line.y1},${line.y2}`}
style={{
width: distance,
left: xMid - distance / 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,37 @@

.workflow-details {

&, & > .row {
height: calc(100vh - 2 * #{$top-bar-height});
}
overflow-y: scroll;

&__content {
padding: 1em;
}
&, & > .row {
height: calc(100vh - 2 * #{$top-bar-height});
}

&__content {
padding: 1em;
}

&__topbar-buttons {
display: inline-block;
white-space: nowrap;

a {
vertical-align: middle;
text-align: center;
line-height: 1em;
padding: 0.5em;
font-size: 1.1em;
border: 1px solid transparent;
display: inline-block;
width: 2em;
margin-right: 0.5em;
color: $argo-color-gray-8;

&__topbar-buttons {
display: inline-block;
white-space: nowrap;

a {
vertical-align: middle;
text-align: center;
line-height: 1em;
padding: 0.5em;
font-size: 1.1em;
border: 1px solid transparent;
display: inline-block;
width: 2em;
margin-right: 0.5em;
color: $argo-color-gray-8;

&.active {
background-color: $argo-color-gray-3;
border: 1px solid $argo-color-gray-4;
border-radius: 5px;
cursor: default;
&.active {
background-color: $argo-color-gray-3;
border: 1px solid $argo-color-gray-4;
border-radius: 5px;
cursor: default;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import * as React from 'react';
import {RouteComponentProps} from 'react-router';
import {Subscription} from 'rxjs';

import * as models from '../../../../models';
import {Link, NodePhase} from '../../../../models';
import {Link, NodePhase, Workflow} from '../../../../models';
import {uiUrl} from '../../../shared/base';
import {services} from '../../../shared/services';

Expand All @@ -16,6 +15,7 @@ import {Consumer, ContextApis} from '../../../shared/context';
import {Utils} from '../../../shared/utils';
import {WorkflowDagRenderOptionsPanel} from '../workflow-dag/workflow-dag-render-options-panel';
import {WorkflowParametersPanel} from '../workflow-parameters-panel';
import {WorkflowYamlPanel} from './workflow-yaml-panel';

require('./workflow-details.scss');

Expand Down Expand Up @@ -44,7 +44,7 @@ export const defaultNodesToDisplay = [

interface WorkflowDetailsState {
workflowDagRenderOptions: WorkflowDagRenderOptions;
workflow: models.Workflow;
workflow: Workflow;
links: Link[];
}

Expand Down Expand Up @@ -293,7 +293,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.delete(this.props.match.params.name, this.props.match.params.namespace)
.then(() => ctx.navigation.goto(uiUrl(`workflows/`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to delete workflow',
type: NotificationType.Error
Expand All @@ -308,7 +308,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.stop(this.props.match.params.name, this.props.match.params.namespace)
.then(wf => ctx.navigation.goto(uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to terminate workflow',
type: NotificationType.Error
Expand All @@ -323,7 +323,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.terminate(this.props.match.params.name, this.props.match.params.namespace)
.then(wf => ctx.navigation.goto(uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to terminate workflow',
type: NotificationType.Error
Expand All @@ -335,7 +335,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.resume(this.props.match.params.name, this.props.match.params.namespace)
.then(wf => ctx.navigation.goto(uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to resume workflow',
type: NotificationType.Error
Expand All @@ -347,7 +347,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.suspend(this.props.match.params.name, this.props.match.params.namespace)
.then(wf => ctx.navigation.goto(uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to suspend workflow',
type: NotificationType.Error
Expand All @@ -362,7 +362,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.resubmit(this.props.match.params.name, this.props.match.params.namespace)
.then(wf => ctx.navigation.goto(uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to resubmit workflow',
type: NotificationType.Error
Expand All @@ -374,7 +374,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
services.workflows
.retry(this.props.match.params.name, this.props.match.params.namespace)
.then(wf => ctx.navigation.goto(uiUrl(`workflows/${wf.metadata.namespace}/${wf.metadata.name}`)))
.catch(error => {
.catch(() => {
this.appContext.apis.notifications.show({
content: 'Unable to retry workflow',
type: NotificationType.Error
Expand Down Expand Up @@ -430,6 +430,7 @@ export class WorkflowDetails extends React.Component<RouteComponentProps<any>, W
)}
<h6>Artifacts</h6>
<WorkflowArtifacts workflow={this.state.workflow} archived={false} />
<WorkflowYamlPanel workflow={this.state.workflow} />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as jsYaml from 'js-yaml';
import * as React from 'react';
import {Workflow} from '../../../../models';
import {YamlViewer} from '../../../shared/components/yaml/yaml-viewer';

export const WorkflowYamlPanel = (props: {workflow: Workflow}) => (
<div className='white-box'>
<div className='white-box__details'>
<YamlViewer value={jsYaml.dump(props.workflow)} />
</div>
</div>
);

0 comments on commit b4fd447

Please sign in to comment.