Skip to content

Commit 4923465

Browse files
committed
pipline example
1 parent 6ec375c commit 4923465

File tree

3 files changed

+218
-3
lines changed

3 files changed

+218
-3
lines changed

web/src/components/forms/flowCollector-status.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import React, { FC } from 'react';
22

3-
import { PageSection } from '@patternfly/react-core';
3+
import { Flex, FlexItem, PageSection } from '@patternfly/react-core';
44
import DynamicLoader from '../dynamic-loader/dynamic-loader';
55
import { GetFlowCollectorJS } from './config/templates';
6+
import { Pipeline } from './pipeline';
67
import { ResourceStatus } from './resource-status';
78
import { Consumer, ResourceWatcher } from './resource-watcher';
9+
import './forms.css';
810

911
export type FlowCollectorStatusProps = {};
1012

@@ -17,7 +19,14 @@ export const FlowCollectorStatus: FC<FlowCollectorStatusProps> = props => {
1719
{({ group, version, kind, existing }) => {
1820
return (
1921
<PageSection id="pageSection">
20-
<ResourceStatus group={group} version={version} kind={kind} existing={existing} />
22+
<Flex className="status-container" direction={{ default: "column" }}>
23+
<FlexItem flex={{ default: "flex_1" }}>
24+
<Pipeline />
25+
</FlexItem>
26+
<FlexItem flex={{ default: "flex_1" }}>
27+
<ResourceStatus group={group} version={version} kind={kind} existing={existing} />
28+
</FlexItem>
29+
</Flex>
2130
</PageSection>
2231
);
2332
}}

web/src/components/forms/forms.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
.wizard-editor-container>div {
2727
display: flex;
2828
flex-direction: column;
29-
flex:1
29+
flex: 1
3030
}
3131

3232
.editor-toggle-container {
@@ -47,4 +47,8 @@
4747
#editor-toggle-footer {
4848
margin-left: 1.5rem;
4949
margin-right: 1.5rem;
50+
}
51+
52+
.status-container {
53+
flex: 1;
5054
}

web/src/components/forms/pipeline.tsx

+202
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
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

Comments
 (0)