Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add correct location, scaling, and anchors for expanded task group's pill labels #10

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading