Skip to content

Commit

Permalink
feat(pipelines): Add ability and styling for selected task edges
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-phillips-18 committed May 8, 2024
1 parent 8c5ae7a commit 08512a1
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {
Edge,
EdgeTerminalType,
GraphElement,
TaskEdge
TaskEdge,
WithSelectionProps
} from '@patternfly/react-topology';

interface DemoTaskEdgeProps {
interface DemoTaskEdgeProps extends WithSelectionProps {
element: GraphElement;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
useVisualizationController,
addSpacerNodes,
pipelineElementFactory,
isEdge,
Edge,
} from '@patternfly/react-topology';
import pipelineGroupsComponentFactory from './pipelineGroupsComponentFactory';
import {
Expand All @@ -37,6 +39,25 @@ const TopologyPipelineGroups: React.FC<{ nodes: PipelineNodeModel[] }> = observe
const [selectedIds, setSelectedIds] = React.useState<string[]>();

useEventListener<SelectionEventListener>(SELECTION_EVENT, ids => {
if (ids?.[0]) {
const element = controller?.getElementById(ids[0]);
if (element && isEdge(element)) {
const edge = element as Edge;
const selectedEdges = [edge.getId()];
const source = edge.getSource();
const target = edge.getTarget();
if (source.getType() === DEFAULT_SPACER_NODE_TYPE) {
const sourceEdges = source.getTargetEdges();
selectedEdges.push(...sourceEdges.map((e) => e.getId()));
}
if (target.getType() === DEFAULT_SPACER_NODE_TYPE) {
const targetEdges = target.getSourceEdges();
selectedEdges.push(...targetEdges.map((e) => e.getId()));
}
setSelectedIds(selectedEdges);
return;
}
}
setSelectedIds(ids);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const pipelineGroupsComponentFactory: ComponentFactory = (
type: string
): React.ComponentType<{ element: GraphElement }> | undefined => {
if (kind === ModelKind.graph) {
return withPanZoom()(GraphComponent);
return withPanZoom()(withSelection()(GraphComponent));
}
switch (type) {
case 'Execution':
Expand All @@ -32,7 +32,7 @@ const pipelineGroupsComponentFactory: ComponentFactory = (
return SpacerNode;
case 'edge':
// draw arrow terminal when isDependency is set on data
return DemoTaskEdge;
return withSelection()(DemoTaskEdge);
default:
return undefined;
}
Expand Down
34 changes: 25 additions & 9 deletions packages/module/src/css/topology-components.css
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@
--edge--stroke: var(--pf-topology__edge--Stroke);
--edge--fill: var(--edge--stroke);
--edge--opacity: 1;
--edge--cursor: pointer;
--edge--cursor: default;
--edge--hover--stroke: var(--pf-topology__edge--HoverStroke);
--edge--hover--fill: var(--edge--hover--stroke);
--edge--active--stroke: var(--pf-topology__edge--ActiveStroke);
Expand All @@ -635,13 +635,15 @@

cursor: var(--edge--cursor);
stroke: var(--edge--stroke);
fill: var(--edge--fill);
fill: none;
opacity: var(--edge--opacity);
}

.pf-topology__edge.pf-m-selectable {
--edge--cursor: pointer;
}
.pf-topology__edge.pf-m-info {
--edge--stroke: var(--pf-topology__edge--m-info--EdgeStroke);
--edge--fill: var(--pf-v5-global--primary-color--light-100);
}

.pf-topology__edge.pf-m-success {
Expand All @@ -662,6 +664,10 @@
stroke-width: 10px;
stroke: transparent;
fill: none;
cursor: var(--edge--cursor);
}
.pf-topology__edge__background.pf-m-selectable {
cursor: pointer;
}
.pf-topology__edge.pf-m-selected .pf-topology__edge__background {
stroke: var(--pf-topology__edge--m-selected--background--Stroke);
Expand All @@ -673,9 +679,10 @@
.pf-topology__edge__link {
stroke-width: var(--edge--stroke-width);
stroke-dasharray: var(--edge--stroke-dasharray);
fill-opacity: 0;
animation: pf-topology__edge__dash 0s linear infinite forwards;
}
--edge--cursor: pointer;
fill: none;
}

.pf-topology__edge__link.pf-m-dotted {
stroke-dasharray: 2;
Expand Down Expand Up @@ -706,31 +713,39 @@

.pf-topology__edge.pf-m-selected .pf-topology__edge__link,
.pf-topology__edge.pf-m-selected .pf-topology-connector-arrow {
fill: var(--edge--active--fill);
stroke: var(--edge--active--stroke);
stroke-width: var(--edge--active--stroke-width);
}
.pf-topology__edge.pf-m-selected .pf-topology-connector-arrow {
fill: var(--edge--active--fill);
}

.pf-topology__edge.pf-m-selected.pf-m-hover .pf-topology__edge__link,
.pf-topology__edge.pf-m-selected.pf-m-hover .pf-topology-connector-arrow {
fill: var(--edge--active--fill);
stroke: var(--edge--active--stroke);
}
.pf-topology__edge.pf-m-selected.pf-m-hover .pf-topology-connector-arrow {
fill: var(--edge--active--fill);
}

.pf-topology__edge.pf-m-dragging {
pointer-events: none;
}
.pf-topology__edge.pf-m-hover .pf-topology__edge__link,
.pf-topology__edge.pf-m-hover .pf-topology-connector-arrow {
fill: var(--edge--hover--fill);
stroke: var(--edge--hover--stroke);
}
.pf-topology__edge.pf-m-hover .pf-topology-connector-arrow {
fill: var(--edge--hover--fill);
}

.pf-topology__edge.pf-m-dragging .pf-topology__edge__link,
.pf-topology__edge.pf-m-dragging .pf-topology-connector-arrow {
fill: var(--edge--interactive--fill);
stroke: var(--edge--interactive--stroke);
}
.pf-topology__edge.pf-m-dragging .pf-topology-connector-arrow {
fill: var(--edge--interactive--fill);
}

.pf-topology__edge .pf-topology-connector-arrow {
cursor: var(--edge__arrow--cursor);
Expand Down Expand Up @@ -779,6 +794,7 @@
.pf-topology-connector-arrow {
stroke-width: 1;
stroke: var(--edge--stroke);
fill: var(--edge--fill)
}

.pf-topology-connector-arrow.pf-m-alt-connector-arrow {
Expand Down
30 changes: 27 additions & 3 deletions packages/module/src/pipelines/components/edges/TaskEdge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { Edge, EdgeTerminalType, GraphElement, NodeStatus, isEdge } from '../../
import { integralShapePath } from '../../utils';
import { DagreLayoutOptions, TOP_TO_BOTTOM } from '../../../layouts';
import { DefaultConnectorTerminal } from '../../../components';
import { OnSelect } from '../../../behavior';
import Layer from '../../../components/layers/Layer';
import { TOP_LAYER } from '../../../const';

interface TaskEdgeProps {
/** The graph edge element to represent */
Expand All @@ -30,6 +33,10 @@ interface TaskEdgeProps {
endTerminalStatus?: NodeStatus;
/** The size of the end terminal */
endTerminalSize?: number;
/** Flag if the element is selected. Part of WithSelectionProps */
selected?: boolean;
/** Function to call when the element should become selected (or deselected). Part of WithSelectionProps */
onSelect?: OnSelect;
}

type TaskEdgeInnerProps = Omit<TaskEdgeProps, 'element'> & { element: Edge };
Expand All @@ -46,18 +53,35 @@ const TaskEdgeInner: React.FunctionComponent<TaskEdgeInnerProps> = observer(
endTerminalStatus,
endTerminalSize = 14,
className,
nodeSeparation
nodeSeparation,
selected,
onSelect,
}) => {
const startPoint = element.getStartPoint();
const endPoint = element.getEndPoint();
const groupClassName = css(styles.topologyEdge, className);
const groupClassName = css(
styles.topologyEdge,
className,
selected && 'pf-m-selected',
onSelect && 'pf-m-selectable',
);
const startIndent: number = element.getData()?.indent || 0;
const verticalLayout = (element.getGraph().getLayoutOptions?.() as DagreLayoutOptions)?.rankdir === TOP_TO_BOTTOM;

const edgePath = integralShapePath(startPoint, endPoint, startIndent, nodeSeparation, verticalLayout);
const edgeBackground = (
<path
onClick={onSelect}
className={css(styles.topologyEdgeBackground, onSelect && 'pf-m-selectable')}
d={edgePath}
/>
);

return (
<g data-test-id="task-handler" className={groupClassName}>
{selected ? edgeBackground : <Layer id={TOP_LAYER}>{edgeBackground}</Layer>}
<path
d={integralShapePath(startPoint, endPoint, startIndent, nodeSeparation, verticalLayout)}
d={edgePath}
transform="translate(0.5,0.5)"
shapeRendering="geometricPrecision"
fillOpacity={0}
Expand Down

0 comments on commit 08512a1

Please sign in to comment.