Skip to content

Commit

Permalink
convert pipeline visualization node to SVG
Browse files Browse the repository at this point in the history
  • Loading branch information
rottencandy committed Oct 30, 2020
1 parent 8e2a3d0 commit 0c94891
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,28 @@

$border-color: var(--pf-global--BorderColor--light-100);
.odc-pipeline-vis-task {
width: 10em;
fill: white;
stroke: $border-color;
stroke-width: 1;
cursor: default;

&__content {
width: inherit;
height: 2.5em;
white-space: normal;
border: 1px solid $border-color;
border-radius: 20px;
color: black;
background-color: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
display: flex;
flex-direction: row;
align-items: center;
&:hover {
box-shadow: 0 0 16px rgba(0, 0, 0, 0.12);
}

&.is-selected {
border: 2px solid $interactive-stroke-color;
}
}
&:not(:first-child) {
margin-top: 1.5em;
&.is-selected {
stroke: $interactive-stroke-color;
stroke-width: 2;
}

&__stepcount {
margin: 0 4px;
white-space: nowrap;
&.is-linked {
cursor: pointer;
}
}

&__status {
margin: 0 3px 0 7px;
width: 1.5em;
height: 1.5em;
flex-grow: 0;
flex-shrink: 0;
order: -1;
}
.odc-pipeline-vis-task-text {
cursor: default;
dominant-baseline: middle;

&__title-wrapper {
flex: 0 0 75px;
display: flex;
flex-direction: column;
min-width: 0;
&.is-text-center {
text-align: center;
margin: 0 auto;
flex: 0 0 100px;
}
&.is-text-center {
text-anchor: middle;
}
&.is-linked {
cursor: pointer;
}

&__title {
flex: 0 0 auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@ import * as _ from 'lodash';
import * as cx from 'classnames';
import { Link } from 'react-router-dom';
import { Tooltip } from '@patternfly/react-core';
import { createSvgIdUrl, useHover } from '@patternfly/react-topology';
import { K8sResourceKind, referenceForModel } from '@console/internal/module/k8s';
import { Firehose, resourcePathFromModel } from '@console/internal/components/utils';
import { runStatus, PipelineTaskSpec, PipelineTaskRef } from '../../../../utils/pipeline-augment';
import {
Firehose,
resourcePathFromModel,
truncateMiddle,
} from '@console/internal/components/utils';
import {
runStatus,
PipelineTaskSpec,
PipelineTaskRef,
getRunStatusColor,
} from '../../../../utils/pipeline-augment';
import { PipelineRunModel, TaskModel, ClusterTaskModel } from '../../../../models';
import SvgDropShadowFilter from '../../../svg/SvgDropShadowFilter';
import { ColoredStatusIcon } from './StatusIcon';
import { PipelineVisualizationStepList } from './PipelineVisualizationStepList';
import TaskComponentTaskStatus from './TaskComponentTaskStatus';
import { createStepStatus, StepStatus, TaskStatus } from './pipeline-step-utils';

import './PipelineVisualizationTask.scss';
Expand All @@ -26,6 +36,8 @@ interface TaskProps {
isPipelineRun: boolean;
disableTooltip?: boolean;
selected?: boolean;
width: number;
height: number;
}

interface PipelineVisualizationTaskProp {
Expand All @@ -41,15 +53,21 @@ interface PipelineVisualizationTaskProp {
pipelineRunStatus?: string;
disableTooltip?: boolean;
selected?: boolean;
width: number;
height: number;
}

const FILTER_ID = 'SvgTaskDropShadowFilterId';

export const PipelineVisualizationTask: React.FC<PipelineVisualizationTaskProp> = ({
pipelineRunName,
task,
namespace,
pipelineRunStatus,
disableTooltip,
selected,
width,
height,
}) => {
const taskStatus = task.status || {
duration: '',
Expand All @@ -70,6 +88,8 @@ export const PipelineVisualizationTask: React.FC<PipelineVisualizationTaskProp>
isPipelineRun={!!pipelineRunStatus}
disableTooltip={disableTooltip}
selected={selected}
width={width}
height={height}
/>
);

Expand Down Expand Up @@ -107,6 +127,8 @@ const TaskComponent: React.FC<TaskProps> = ({
isPipelineRun,
disableTooltip,
selected,
width,
height,
}) => {
const stepList = _.get(task, ['data', 'spec', 'steps'], []);
const stepStatusList: StepStatus[] = stepList.map((step) => createStepStatus(step, status));
Expand All @@ -121,22 +143,44 @@ const TaskComponent: React.FC<TaskProps> = ({
status?.reason !== runStatus.Cancelled &&
!!path;

const [hover, hoverRef] = useHover();
const truncatedVisualName = React.useMemo(
() => truncateMiddle(visualName, { length: showStatusState ? 11 : 14, truncateEnd: true }),
[visualName, showStatusState],
);

let taskPill = (
<div className={cx('odc-pipeline-vis-task__content', { 'is-selected': selected })}>
<div
className={cx('odc-pipeline-vis-task__title-wrapper', {
<g ref={hoverRef}>
<SvgDropShadowFilter dy={1} id={FILTER_ID} />
<rect
filter={hover ? createSvgIdUrl(FILTER_ID) : ''}
width={width}
height={height}
rx={15}
className={cx('odc-pipeline-vis-task', {
'is-selected': selected,
'is-linked': enableLogLink,
})}
/>
{isPipelineRun && showStatusState && (
<foreignObject height={18} width={18} x={9} y={6}>
<ColoredStatusIcon status={status.reason} height={18} width={18} />
</foreignObject>
)}
<text
x={showStatusState ? 30 : width / 2}
y={height / 2 + 1}
className={cx('odc-pipeline-vis-task-text', {
'is-text-center': !isPipelineRun,
'is-linked': enableLogLink,
})}
>
<div className="odc-pipeline-vis-task__title">{visualName}</div>
{showStatusState && <TaskComponentTaskStatus steps={stepStatusList} />}
</div>
{isPipelineRun && (
<div className="odc-pipeline-vis-task__status">
{showStatusState && <ColoredStatusIcon status={status.reason} height={18} width={18} />}
</div>
{truncatedVisualName}
</text>
{showStatusState && (
<SvgTaskStatus steps={stepStatusList} x={30} y={23} width={width / 2 + 15} />
)}
</div>
</g>
);
if (!disableTooltip) {
taskPill = (
Expand All @@ -156,15 +200,36 @@ const TaskComponent: React.FC<TaskProps> = ({
);
}

const visTask = (
<>
<div className="odc-pipeline-vis-task__connector" />
{taskPill}
</>
);
return enableLogLink ? <Link to={path}>{taskPill}</Link> : taskPill;
};

interface SvgTaskStatusProps {
steps: StepStatus[];
x: number;
y: number;
width: number;
}

const SvgTaskStatus: React.FC<SvgTaskStatusProps> = ({ steps, x, y, width }) => {
if (steps.length === 0) {
return null;
}
const stepWidth = width / steps.length;
const gap = 2;
return (
<div className={cx('odc-pipeline-vis-task', { 'is-linked': enableLogLink })}>
{enableLogLink ? <Link to={path}>{visTask}</Link> : visTask}
</div>
<g>
{steps.map((step, index) => {
return (
<rect
key={step.name}
x={x + stepWidth * index}
y={y}
width={stepWidth - gap}
height={2}
fill={getRunStatusColor(step.runStatus).pftoken.value}
/>
);
})}
</g>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@
overflow: hidden;
box-shadow: var(--pf-c-dropdown__menu--BoxShadow);
}
&__label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&__trigger-background {
background: var(--pf-global--BackgroundColor--light-100);
fill: var(--pf-global--BackgroundColor--light-100);
&.is-disabled {
fill: var(--pf-global--disabled-color--300);
}
}
&__trigger-underline {
fill: var(--pf-global--Color--100);
&__hover {
fill: var(--pf-global--link--Color);
}
}
&__trigger {
position: fixed;
padding: var(--pf-global--spacer--xs) var(--pf-global--spacer--md);
width: 100%;
font-size: var(--pf-global--FontSize--md);
text-anchor: middle;
dominant-baseline: middle;
cursor: pointer;
}
&__trigger-disabled {
fill: var(--pf-global--disabled-color--100);
}
&__list-items {
max-height: 350px;
Expand All @@ -27,4 +35,3 @@
margin: 0;
}
}

0 comments on commit 0c94891

Please sign in to comment.