Skip to content

Commit

Permalink
Add correct location, scaling, and anchors for expanded task group's …
Browse files Browse the repository at this point in the history
…pill labels.
  • Loading branch information
jeff-phillips-18 committed Jun 17, 2024
1 parent 3d9a3e2 commit 1ca13b5
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import {
EdgeCreationTypes,
useHover,
ScaleDetailsLevel,
RunStatus
// NodeLabel
RunStatus,
TaskGroupPillLabel
} from '@patternfly/react-topology';
import { DEFAULT_TASK_HEIGHT, GROUP_TASK_WIDTH } from './createDemoPipelineGroupsNodes';
import TaskGroupPillLabel from '@patternfly/react-topology/dist/esm/pipelines/components/groups/TaskGroupPillLabel';

type DemoTaskGroupProps = {
element: GraphElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
GraphElement,
LabelPosition,
observer,
ScaleDetailsLevel,
WithContextMenuProps,
WithDragNodeProps,
WithSelectionProps
Expand All @@ -18,14 +17,14 @@ type DemoPipelinesGroupProps = {

const DemoPipelinesGroup: React.FunctionComponent<DemoPipelinesGroupProps> = ({ element }) => {
const data = element.getData();
const detailsLevel = element.getGraph().getDetailsLevel();

return (
<DefaultTaskGroup
element={element}
collapsible={false}
showLabel={detailsLevel === ScaleDetailsLevel.high}
labelPosition={LabelPosition.top}
showLabelOnHover
hideDetailsAtMedium
badge={data?.badge}
/>
);
Expand Down
22 changes: 0 additions & 22 deletions packages/module/src/components/nodes/labels/NodeLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export type NodeLabelProps = {
y?: number;
position?: LabelPosition;
centerLabelOnEdge?: boolean;
// isLabelPillShape?: boolean;
boxRef?: React.Ref<SVGRectElement>;
cornerRadius?: number;
status?: NodeStatus;
Expand Down Expand Up @@ -60,7 +59,6 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
y = 0,
position = LabelPosition.bottom,
centerLabelOnEdge,
// isLabelPillShape,
secondaryLabel,
status,
badge,
Expand Down Expand Up @@ -204,25 +202,6 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
filterId = NODE_SHADOW_FILTER_ID_HOVER;
}

// if (isLabelPillShape) {
// return (
// <g className={className} ref={refs} transform={`translate(${startX}, ${startY})`}>
// <NodeShadows />
// <rect
// ref={boxRef}
// className={css(styles.topologyNodeLabelBackground)}
// key={`rect-${filterId}-${width}`} // update key to force remount on filter or size update
// filter={filterId && createSvgIdUrl(filterId)}
// x={0}
// y={0}
// width={width}
// height={backgroundHeight}
// rx={cornerRadius}
// ry={cornerRadius}
// />{' '}
// </g>
// );
// } else {
return (
<g className={className} ref={refs} transform={`translate(${startX}, ${startY})`}>
<NodeShadows />
Expand Down Expand Up @@ -338,6 +317,5 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
</g>
);
};
// };

export default NodeLabel;
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ export interface DefaultTaskGroupProps {
GroupLabelComponent?: React.FC<TaskGroupPillLabelProps>;
/** Center the label on the edge, overrides the label offset, only applicable to expanded groups */
centerLabelOnEdge?: boolean;
/** Applies task node styling to the group label */
isLabelPillShape?: boolean;
/** The Icon class to show in the label, ignored when labelIcon is specified */
labelIconClass?: string;
/** The label icon component to show in the label, takes precedence over labelIconClass */
Expand Down Expand Up @@ -131,7 +129,6 @@ type PipelinesDefaultGroupInnerProps = Omit<DefaultTaskGroupProps, 'element'> &

const DefaultTaskGroupInner: React.FunctionComponent<PipelinesDefaultGroupInnerProps> = observer(
({
className,
element,
badge,
onCollapseChange,
Expand Down Expand Up @@ -212,7 +209,6 @@ const DefaultTaskGroupInner: React.FunctionComponent<PipelinesDefaultGroupInnerP
if (element.isCollapsed()) {
return (
<DefaultTaskGroupCollapsed
className={className}
element={element}
shadowCount={collapsedShadowCount}
onCollapseChange={handleCollapse}
Expand All @@ -221,16 +217,7 @@ const DefaultTaskGroupInner: React.FunctionComponent<PipelinesDefaultGroupInnerP
/>
);
}
return (
// TODO: Support status indicators on expanded state.
<DefaultTaskGroupExpanded
isLabelPillShape
className={className}
element={element}
onCollapseChange={handleCollapse}
{...rest}
/>
);
return <DefaultTaskGroupExpanded element={element} badge={badge} onCollapseChange={handleCollapse} {...rest} />;
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import CollapseIcon from '@patternfly/react-icons/dist/esm/icons/compress-alt-ic
import NodeLabel from '../../../components/nodes/labels/NodeLabel';
import { Layer } from '../../../components/layers';
import { GROUPS_LAYER, TOP_LAYER } from '../../../const';
import { maxPadding, useCombineRefs, useHover, useSize } from '../../../utils';
import { AnchorEnd, isGraph, LabelPosition, Node, NodeStyle, ScaleDetailsLevel } from '../../../types';
import { useCombineRefs, useHover, useSize } from '../../../utils';
import { AnchorEnd, isGraph, LabelPosition, Node, ScaleDetailsLevel } from '../../../types';
import { useAnchor, useDragNode } from '../../../behavior';
import { DagreLayoutOptions, TOP_TO_BOTTOM } from '../../../layouts';
import TaskGroupSourceAnchor from '../anchors/TaskGroupSourceAnchor';
Expand All @@ -28,6 +28,7 @@ const DefaultTaskGroupExpanded: React.FunctionComponent<Omit<DefaultTaskGroupPro
showLabel = true,
showLabelOnHover,
hideDetailsAtMedium,
status,
GroupLabelComponent = NodeLabel,
truncateLength,
canDrop,
Expand All @@ -53,16 +54,13 @@ const DefaultTaskGroupExpanded: React.FunctionComponent<Omit<DefaultTaskGroupPro
const [hovered, hoverRef] = useHover(200, 500);
const [labelHover, labelHoverRef] = useHover(0);
const dragLabelRef = useDragNode()[1];
const [labelSize, labelRef] = useSize([centerLabelOnEdge]);
const taskRef = React.useRef();
const pillRef = useSize();
const refs = useCombineRefs<SVGPathElement>(hoverRef, dragNodeRef);
const isHover = hover !== undefined ? hover : hovered || labelHover;
const [labelSize, labelRef] = useSize([centerLabelOnEdge]);
const verticalLayout = (element.getGraph().getLayoutOptions?.() as DagreLayoutOptions)?.rankdir === TOP_TO_BOTTOM;
const groupLabelPosition = labelPosition ?? element.getLabelPosition() ?? LabelPosition.bottom;
let parent = element.getParent();
const detailsLevel = element.getGraph().getDetailsLevel();
const { width } = element.getBounds();

let altGroup = false;
while (!isGraph(parent)) {
Expand Down Expand Up @@ -110,41 +108,37 @@ const DefaultTaskGroupExpanded: React.FunctionComponent<Omit<DefaultTaskGroupPro
AnchorEnd.target
);

const children = element.getNodes().filter((c) => c.isVisible());

// cast to number and coerce
const padding = maxPadding(element.getStyle<NodeStyle>().padding ?? 17);

const { minX, minY, maxX, maxY } = children.reduce(
(acc, child) => {
const bounds = child.getBounds();
return {
minX: Math.min(acc.minX, bounds.x - padding),
minY: Math.min(acc.minY, bounds.y - padding),
maxX: Math.max(acc.maxX, bounds.x + bounds.width + padding),
maxY: Math.max(acc.maxY, bounds.y + bounds.height + padding)
};
},
{ minX: Infinity, minY: Infinity, maxX: 0, maxY: 0 }
);
const bounds = element.getBounds();

const [labelX, labelY] = React.useMemo(() => {
if (!showLabel || !(label || element.getLabel())) {
return [0, 0];
}
switch (groupLabelPosition) {
case LabelPosition.top:
return [minX + (maxX - minX) / 2, -minY + (centerLabelOnEdge ? 0 : labelOffset)];
return [bounds.x + bounds.width / 2, -bounds.y + (centerLabelOnEdge ? 0 : labelOffset)];
case LabelPosition.right:
return [maxX + (centerLabelOnEdge ? 0 : labelOffset), minY + (maxY - minY) / 2];
return [bounds.x + bounds.width + (centerLabelOnEdge ? 0 : labelOffset), bounds.y + bounds.height / 2];
case LabelPosition.left:
return [centerLabelOnEdge ? minX : labelOffset, minY + (maxY - minY) / 2];
return [centerLabelOnEdge ? bounds.x : labelOffset, bounds.y + bounds.height / 2];
case LabelPosition.bottom:
default:
return [minX + (maxX - minX) / 2, maxY + (centerLabelOnEdge ? 0 : labelOffset)];
return [bounds.x + bounds.width / 2, bounds.y + bounds.height + (centerLabelOnEdge ? 0 : labelOffset)];
}
}, [showLabel, label, element, groupLabelPosition, minX, maxX, minY, centerLabelOnEdge, labelOffset, maxY]);
}, [
showLabel,
label,
element,
groupLabelPosition,
bounds.x,
bounds.width,
bounds.y,
bounds.height,
centerLabelOnEdge,
labelOffset
]);

const children = element.getNodes().filter((c) => c.isVisible());
if (children.length === 0) {
return null;
}
Expand Down Expand Up @@ -175,13 +169,15 @@ const DefaultTaskGroupExpanded: React.FunctionComponent<Omit<DefaultTaskGroupPro

const groupLabel = labelShown ? (
<g ref={labelHoverRef} transform={isHover ? `scale(${labelScale})` : undefined}>
<NodeLabel
<GroupLabelComponent
element={element}
boxRef={labelRef}
className={styles.topologyGroupLabel}
x={labelX * labelPositionScale}
y={labelY * labelPositionScale}
position={labelPosition}
centerLabelOnEdge={centerLabelOnEdge}
runStatus={status}
paddingX={8}
paddingY={5}
dragRef={dragNodeRef ? dragLabelRef : undefined}
Expand All @@ -199,12 +195,12 @@ const DefaultTaskGroupExpanded: React.FunctionComponent<Omit<DefaultTaskGroupPro
labelIconPadding={labelIconPadding}
onContextMenu={onContextMenu}
contextMenuOpen={contextMenuOpen}
hover={isHover}
hover={isHover || labelHover}
actionIcon={collapsible ? <CollapseIcon /> : undefined}
onActionIconClick={() => onCollapseChange(element, true)}
>
{label || element.getLabel()}
</NodeLabel>
</GroupLabelComponent>
</g>
) : null;

Expand All @@ -213,53 +209,15 @@ const DefaultTaskGroupExpanded: React.FunctionComponent<Omit<DefaultTaskGroupPro
<Layer id={GROUPS_LAYER}>
<g ref={refs} onContextMenu={onContextMenu} onClick={onSelect} className={innerGroupClassName}>
<rect
x={minX}
y={minY}
width={maxX - minX}
height={maxY - minY}
x={bounds.x}
y={bounds.y}
width={bounds.width}
height={bounds.height}
className={styles.topologyGroupBackground}
/>
</g>
{groupLabel && isHover ? <Layer id={TOP_LAYER}>{groupLabel}</Layer> : groupLabel}
</Layer>
{showLabel && (label || element.getLabel()) && (
<Layer id={isHover ? TOP_LAYER : undefined}>
<GroupLabelComponent
element={element}
boxRef={labelRef}
className={styles.topologyGroupLabel}
x={labelX}
y={labelY}
position={labelPosition}
centerLabelOnEdge={centerLabelOnEdge}
paddingX={8}
paddingY={5}
dragRef={dragNodeRef ? dragLabelRef : undefined}
// status={element.getNodeStatus()}
secondaryLabel={secondaryLabel}
truncateLength={truncateLength}
badge={badge}
badgeColor={badgeColor}
badgeTextColor={badgeTextColor}
badgeBorderColor={badgeBorderColor}
badgeClassName={badgeClassName}
badgeLocation={badgeLocation}
labelIconClass={labelIconClass}
labelIcon={labelIcon}
labelIconPadding={labelIconPadding}
onContextMenu={onContextMenu}
contextMenuOpen={contextMenuOpen}
hover={isHover || labelHover}
actionIcon={collapsible ? <CollapseIcon /> : undefined}
onActionIconClick={() => onCollapseChange(element, true)}
width={width}
taskRef={taskRef}
pillRef={pillRef as any}
>
{label || element.getLabel()}
</GroupLabelComponent>
</Layer>
)}
</g>
);
}
Expand Down
Loading

0 comments on commit 1ca13b5

Please sign in to comment.