Skip to content

Commit

Permalink
Merge pull request patternfly#114 from leandroberetta/outline-type
Browse files Browse the repository at this point in the history
added property to set whether the outline is hull or rect
  • Loading branch information
jeff-phillips-18 authored Nov 14, 2023
2 parents 8696649 + 26887b5 commit a8a63ce
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 17 deletions.
26 changes: 24 additions & 2 deletions packages/demo-app-ts/src/data/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface GeneratorNodeOptions {
nodeIcons?: boolean;
smallNodes?: boolean;
contextMenus?: boolean;
hulledOutline?: boolean;
}

export interface GeneratorEdgeOptions {
Expand All @@ -53,7 +54,8 @@ export const DefaultNodeOptions: GeneratorNodeOptions = {
nodeBadges: false,
nodeIcons: false,
smallNodes: false,
contextMenus: false
contextMenus: false,
hulledOutline: true
};

export const DefaultEdgeOptions: GeneratorEdgeOptions = {
Expand All @@ -76,6 +78,7 @@ export const getNodeOptions = (
showStatusDecorator?: boolean;
showDecorators?: boolean;
showContextMenu?: boolean;
hulledOutline?: boolean;
labelIconClass?: string;
labelIcon?: React.ComponentClass<SVGIconProps>;
} => {
Expand All @@ -91,6 +94,7 @@ export const getNodeOptions = (
showStatusDecorator: nodeCreationOptions.statusDecorators,
showDecorators: nodeCreationOptions.showDecorators,
showContextMenu: nodeCreationOptions.contextMenus,
hulledOutline: nodeCreationOptions.hulledOutline,
labelIconClass,
labelIcon
};
Expand Down Expand Up @@ -129,6 +133,23 @@ export const generateEdge = (
tagStatus: options.edgeStatuses[index % options.edgeStatuses.length]
});

export const updateGroup = (group: NodeModel, nodeCreationOptions: GeneratorNodeOptions): NodeModel => {
return {
...group,
data: {
badge: nodeCreationOptions.nodeBadges ? 'GN' : undefined,
badgeColor: '#F2F0FC',
badgeTextColor: '#5752d1',
badgeBorderColor: '#CBC1FF',
collapsedWidth: 75,
collapsedHeight: 75,
showContextMenu: nodeCreationOptions.contextMenus,
collapsible: true,
hulledOutline: nodeCreationOptions.hulledOutline
}
};
};

export const generateDataModel = (
numNodes: number,
numGroups: number,
Expand Down Expand Up @@ -167,7 +188,8 @@ export const generateDataModel = (
collapsedWidth: 75,
collapsedHeight: 75,
showContextMenu: nodeCreationOptions.contextMenus,
collapsible: true
collapsible: true,
hulledOutline: nodeOptions.hulledOutline
}
};
if (level === groupDepth) {
Expand Down
4 changes: 2 additions & 2 deletions packages/demo-app-ts/src/demos/TopologyPackage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import stylesComponentFactory from '../components/stylesComponentFactory';
import defaultLayoutFactory from '../layouts/defaultLayoutFactory';
import defaultComponentFactory from '../components/defaultComponentFactory';
import { generateDataModel, generateEdge, generateNode } from '../data/generator';
import { generateDataModel, generateEdge, generateNode, updateGroup } from '../data/generator';
import { useTopologyOptions } from '../utils/useTopologyOptions';
import { Tab, Tabs, TabTitleText } from '@patternfly/react-core';

Expand Down Expand Up @@ -157,7 +157,7 @@ const TopologyViewComponent: React.FunctionComponent<TopologyViewComponentProps>
if (nodes.length) {
const updatedNodes: NodeModel[] = nodes.map((node, index) => {
if (node.group) {
return node;
return updateGroup(node, nodeOptions);
}
return {
...node,
Expand Down
8 changes: 8 additions & 0 deletions packages/demo-app-ts/src/utils/useTopologyOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ export const useTopologyOptions = (
>
Context Menus
</SelectOption>
<SelectOption
hasCheckbox
value="Rectangle Groups"
isSelected={!nodeOptions.hulledOutline}
onClick={() => setNodeOptions((prev) => ({ ...prev, hulledOutline: !prev.hulledOutline }))}
>
Rectangle Groups
</SelectOption>
</SelectList>
);

Expand Down
2 changes: 2 additions & 0 deletions packages/module/src/components/groups/DefaultGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ interface DefaultGroupProps {
onContextMenu?: (e: React.MouseEvent) => void;
/** Flag indicating that the context menu for the node is currently open */
contextMenuOpen?: boolean;
/** Flag indicating whether to use hull layout or rect layout for expanded groups. Defaults to hull (true) */
hulledOutline?: boolean;
}

type DefaultGroupInnerProps = Omit<DefaultGroupProps, 'element'> & { element: Node };
Expand Down
40 changes: 27 additions & 13 deletions packages/module/src/components/groups/DefaultGroupExpanded.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
WithSelectionProps
} from '../../behavior';
import { CollapsibleGroupProps } from './types';
import Rect from '../../geom/Rect';

type DefaultGroupExpandedProps = {
className?: string;
Expand All @@ -41,6 +42,7 @@ type DefaultGroupExpandedProps = {
labelIconClass?: string; // Icon to show in label
labelIcon?: string;
labelIconPadding?: number;
hulledOutline?: boolean;
} & CollapsibleGroupProps & WithDragNodeProps & WithSelectionProps & WithDndDropProps & WithContextMenuProps;

type PointWithSize = [number, number, number];
Expand Down Expand Up @@ -96,7 +98,8 @@ const DefaultGroupExpanded: React.FunctionComponent<DefaultGroupExpandedProps> =
labelIconClass,
labelIcon,
labelIconPadding,
onCollapseChange
onCollapseChange,
hulledOutline = true,
}) => {
const [hovered, hoverRef] = useHover();
const [labelHover, labelHoverRef] = useHover();
Expand All @@ -107,6 +110,7 @@ const DefaultGroupExpanded: React.FunctionComponent<DefaultGroupExpandedProps> =
const outlineRef = useCombineRefs(dndDropRef, anchorRef);
const labelLocation = React.useRef<PointWithSize>();
const pathRef = React.useRef<string>();
const boxRef = React.useRef<Rect | null>(null);

let parent = element.getParent();
let altGroup = false;
Expand All @@ -119,7 +123,7 @@ const DefaultGroupExpanded: React.FunctionComponent<DefaultGroupExpandedProps> =
const padding = maxPadding(element.getStyle<NodeStyle>().padding ?? 17);
const hullPadding = (point: PointWithSize | PointTuple) => (point[2] || 0) + padding;

if (!droppable || !pathRef.current || !labelLocation.current) {
if (!droppable || (hulledOutline && !pathRef.current) || (!hulledOutline && !boxRef.current) || !labelLocation.current) {
const children = element.getNodes().filter(c => c.isVisible());
if (children.length === 0) {
return null;
Expand All @@ -141,17 +145,23 @@ const DefaultGroupExpanded: React.FunctionComponent<DefaultGroupExpandedProps> =
points.push([x + width, y + height, 0] as PointWithSize);
}
});
const hullPoints: (PointWithSize | PointTuple)[] =
points.length > 2 ? polygonHull(points as PointTuple[]) : (points as PointTuple[]);
if (!hullPoints) {
return null;
}

// change the box only when not dragging
pathRef.current = hullPath(hullPoints as PointTuple[], hullPadding);
if (hulledOutline) {
const hullPoints: (PointWithSize | PointTuple)[] =
points.length > 2 ? polygonHull(points as PointTuple[]) : (points as PointTuple[]);
if (!hullPoints) {
return null;
}

// Compute the location of the group label.
labelLocation.current = computeLabelLocation(hullPoints as PointWithSize[]);
// change the box only when not dragging
pathRef.current = hullPath(hullPoints as PointTuple[], hullPadding);

// Compute the location of the group label.
labelLocation.current = computeLabelLocation(hullPoints as PointWithSize[]);
} else {
boxRef.current = element.getBounds();
labelLocation.current = [boxRef.current.x + boxRef.current.width / 2, boxRef.current.y + boxRef.current.height, 0];
}
}

const groupClassName = css(
Expand All @@ -177,14 +187,18 @@ const DefaultGroupExpanded: React.FunctionComponent<DefaultGroupExpandedProps> =
<g ref={labelHoverRef} onContextMenu={onContextMenu} onClick={onSelect} className={groupClassName}>
<Layer id={GROUPS_LAYER}>
<g ref={refs} onContextMenu={onContextMenu} onClick={onSelect} className={innerGroupClassName}>
<path ref={outlineRef} className={styles.topologyGroupBackground} d={pathRef.current} />
{hulledOutline ? (
<path ref={outlineRef} className={styles.topologyGroupBackground} d={pathRef.current} />
) : (
<rect ref={outlineRef} className={styles.topologyGroupBackground} x={boxRef.current.x} y={boxRef.current.y} width={boxRef.current.width} height={boxRef.current.height}/>
)}
</g>
</Layer>
{showLabel && (label || element.getLabel()) && (
<NodeLabel
className={styles.topologyGroupLabel}
x={labelLocation.current[0]}
y={labelLocation.current[1] + hullPadding(labelLocation.current) + 24}
y={labelLocation.current[1] + (hulledOutline ? hullPadding(labelLocation.current) : 0) + 24}
paddingX={8}
paddingY={5}
dragRef={dragNodeRef ? dragLabelRef : undefined}
Expand Down

0 comments on commit a8a63ce

Please sign in to comment.