|
1 | 1 | import React from 'react'; |
2 | 2 | import { |
3 | | - Model, |
4 | | - ModelKind, |
5 | | - withPanZoom, |
6 | | - GraphComponent, |
7 | | - useComponentFactory, |
8 | | - useModel, |
9 | | - ComponentFactory, |
10 | | - useLayoutFactory, |
11 | 3 | Graph, |
12 | 4 | Layout, |
13 | 5 | PipelineDagreLayout, |
14 | | - PipelineNodeModel, |
| 6 | + Visualization, |
| 7 | + VisualizationProvider, |
| 8 | + useEventListener, |
| 9 | + SelectionEventListener, |
| 10 | + SELECTION_EVENT, |
| 11 | + TopologyView, |
| 12 | + VisualizationSurface, |
| 13 | + useVisualizationController, |
| 14 | + NODE_SEPARATION_HORIZONTAL, |
| 15 | + GRAPH_LAYOUT_END_EVENT, |
15 | 16 | getSpacerNodes, |
16 | 17 | getEdgesFromNodes, |
17 | | - useVisualizationController |
| 18 | + DEFAULT_EDGE_TYPE |
18 | 19 | } from '@patternfly/react-topology'; |
19 | 20 | import '@patternfly/react-styles/css/components/Topology/topology-components.css'; |
20 | | -import withTopologySetup from './utils/withTopologySetup'; |
21 | | -import pipelineComponentFactory from './components/pipelineComponentFactory'; |
22 | | -import { createFinallyTasks, createParallelTasks, createStatusTasks, setWhenStatus } from './utils/pipelineUtils'; |
| 21 | +import pipelineComponentFactory, { GROUPED_EDGE_TYPE } from './components/pipelineComponentFactory'; |
| 22 | +import { usePipelineOptions } from './usePipelineOptions'; |
| 23 | +import { useDemoPipelineNodes } from './useDemoPipelineNodes'; |
| 24 | +import { GROUPED_PIPELINE_NODE_SEPARATION_HORIZONTAL } from './components/DemoTaskGroupEdge'; |
| 25 | + |
| 26 | +export const PIPELINE_NODE_SEPARATION_VERTICAL = 65; |
23 | 27 |
|
24 | 28 | export const LAYOUT_TITLE = 'Layout'; |
25 | 29 |
|
26 | | -const getModel = (layout: string): Model => { |
27 | | - const tasks: PipelineNodeModel[] = createStatusTasks('task', 4, undefined, false, true, true, true); |
| 30 | +const PIPELINE_LAYOUT = 'PipelineLayout'; |
| 31 | +const GROUPED_PIPELINE_LAYOUT = 'GroupedPipelineLayout'; |
28 | 32 |
|
29 | | - const whenTasks = tasks.reduce((acc, task, index) => { |
30 | | - if (index % (Math.floor(tasks.length / 3) + 1) !== 0) { |
31 | | - acc.push(task); |
32 | | - } |
33 | | - return acc; |
34 | | - }, []); |
35 | | - setWhenStatus(whenTasks); |
| 33 | +const TopologyPipelineLayout: React.FC = () => { |
| 34 | + const [selectedIds, setSelectedIds] = React.useState<string[]>(); |
36 | 35 |
|
37 | | - for (let i = 0; i < tasks.length; i++) { |
38 | | - tasks[i + 1].runAfterTasks.push(tasks[i].id); |
39 | | - i++; |
40 | | - if (i + 1 < tasks.length) { |
41 | | - tasks[i + 1].runAfterTasks.push(tasks[i].id); |
42 | | - } |
43 | | - i++; |
44 | | - if (i + 1 < tasks.length) { |
45 | | - tasks[i + 1].runAfterTasks.push(tasks[i].id); |
46 | | - } |
47 | | - i++; |
48 | | - } |
| 36 | + const controller = useVisualizationController(); |
| 37 | + const { contextToolbar, showContextMenu, showBadges, showIcons, showGroups, badgeTooltips } = usePipelineOptions( |
| 38 | + true |
| 39 | + ); |
| 40 | + const pipelineNodes = useDemoPipelineNodes( |
| 41 | + showContextMenu, |
| 42 | + showBadges, |
| 43 | + showIcons, |
| 44 | + badgeTooltips, |
| 45 | + 'PipelineDagreLayout', |
| 46 | + showGroups |
| 47 | + ); |
49 | 48 |
|
50 | | - const parallelTasks = createParallelTasks('parallelTasks', tasks[9].id, 3, 2, true, true); |
51 | | - tasks.push(...parallelTasks); |
| 49 | + React.useEffect(() => { |
| 50 | + const spacerNodes = getSpacerNodes(pipelineNodes); |
| 51 | + const nodes = [...pipelineNodes, ...spacerNodes]; |
| 52 | + const edges = getEdgesFromNodes( |
| 53 | + nodes.filter(n => !n.group), |
| 54 | + showGroups ? GROUPED_EDGE_TYPE : DEFAULT_EDGE_TYPE |
| 55 | + ); |
52 | 56 |
|
53 | | - const finallyNodes = createFinallyTasks('finally', 2, tasks, true); |
54 | | - const finallyGroup = { |
55 | | - id: 'finally-group', |
56 | | - type: 'finally-group', |
57 | | - children: finallyNodes.map(n => n.id), |
58 | | - group: true, |
59 | | - style: { padding: [35, 17] } |
60 | | - }; |
| 57 | + controller.fromModel( |
| 58 | + { |
| 59 | + graph: { |
| 60 | + id: 'g1', |
| 61 | + type: 'graph', |
| 62 | + x: 25, |
| 63 | + y: 25, |
| 64 | + layout: showGroups ? GROUPED_PIPELINE_LAYOUT : PIPELINE_LAYOUT |
| 65 | + }, |
| 66 | + nodes, |
| 67 | + edges |
| 68 | + }, |
| 69 | + true |
| 70 | + ); |
| 71 | + controller.getGraph().layout(); |
| 72 | + }, [controller, pipelineNodes, showGroups]); |
61 | 73 |
|
62 | | - const spacerNodes = getSpacerNodes([...tasks, ...finallyNodes]); |
63 | | - const edges = getEdgesFromNodes([...tasks, ...finallyNodes, ...spacerNodes]); |
| 74 | + useEventListener<SelectionEventListener>(SELECTION_EVENT, ids => { |
| 75 | + setSelectedIds(ids); |
| 76 | + }); |
64 | 77 |
|
65 | | - return { |
66 | | - graph: { |
67 | | - id: 'g1', |
68 | | - type: 'graph', |
69 | | - x: 25, |
70 | | - y: 25, |
71 | | - layout |
72 | | - }, |
73 | | - nodes: [...tasks, ...finallyNodes, ...spacerNodes, finallyGroup], |
74 | | - edges |
75 | | - }; |
| 78 | + return ( |
| 79 | + <TopologyView contextToolbar={contextToolbar}> |
| 80 | + <VisualizationSurface state={{ selectedIds }} /> |
| 81 | + </TopologyView> |
| 82 | + ); |
76 | 83 | }; |
77 | 84 |
|
78 | | -export const PipelineLayout = withTopologySetup(() => { |
79 | | - useLayoutFactory((type: string, graph: Graph): Layout | undefined => new PipelineDagreLayout(graph, { nodesep: 95 })); |
80 | | - useComponentFactory(pipelineComponentFactory); |
81 | | - const controller = useVisualizationController(); |
82 | | - controller.setFitToScreenOnLayout(true); |
| 85 | +TopologyPipelineLayout.displayName = 'TopologyPipelineLayout'; |
83 | 86 |
|
84 | | - // support pan zoom and drag |
85 | | - useComponentFactory( |
86 | | - React.useCallback<ComponentFactory>(kind => { |
87 | | - if (kind === ModelKind.graph) { |
88 | | - return withPanZoom()(GraphComponent); |
| 87 | +export const PipelineLayout = React.memo(() => { |
| 88 | + const controller = new Visualization(); |
| 89 | + controller.setFitToScreenOnLayout(true); |
| 90 | + controller.registerComponentFactory(pipelineComponentFactory); |
| 91 | + controller.registerLayoutFactory( |
| 92 | + (type: string, graph: Graph): Layout | undefined => |
| 93 | + new PipelineDagreLayout(graph, { |
| 94 | + nodesep: PIPELINE_NODE_SEPARATION_VERTICAL, |
| 95 | + ranksep: |
| 96 | + type === GROUPED_PIPELINE_LAYOUT ? GROUPED_PIPELINE_NODE_SEPARATION_HORIZONTAL : NODE_SEPARATION_HORIZONTAL, |
| 97 | + ignoreGroups: true |
| 98 | + }) |
| 99 | + ); |
| 100 | + controller.fromModel( |
| 101 | + { |
| 102 | + graph: { |
| 103 | + id: 'g1', |
| 104 | + type: 'graph', |
| 105 | + x: 25, |
| 106 | + y: 25, |
| 107 | + layout: PIPELINE_LAYOUT |
89 | 108 | } |
90 | | - return undefined; |
91 | | - }, []) |
| 109 | + }, |
| 110 | + false |
92 | 111 | ); |
| 112 | + controller.addEventListener(GRAPH_LAYOUT_END_EVENT, () => { |
| 113 | + controller.getGraph().fit(75); |
| 114 | + }); |
93 | 115 |
|
94 | | - useModel(getModel('PipelineDagreLayout')); |
95 | | - return null; |
| 116 | + return ( |
| 117 | + <VisualizationProvider controller={controller}> |
| 118 | + <TopologyPipelineLayout /> |
| 119 | + </VisualizationProvider> |
| 120 | + ); |
96 | 121 | }); |
0 commit comments