Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/web/ui/src/features/component/ComponentView.tsx
5286 views
1
import { FC, Fragment, ReactElement } from 'react';
2
import { Link } from 'react-router-dom';
3
import { faCubes, faLink } from '@fortawesome/free-solid-svg-icons';
4
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
6
import { partitionBody } from '../../utils/partition';
7
8
import ComponentBody from './ComponentBody';
9
import ComponentList from './ComponentList';
10
import { HealthLabel } from './HealthLabel';
11
import { ComponentDetail, ComponentInfo, PartitionedBody } from './types';
12
13
import styles from './ComponentView.module.css';
14
15
export interface ComponentViewProps {
16
component: ComponentDetail;
17
info: Record<string, ComponentInfo>;
18
}
19
20
export const ComponentView: FC<ComponentViewProps> = (props) => {
21
// TODO(rfratto): expand/collapse icon for sections (treat it like Row in grafana dashboard)
22
23
const referencedBy = props.component.referencedBy.filter((id) => props.info[id] !== undefined).map((id) => props.info[id]);
24
const referencesTo = props.component.referencesTo.filter((id) => props.info[id] !== undefined).map((id) => props.info[id]);
25
26
const argsPartition = partitionBody(props.component.arguments, 'Arguments');
27
const exportsPartition = props.component.exports && partitionBody(props.component.exports, 'Exports');
28
const debugPartition = props.component.debugInfo && partitionBody(props.component.debugInfo, 'Debug info');
29
30
function partitionTOC(partition: PartitionedBody): ReactElement {
31
return (
32
<li>
33
<Link to={'#' + partition.key.join('-')} target="_top">
34
{partition.displayName[partition.displayName.length - 1]}
35
</Link>
36
{partition.inner.length > 0 && (
37
<ul>
38
{partition.inner.map((next, idx) => {
39
return <Fragment key={idx.toString()}>{partitionTOC(next)}</Fragment>;
40
})}
41
</ul>
42
)}
43
</li>
44
);
45
}
46
47
return (
48
<div className={styles.page}>
49
<nav>
50
<h1>Sections</h1>
51
<hr />
52
<ul>
53
<li>
54
<Link to={'#' + props.component.id} target="_top">
55
{props.component.id}
56
</Link>
57
</li>
58
{argsPartition && partitionTOC(argsPartition)}
59
{exportsPartition && partitionTOC(exportsPartition)}
60
{debugPartition && partitionTOC(debugPartition)}
61
{props.component.referencesTo.length > 0 && (
62
<li>
63
<Link to="#dependencies" target="_top">
64
Dependencies
65
</Link>
66
</li>
67
)}
68
{props.component.referencedBy.length > 0 && (
69
<li>
70
<Link to="#dependants" target="_top">
71
Dependants
72
</Link>
73
</li>
74
)}
75
{props.component.moduleInfo && (
76
<li>
77
<Link to="#module" target="_top">
78
Module components
79
</Link>
80
</li>
81
)}
82
</ul>
83
</nav>
84
85
<main className={styles.content}>
86
<h1 id={props.component.id}>
87
<span className={styles.icon}>
88
<FontAwesomeIcon icon={faCubes} />
89
</span>
90
{props.component.id}
91
&nbsp; {/* space to separate the component name and label so double-click selections work */}
92
<span className={styles.healthLabel}>
93
<HealthLabel health={props.component.health.state} />
94
</span>
95
</h1>
96
97
<div className={styles.docsLink}>
98
<a href={`https://grafana.com/docs/agent/latest/flow/reference/components/${props.component.name}`}>
99
Documentation <FontAwesomeIcon icon={faLink} />
100
</a>
101
</div>
102
103
{props.component.health.message && (
104
<blockquote>
105
<h1>
106
Latest health message{' '}
107
{props.component.health.updatedTime && (
108
<span className={styles.updateTime}>({props.component.health.updatedTime})</span>
109
)}
110
</h1>
111
<p>{props.component.health.message}</p>
112
</blockquote>
113
)}
114
115
<ComponentBody partition={argsPartition} />
116
{exportsPartition && <ComponentBody partition={exportsPartition} />}
117
{debugPartition && <ComponentBody partition={debugPartition} />}
118
119
{props.component.referencesTo.length > 0 && (
120
<section id="dependencies">
121
<h2>Dependencies</h2>
122
<div className={styles.sectionContent}>
123
<ComponentList components={referencesTo} parent={props.component.parent} />
124
</div>
125
</section>
126
)}
127
128
{props.component.referencedBy.length > 0 && (
129
<section id="dependants">
130
<h2>Dependants</h2>
131
<div className={styles.sectionContent}>
132
<ComponentList components={referencedBy} parent={props.component.parent} />
133
</div>
134
</section>
135
)}
136
137
{props.component.moduleInfo && (
138
<section id="module">
139
<h2>Module components</h2>
140
<div className={styles.sectionContent}>
141
<ComponentList
142
components={props.component.moduleInfo}
143
parent={pathJoin([props.component.parent, props.component.id])}
144
/>
145
</div>
146
</section>
147
)}
148
</main>
149
</div>
150
);
151
};
152
153
function pathJoin(paths: (string | undefined)[]): string {
154
return paths.filter((p) => p && p !== '').join('/');
155
}
156
157