From b47f9cd0a6cba1665a09385ffc3411a170625388 Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Thu, 6 Jun 2024 14:30:55 -0400 Subject: [PATCH] feat(pipelines): add expand all and collapse all buttons to control bar --- frontend/package-lock.json | 8 +-- frontend/package.json | 2 +- .../topology/PipelineVisualizationSurface.tsx | 60 +++++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1a57379771..bffea86773 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,7 +22,7 @@ "@patternfly/react-styles": "^5.2.1", "@patternfly/react-table": "^5.2.1", "@patternfly/react-tokens": "^5.2.1", - "@patternfly/react-topology": "^5.4.0-prerelease.1", + "@patternfly/react-topology": "^5.4.0-prerelease.6", "@patternfly/react-virtualized-extension": "^5.0.0", "@types/classnames": "^2.3.1", "axios": "^1.6.4", @@ -3922,9 +3922,9 @@ "integrity": "sha512-8GYz/jnJTGAWUJt5eRAW5dtyiHPKETeFJBPGHaUQnvi/t1ZAkoy8i4Kd/RlHsDC7ktiu813SKCmlzwBwldAHKg==" }, "node_modules/@patternfly/react-topology": { - "version": "5.4.0-prerelease.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.4.0-prerelease.1.tgz", - "integrity": "sha512-NCSxXsr+U0m5VceVs6ALiS24ntIr7HfpHwMXCmx7r+zoT+X3piFNH/DhMYWWtVhyGlCXXpjQvQc0AQ9xzZ8lKw==", + "version": "5.4.0-prerelease.6", + "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.4.0-prerelease.6.tgz", + "integrity": "sha512-suyY+UOW9GgcDjt0HMHTKYx9UePdHAF3BSZN0Xt1zFtgR3AFMl3DOuAeYva4Yyk18OkA0D9gRe29283kgG536Q==", "dependencies": { "@patternfly/react-core": "^5.1.1", "@patternfly/react-icons": "^5.1.1", diff --git a/frontend/package.json b/frontend/package.json index ec7d78d92a..d8cb43d6d7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -65,7 +65,7 @@ "@patternfly/react-styles": "^5.2.1", "@patternfly/react-table": "^5.2.1", "@patternfly/react-tokens": "^5.2.1", - "@patternfly/react-topology": "^5.4.0-prerelease.1", + "@patternfly/react-topology": "^5.4.0-prerelease.6", "@patternfly/react-virtualized-extension": "^5.0.0", "@types/classnames": "^2.3.1", "axios": "^1.6.4", diff --git a/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx b/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx index cec5967284..f05528ecbc 100644 --- a/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx +++ b/frontend/src/concepts/topology/PipelineVisualizationSurface.tsx @@ -10,6 +10,8 @@ import { useVisualizationController, VisualizationSurface, addSpacerNodes, + DEFAULT_SPACER_NODE_TYPE, + DEFAULT_EDGE_TYPE, } from '@patternfly/react-topology'; import { EmptyState, @@ -18,6 +20,7 @@ import { EmptyStateHeader, } from '@patternfly/react-core'; import { ExclamationCircleIcon } from '@patternfly/react-icons'; +import { NODE_HEIGHT, NODE_WIDTH } from './const'; type PipelineVisualizationSurfaceProps = { nodes: PipelineNodeModel[]; @@ -62,6 +65,55 @@ const PipelineVisualizationSurface: React.FC } } }, [controller, nodes]); + + const collapseAllCallback = React.useCallback( + (collapseAll: boolean) => { + // First, expand/collapse all nodes + if (collapseAll) { + controller.getGraph().collapseAll(); + } else { + controller.getGraph().expandAll(); + } + // We must recreate the model based on what is visible + const model = controller.toModel(); + + // Get all the non-spacer nodes, mark them all visible again + const nonSpacerNodes = model + .nodes!.filter((n) => n.type !== DEFAULT_SPACER_NODE_TYPE) + .map((n) => ({ + ...n, + visible: true, + })); + + // If collapsing, set the size of the collapsed group nodes + if (collapseAll) { + nonSpacerNodes.forEach((node) => { + const newNode = node; + if (node.group && node.collapsed) { + newNode.width = NODE_WIDTH; + newNode.height = NODE_HEIGHT; + } + }); + } + // Determine the new set of nodes, including the spacer nodes + const pipelineNodes = addSpacerNodes(nonSpacerNodes); + + // Determine the new edges + const edges = getEdgesFromNodes( + pipelineNodes, + DEFAULT_SPACER_NODE_TYPE, + DEFAULT_EDGE_TYPE, + DEFAULT_EDGE_TYPE, + ); + + // Apply the new model and run the layout + controller.fromModel({ nodes: pipelineNodes, edges }, true); + controller.getGraph().layout(); + controller.getGraph().fit(80); + }, + [controller], + ); + if (error) { return ( @@ -81,6 +133,8 @@ const PipelineVisualizationSurface: React.FC { controller.getGraph().scaleBy(4 / 3); }), @@ -94,6 +148,12 @@ const PipelineVisualizationSurface: React.FC controller.getGraph().reset(); controller.getGraph().layout(); }), + expandAllCallback: action(() => { + collapseAllCallback(false); + }), + collapseAllCallback: action(() => { + collapseAllCallback(true); + }), legend: false, })} />