Skip to content

Commit

Permalink
Merge branch 'patternfly:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
wise-king-sullyman authored Feb 21, 2024
2 parents 2f00eac + bed1c18 commit 76c75be
Show file tree
Hide file tree
Showing 24 changed files with 197 additions and 99 deletions.
3 changes: 1 addition & 2 deletions packages/demo-app-ts/src/components/GroupHull.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import { polygonHull } from 'd3-polygon';
import * as _ from 'lodash';
import {
WithDragNodeProps,
WithSelectionProps,
Expand Down Expand Up @@ -85,7 +84,7 @@ const GroupHull: React.FunctionComponent<GroupHullProps> = ({
return null;
}
const points: PointWithSize[] = [];
_.forEach(nodeChildren, c => {
nodeChildren.forEach(c => {
if (c.getNodeShape() === NodeShape.ellipse) {
const { width, height } = c.getBounds();
const { x, y } = c.getBounds().getCenter();
Expand Down
7 changes: 3 additions & 4 deletions packages/demo-app-ts/src/demos/TopologyPackage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { action } from 'mobx';
import * as _ from 'lodash';
import {
Controller,
createTopologyControlButtons,
Expand Down Expand Up @@ -146,8 +145,8 @@ const TopologyViewComponent: React.FunctionComponent<TopologyViewComponentProps>
}, [controller, lowScale, medScale]);

const topologySideBar = (
<TopologySideBar show={_.size(selectedIds) > 0} resizable={sideBarResizable} onClose={() => setSelectedIds([])}>
<div style={{ marginTop: 27, marginLeft: 20, height: '800px' }}>{_.head(selectedIds)}</div>
<TopologySideBar show={!!selectedIds?.length} resizable={sideBarResizable} onClose={() => setSelectedIds([])}>
<div style={{ marginTop: 27, marginLeft: 20, height: '800px' }}>{selectedIds?.[0]}</div>
</TopologySideBar>
);

Expand Down Expand Up @@ -208,7 +207,7 @@ const TopologyViewComponent: React.FunctionComponent<TopologyViewComponentProps>
contextToolbar={contextToolbar}
viewToolbar={viewToolbar}
sideBar={useSidebar && topologySideBar}
sideBarOpen={useSidebar && _.size(selectedIds) > 0}
sideBarOpen={useSidebar && !!selectedIds?.length}
sideBarResizable={sideBarResizable}
>
<VisualizationSurface state={{ selectedIds }} />
Expand Down
9 changes: 6 additions & 3 deletions packages/demo-app-ts/src/utils/styleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,18 @@ export const createNode = (options: {
(options.marginX || 60) +
(options.x ??
(options.column - 1) *
(options.label && options.labelPosition === LabelPosition.right ? RIGHT_LABEL_COLUMN_WIDTH : COLUMN_WIDTH));
(options.label && [LabelPosition.right, LabelPosition.left].includes(options.labelPosition)
? RIGHT_LABEL_COLUMN_WIDTH
: COLUMN_WIDTH));
nodeModel.y =
20 +
(width - height) / 2 +
(options.y ??
(options.row - 1) *
(!options.label || options.labelPosition === LabelPosition.right ? ROW_HEIGHT : BOTTOM_LABEL_ROW_HEIGHT));
(!options.label || [LabelPosition.right, LabelPosition.left].includes(options.labelPosition)
? ROW_HEIGHT
: BOTTOM_LABEL_ROW_HEIGHT));
}

return nodeModel;
};

Expand Down
22 changes: 16 additions & 6 deletions packages/demo-app-ts/src/utils/useTopologyOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import * as _ from 'lodash';
import {
Button,
Dropdown,
Expand All @@ -21,9 +20,6 @@ import { DefaultEdgeOptions, DefaultNodeOptions, GeneratorEdgeOptions, Generator
import { EDGE_ANIMATION_SPEEDS, EDGE_STYLES, EDGE_TERMINAL_TYPES, NODE_SHAPES, NODE_STATUSES } from './styleUtils';
import { Controller, Model, NodeShape } from '@patternfly/react-topology';

const GRAPH_LAYOUT_OPTIONS = ['x', 'y', 'visible', 'style', 'layout', 'scale', 'scaleExtent', 'layers'];
const NODE_LAYOUT_OPTIONS = ['x', 'y', 'visible', 'style', 'collapsed', 'width', 'height', 'shape'];

export const useTopologyOptions = (
controller: Controller
): {
Expand Down Expand Up @@ -380,7 +376,14 @@ export const useTopologyOptions = (
const currentModel = controller.toModel();
currentModel.graph = {
...currentModel.graph,
..._.pick(savedModel.graph, GRAPH_LAYOUT_OPTIONS)
x: savedModel.graph.x,
y: savedModel.graph.y,
visible: savedModel.graph.visible,
style: savedModel.graph.style,
layout: savedModel.graph.layout,
scale: savedModel.graph.scale,
scaleExtent: savedModel.graph.scaleExtent,
layers: savedModel.graph.layers,
};
currentModel.nodes = currentModel.nodes.map((n) => {
const savedNode = savedModel.nodes.find((sn) => sn.id === n.id);
Expand All @@ -389,7 +392,14 @@ export const useTopologyOptions = (
}
return {
...n,
..._.pick(savedNode, NODE_LAYOUT_OPTIONS)
x: savedNode.x,
y: savedNode.y,
visible: savedNode.visible,
style: savedNode.style,
collapsed: savedNode.collapsed,
width: savedNode.width,
height: savedNode.height,
shape: savedNode.shape,
};
});
controller.fromModel(currentModel, false);
Expand Down
2 changes: 0 additions & 2 deletions packages/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"@types/react-measure": "^2.0.6",
"d3": "^7.8.0",
"dagre": "0.8.2",
"lodash": "^4.17.19",
"mobx": "^6.9.0",
"mobx-react": "^7.6.0",
"point-in-svg-path": "^1.0.1",
Expand All @@ -61,7 +60,6 @@
"@patternfly/patternfly-a11y": "^4.3.1",
"@patternfly/react-code-editor": "^5.1.1",
"@patternfly/react-table": "^5.1.1",
"@types/lodash": "^4.14.191",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"camel-case": "^3.0.0",
Expand Down
13 changes: 8 additions & 5 deletions packages/module/src/Visualization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ComponentType } from 'react';
import { action, computed, observable, makeObservable } from 'mobx';
import * as _ from 'lodash';
import { action, computed, observable, makeObservable, configure } from 'mobx';
import {
Controller,
Graph,
Expand All @@ -24,6 +23,9 @@ import {
import defaultElementFactory from './elements/defaultElementFactory';
import Stateful from './utils/Stateful';

// Configure MobX to isolate state, this allows for applications to use different versions of MobX
configure({ isolateGlobalState: true });

export class Visualization extends Stateful implements Controller {
elements: { [id: string]: GraphElement } = {};

Expand Down Expand Up @@ -94,7 +96,7 @@ export class Visualization extends Stateful implements Controller {

// If not merging, clear out the old elements
if (!merge) {
_.forIn(this.elements, element => this.removeElement(element));
Object.keys(this.elements).forEach(element => this.removeElement(this.elements[element]));
}

// Create the graph if given in the model
Expand Down Expand Up @@ -147,7 +149,8 @@ export class Visualization extends Stateful implements Controller {

// remove all stale elements
if (merge) {
_.forIn(this.elements, element => {
Object.keys(this.elements).forEach(key => {
const element = this.elements[key];
if (!validIds.includes(element.getId())) {
this.removeElement(element);
}
Expand Down Expand Up @@ -186,7 +189,7 @@ export class Visualization extends Stateful implements Controller {
}

getElements(): GraphElement[] {
return _.values(this.elements);
return Object.values(this.elements);
}

toModel(): Model {
Expand Down
24 changes: 17 additions & 7 deletions packages/module/src/components/VisualizationSurface.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as React from 'react';
import * as _ from 'lodash';
import { action } from 'mobx';
// https://github.com/mobxjs/mobx-react#observer-batching
import 'mobx-react/batchingForReactDom';
import { observer } from 'mobx-react';
import ReactMeasure from 'react-measure';
import ReactMeasure, { ContentRect } from 'react-measure';
import { css } from '@patternfly/react-styles';
import styles from '../css/topology-components';
import { State } from '../types';
Expand All @@ -29,25 +28,36 @@ const VisualizationSurface: React.FunctionComponent<VisualizationSurfaceProps> =
state
}: VisualizationSurfaceProps) => {
const controller = useVisualizationController();
const timerId = React.useRef<NodeJS.Timer>();

const debounceMeasure = React.useCallback((func: (contentRect: ContentRect) => void, delay?: number) => {
return (contentRect: ContentRect) => {
if (!timerId.current) {
func(contentRect)
}
clearTimeout(timerId.current)

timerId.current = setTimeout(() => func(contentRect), delay)
}
}, []);

React.useEffect(() => {
state && controller.setState(state);
}, [controller, state]);

const onMeasure = React.useMemo(
() =>
_.debounce<any>(
action((contentRect: { client: { width: number; height: number } }) => {
debounceMeasure(
action((contentRect: ContentRect) => {
controller.getGraph().setDimensions(new Dimensions(contentRect.client.width, contentRect.client.height));
}),
100,
{ leading: true, trailing: true }
),
[controller]
[controller, debounceMeasure]
);

// dispose of onMeasure
React.useEffect(() => () => onMeasure.cancel(), [onMeasure]);
React.useEffect(() => () => clearTimeout(timerId.current), [onMeasure]);

if (!controller.hasGraph()) {
return null;
Expand Down
7 changes: 3 additions & 4 deletions packages/module/src/components/edges/DefaultEdge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import * as _ from 'lodash';
import { observer } from 'mobx-react';
import { Edge, EdgeTerminalType, GraphElement, isEdge, isNode, NodeStatus, ScaleDetailsLevel } from '../../types';
import { ConnectDragSource, OnSelect } from '../../behavior';
Expand Down Expand Up @@ -134,15 +133,15 @@ const DefaultEdgeInner: React.FunctionComponent<DefaultEdgeInnerProps> = observe
const bgStartPoint =
!startTerminalType || startTerminalType === EdgeTerminalType.none
? [startPoint.x, startPoint.y]
: getConnectorStartPoint(_.head(bendpoints) || endPoint, startPoint, startTerminalSize);
: getConnectorStartPoint(bendpoints?.[0] || endPoint, startPoint, startTerminalSize);
const bgEndPoint =
!endTerminalType || endTerminalType === EdgeTerminalType.none
? [endPoint.x, endPoint.y]
: getConnectorStartPoint(_.last(bendpoints) || startPoint, endPoint, endTerminalSize);
: getConnectorStartPoint(bendpoints?.[bendpoints.length - 1] || startPoint, endPoint, endTerminalSize);
const backgroundPath = `M${bgStartPoint[0]} ${bgStartPoint[1]} ${bendpoints
.map((b: Point) => `L${b.x} ${b.y} `)
.join('')}L${bgEndPoint[0]} ${bgEndPoint[1]}`;

const showTag = tag && (detailsLevel === ScaleDetailsLevel.high || hover);
const scale = element.getGraph().getScale();
const tagScale = hover && !(detailsLevel === ScaleDetailsLevel.high) ? Math.max(1, 1 / scale) : 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import * as _ from 'lodash';
import { css } from '@patternfly/react-styles';
import styles from '../../../css/topology-components';
import Point from '../../../geom/Point';
Expand All @@ -15,8 +14,8 @@ interface ConnectorArrowProps {
dragRef?: ConnectDragSource;
}

const pointsStringFromPoints = (points: [number, number][]): string =>
_.reduce(points, (result: string, nextPoint: [number, number]) => `${result} ${nextPoint[0]},${nextPoint[1]}`, '');
const pointsStringFromPoints = (points?: [number, number][]): string =>
points?.reduce((result: string, nextPoint: [number, number]) => `${result} ${nextPoint[0]},${nextPoint[1]}`, '') ?? '';

const ConnectorArrow: React.FunctionComponent<ConnectorArrowProps> = ({
startPoint,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import * as _ from 'lodash';
import { css } from '@patternfly/react-styles';
import styles from '../../../css/topology-components';
import { Edge, EdgeTerminalType, NodeStatus } from '../../../types';
Expand Down Expand Up @@ -55,7 +54,7 @@ const DefaultConnectorTerminal: React.FunctionComponent<EdgeConnectorArrowProps>
return null;
}
const bendPoints = edge.getBendpoints();
const startPoint = isTarget ? _.last(bendPoints) || edge.getStartPoint() : _.head(bendPoints) || edge.getEndPoint();
const startPoint = isTarget ? bendPoints[bendPoints.length - 1] || edge.getStartPoint() : bendPoints[0] || edge.getEndPoint();
const endPoint = isTarget ? edge.getEndPoint() : edge.getStartPoint();
const classes = css(styles.topologyEdge, className, StatusModifier[status]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const getConnectorStartPoint = (startPoint: Point, endPoint: Point, size:
export const getConnectorRotationAngle = (startPoint: Point, endPoint: Point): number =>
180 - (Math.atan2(endPoint.y - startPoint.y, startPoint.x - endPoint.x) * 180) / Math.PI;

export const getConnectorBoundingBox = (startPoint: Point, endPoint: Point, size: number): [number, number][] => {
export const getConnectorBoundingBox = (startPoint: Point, endPoint: Point, size: number): [number, number][] | null => {
const length = Math.sqrt((endPoint.x - startPoint.x) ** 2 + (endPoint.y - startPoint.y) ** 2);
if (!length) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion packages/module/src/components/groups/DefaultGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface DefaultGroupProps {
secondaryLabel?: string;
/** Flag to show the label */
showLabel?: boolean; // Defaults to true
/** Position of the label, bottom or left. Defaults to element.getLabelPosition() or bottom */
/** Position of the label, top or bottom. Defaults to element.getLabelPosition() or bottom */
labelPosition?: LabelPosition;
/** The maximum length of the label before truncation */
truncateLength?: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ const DefaultGroupCollapsed: React.FunctionComponent<DefaultGroupCollapsedProps>
{showLabel && (
<NodeLabel
className={styles.topologyGroupLabel}
x={labelPosition === LabelPosition.right ? collapsedWidth + 8 : collapsedWidth / 2}
y={labelPosition === LabelPosition.right ? collapsedHeight / 2 : collapsedHeight + 6}
x={collapsedWidth / 2}
y={labelPosition === LabelPosition.top ? collapsedHeight / 2 - collapsedHeight : collapsedHeight + 6}
paddingX={8}
paddingY={5}
dragRef={dragNodeRef ? dragLabelRef : undefined}
Expand Down
Loading

0 comments on commit 76c75be

Please sign in to comment.