import classNames from 'classnames'; import { get } from 'lodash'; import React from 'react'; import type { IExecutionStageSummary } from '../../../domain'; import type { IPipelineGraphNode } from './pipelineGraph.service'; import { LabelComponent, Markdown } from '../../../presentation'; import { Popover } from '../../../presentation/Popover'; import { GroupExecutionPopover } from '../stages/group/GroupExecutionPopover'; import { logger } from '../../../utils'; export interface IPipelineGraphNodeProps { isExecution: boolean; labelOffsetX: number; labelOffsetY: number; maxLabelWidth: number; nodeClicked: (node: IPipelineGraphNode | IExecutionStageSummary, subIndex?: number) => void; highlight: (node: IPipelineGraphNode, highlight: boolean) => void; nodeRadius: number; node: IPipelineGraphNode; } export class PipelineGraphNode extends React.Component { private highlight = (): void => { this.props.highlight(this.props.node, true); }; private removeHighlight = (): void => { this.props.highlight(this.props.node, false); }; private handleClick = (): void => { logger.log({ category: `Pipeline Graph (${this.props.isExecution ? 'execution' : 'config'})`, action: `Node clicked`, }); this.props.nodeClicked(this.props.node); }; private subStageClicked = (groupStage: IExecutionStageSummary, stage: IExecutionStageSummary): void => { logger.log({ category: `Pipeline Graph (${this.props.isExecution ? 'execution' : 'config'})`, action: `Grouped stage clicked`, }); this.props.nodeClicked(groupStage, stage.index); }; public render() { const { labelOffsetX, labelOffsetY, maxLabelWidth, nodeRadius, node } = this.props; const isGroup = node.stage && node.stage.type === 'group'; let stageType = get(node, ['masterStage', 'type'], undefined); stageType = stageType || get(node, ['stage', 'activeStageType'], ''); const circleClassName = classNames( `stage-type-${stageType.toLowerCase()}`, 'execution-marker', `execution-marker-${(node.status || '').toLowerCase()}`, 'graph-node', { active: node.isActive, clickable: !isGroup, }, ); const warningsPopover = (

The following errors may affect the ability to run this pipeline:

); let GraphNode = ( {isGroup && ( )} {!isGroup && ( )} {(node.root || node.leaf) && !node.executionStage && !isGroup && ( )} ); // Only for pipeline if (node.hasWarnings) { GraphNode = ( {GraphNode} ); } // Render the label differently if there is a custom label component let GraphLabel = node.labelComponent ? (
) : (
{node.name}
); // Wrap all the label html in a foreignObject to make SVG happy GraphLabel = ( {GraphLabel} ); let NodeContents = ( <> {GraphNode} {GraphLabel} ); if (node.stage && node.stage.type === 'group') { NodeContents = ( {NodeContents} ); } return ( {NodeContents} ); } }