1
+ import {
2
+ DEFAULT_EDGE_TYPE ,
3
+ DEFAULT_FINALLY_NODE_TYPE ,
4
+ DEFAULT_SPACER_NODE_TYPE ,
5
+ DEFAULT_TASK_NODE_TYPE ,
6
+ DEFAULT_WHEN_OFFSET ,
7
+ DefaultTaskGroup ,
8
+ FinallyNode ,
9
+ Graph ,
10
+ GraphComponent ,
11
+ Layout ,
12
+ Model ,
13
+ ModelKind ,
14
+ Node ,
15
+ PipelineDagreLayout ,
16
+ PipelineNodeModel ,
17
+ RunStatus ,
18
+ SpacerNode ,
19
+ TaskEdge ,
20
+ TaskNode ,
21
+ TopologyView ,
22
+ Visualization ,
23
+ VisualizationProvider ,
24
+ VisualizationSurface ,
25
+ WhenDecorator ,
26
+ getEdgesFromNodes ,
27
+ getSpacerNodes ,
28
+ useVisualizationController
29
+ } from '@patternfly/react-topology' ;
30
+ import * as React from 'react' ;
31
+
32
+ export interface Step {
33
+ id : string ;
34
+ type ?: string ;
35
+ label : string ;
36
+ runAfterTasks ?: string [ ] ;
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ data ?: any ;
39
+ }
40
+
41
+ const steps : Step [ ] = [
42
+ {
43
+ id : 'ebpf' ,
44
+ label : 'eBPF agents' ,
45
+ data : {
46
+ status : RunStatus . Succeeded
47
+ }
48
+ } ,
49
+ {
50
+ id : 'kafka' ,
51
+ label : 'Kafka' ,
52
+ runAfterTasks : [ 'ebpf' ] ,
53
+ } ,
54
+ {
55
+ id : 'flp' ,
56
+ label : 'Flowlogs pipeline' ,
57
+ runAfterTasks : [ 'kafka' ] ,
58
+ data : {
59
+ status : RunStatus . Succeeded
60
+ }
61
+ } ,
62
+ {
63
+ id : 'loki' ,
64
+ label : 'Loki' ,
65
+ runAfterTasks : [ 'flp' ] ,
66
+ } ,
67
+ {
68
+ id : 'prom' ,
69
+ label : 'Prometheus' ,
70
+ runAfterTasks : [ 'flp' ] ,
71
+ } ,
72
+ {
73
+ id : 'exporter-1' ,
74
+ label : 'OpenTelemetry' ,
75
+ runAfterTasks : [ 'flp' ] ,
76
+ } ,
77
+ {
78
+ id : 'exporter-2' ,
79
+ label : 'Kafka' ,
80
+ runAfterTasks : [ 'flp' ] ,
81
+ } ,
82
+ {
83
+ id : 'exporter-3' ,
84
+ label : 'IPFIX' ,
85
+ runAfterTasks : [ 'flp' ] ,
86
+ } ,
87
+ {
88
+ id : 'plugin' ,
89
+ label : 'Console plugin' ,
90
+ runAfterTasks : [ 'loki' , 'prom' ] ,
91
+ data : {
92
+ status : RunStatus . Succeeded
93
+ }
94
+ } ,
95
+ ] ;
96
+
97
+ const getSteps = ( ) => {
98
+ return steps . map ( s => ( {
99
+ type : s . type || 'DEFAULT_TASK_NODE' ,
100
+ width : 180 ,
101
+ height : 32 ,
102
+ style : {
103
+ padding : [ 45 , 15 ]
104
+ } ,
105
+ ...s
106
+ } ) ) as PipelineNodeModel [ ] ;
107
+ } ;
108
+
109
+ export interface StepProps {
110
+ element : Node ;
111
+ }
112
+
113
+ export const StepNode : React . FunctionComponent < StepProps > = ( { element } ) => {
114
+ const data = element . getData ( ) ;
115
+
116
+ const whenDecorator = data ?. whenStatus ? (
117
+ < WhenDecorator element = { element } status = { data . whenStatus } leftOffset = { DEFAULT_WHEN_OFFSET } />
118
+ ) : null ;
119
+
120
+ return (
121
+ < TaskNode element = { element } status = { data ?. status } >
122
+ { whenDecorator }
123
+ </ TaskNode >
124
+ ) ;
125
+ } ;
126
+
127
+ const pipelineComponentFactory = ( kind : ModelKind , type : string ) => {
128
+ if ( kind === ModelKind . graph ) {
129
+ return GraphComponent ;
130
+ }
131
+ switch ( type ) {
132
+ case DEFAULT_TASK_NODE_TYPE :
133
+ return StepNode ;
134
+ case DEFAULT_FINALLY_NODE_TYPE :
135
+ return FinallyNode ;
136
+ case 'task-group' :
137
+ return DefaultTaskGroup ;
138
+ case 'finally-group' :
139
+ return DefaultTaskGroup ;
140
+ case DEFAULT_SPACER_NODE_TYPE :
141
+ return SpacerNode ;
142
+ case 'finally-spacer-edge' :
143
+ case DEFAULT_EDGE_TYPE :
144
+ return TaskEdge ;
145
+ default :
146
+ return undefined ;
147
+ }
148
+ } ;
149
+
150
+ export const PipelineSteps : React . FC = ( ) => {
151
+ const controller = useVisualizationController ( ) ;
152
+ React . useEffect ( ( ) => {
153
+ controller . fromModel (
154
+ {
155
+ graph : {
156
+ id : 'g1' ,
157
+ type : 'graph'
158
+ } ,
159
+ nodes : getSteps ( )
160
+ } ,
161
+ false
162
+ ) ;
163
+ } , [ controller ] ) ;
164
+
165
+ return (
166
+ < TopologyView >
167
+ < VisualizationSurface />
168
+ </ TopologyView >
169
+ ) ;
170
+ } ;
171
+
172
+ PipelineSteps . displayName = 'PipelineSteps' ;
173
+
174
+ export const Pipeline : React . FC = ( ) => {
175
+ const controller = new Visualization ( ) ;
176
+ controller . setFitToScreenOnLayout ( true ) ;
177
+ controller . registerComponentFactory ( pipelineComponentFactory ) ;
178
+ controller . registerLayoutFactory ( ( type : string , graph : Graph ) : Layout | undefined => new PipelineDagreLayout ( graph ) ) ;
179
+ const spacerNodes = getSpacerNodes ( getSteps ( ) ) ;
180
+ const nodes = [ ...getSteps ( ) , ...spacerNodes ] ;
181
+ const edges = getEdgesFromNodes ( getSteps ( ) ) ;
182
+
183
+ const model : Model = {
184
+ nodes,
185
+ edges,
186
+ graph : {
187
+ id : 'g1' ,
188
+ type : 'graph' ,
189
+ layout : 'pipelineLayout'
190
+ }
191
+ } ;
192
+
193
+ controller . fromModel ( model , false ) ;
194
+
195
+ return (
196
+ < VisualizationProvider controller = { controller } >
197
+ < VisualizationSurface />
198
+ </ VisualizationProvider >
199
+ ) ;
200
+ } ;
201
+
202
+ export default Pipeline ;
0 commit comments