mirror of
https://github.com/prometheus/prometheus
synced 2025-01-12 18:01:36 +00:00
React UI: More conversions to Function Components (#6259)
* React UI: More conversions to Function Components Signed-off-by: Julius Volz <julius.volz@gmail.com> * Address chat feedback over Riot Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
f7446778f3
commit
fffb5ca1e9
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent, ReactNode } from 'react';
|
||||
import React, { FC, ReactNode } from 'react';
|
||||
|
||||
import { Alert, Table } from 'reactstrap';
|
||||
|
||||
@ -41,96 +41,92 @@ interface Metric {
|
||||
|
||||
type SampleValue = [number, string];
|
||||
|
||||
class DataTable extends PureComponent<QueryResult> {
|
||||
limitSeries(series: InstantSample[] | RangeSamples[]): InstantSample[] | RangeSamples[] {
|
||||
const maxSeries = 10000;
|
||||
const limitSeries = <S extends InstantSample | RangeSamples>(series: S[]): S[] => {
|
||||
const maxSeries = 10000;
|
||||
|
||||
if (series.length > maxSeries) {
|
||||
return series.slice(0, maxSeries);
|
||||
}
|
||||
return series;
|
||||
if (series.length > maxSeries) {
|
||||
return series.slice(0, maxSeries);
|
||||
}
|
||||
return series;
|
||||
};
|
||||
|
||||
const DataTable: FC<QueryResult> = ({ data }) => {
|
||||
if (data === null) {
|
||||
return <Alert color="light">No data queried yet</Alert>;
|
||||
}
|
||||
|
||||
render() {
|
||||
const data = this.props.data;
|
||||
if (data.result === null || data.result.length === 0) {
|
||||
return <Alert color="secondary">Empty query result</Alert>;
|
||||
}
|
||||
|
||||
if (data === null) {
|
||||
return <Alert color="light">No data queried yet</Alert>;
|
||||
}
|
||||
|
||||
if (data.result === null || data.result.length === 0) {
|
||||
return <Alert color="secondary">Empty query result</Alert>;
|
||||
}
|
||||
|
||||
let rows: ReactNode[] = [];
|
||||
let limited = false;
|
||||
switch (data.resultType) {
|
||||
case 'vector':
|
||||
rows = (this.limitSeries(data.result) as InstantSample[]).map(
|
||||
(s: InstantSample, index: number): ReactNode => {
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>
|
||||
<SeriesName labels={s.metric} format={false} />
|
||||
</td>
|
||||
<td>{s.value[1]}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
);
|
||||
limited = rows.length !== data.result.length;
|
||||
break;
|
||||
case 'matrix':
|
||||
rows = (this.limitSeries(data.result) as RangeSamples[]).map((s, index) => {
|
||||
const valueText = s.values
|
||||
.map(v => {
|
||||
return [1] + ' @' + v[0];
|
||||
})
|
||||
.join('\n');
|
||||
let rows: ReactNode[] = [];
|
||||
let limited = false;
|
||||
switch (data.resultType) {
|
||||
case 'vector':
|
||||
rows = (limitSeries(data.result) as InstantSample[]).map(
|
||||
(s: InstantSample, index: number): ReactNode => {
|
||||
return (
|
||||
<tr style={{ whiteSpace: 'pre' }} key={index}>
|
||||
<tr key={index}>
|
||||
<td>
|
||||
<SeriesName labels={s.metric} format={false} />
|
||||
</td>
|
||||
<td>{valueText}</td>
|
||||
<td>{s.value[1]}</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
limited = rows.length !== data.result.length;
|
||||
break;
|
||||
case 'scalar':
|
||||
rows.push(
|
||||
<tr key="0">
|
||||
<td>scalar</td>
|
||||
<td>{data.result[1]}</td>
|
||||
}
|
||||
);
|
||||
limited = rows.length !== data.result.length;
|
||||
break;
|
||||
case 'matrix':
|
||||
rows = (limitSeries(data.result) as RangeSamples[]).map((s, index) => {
|
||||
const valueText = s.values
|
||||
.map(v => {
|
||||
return [1] + ' @' + v[0];
|
||||
})
|
||||
.join('\n');
|
||||
return (
|
||||
<tr style={{ whiteSpace: 'pre' }} key={index}>
|
||||
<td>
|
||||
<SeriesName labels={s.metric} format={false} />
|
||||
</td>
|
||||
<td>{valueText}</td>
|
||||
</tr>
|
||||
);
|
||||
break;
|
||||
case 'string':
|
||||
rows.push(
|
||||
<tr key="0">
|
||||
<td>scalar</td>
|
||||
<td>{data.result[1]}</td>
|
||||
</tr>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return <Alert color="danger">Unsupported result value type</Alert>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{limited && (
|
||||
<Alert color="danger">
|
||||
<strong>Warning:</strong> Fetched {data.result.length} metrics, only displaying first {rows.length}.
|
||||
</Alert>
|
||||
)}
|
||||
<Table hover size="sm" className="data-table">
|
||||
<tbody>{rows}</tbody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
});
|
||||
limited = rows.length !== data.result.length;
|
||||
break;
|
||||
case 'scalar':
|
||||
rows.push(
|
||||
<tr key="0">
|
||||
<td>scalar</td>
|
||||
<td>{data.result[1]}</td>
|
||||
</tr>
|
||||
);
|
||||
break;
|
||||
case 'string':
|
||||
rows.push(
|
||||
<tr key="0">
|
||||
<td>scalar</td>
|
||||
<td>{data.result[1]}</td>
|
||||
</tr>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return <Alert color="danger">Unsupported result value type</Alert>;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{limited && (
|
||||
<Alert color="danger">
|
||||
<strong>Warning:</strong> Fetched {data.result.length} metrics, only displaying first {rows.length}.
|
||||
</Alert>
|
||||
)}
|
||||
<Table hover size="sm" className="data-table">
|
||||
<tbody>{rows}</tbody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataTable;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
import SeriesName from './SeriesName';
|
||||
|
||||
@ -6,31 +6,23 @@ interface LegendProps {
|
||||
series: any; // TODO: Type this.
|
||||
}
|
||||
|
||||
class Legend extends PureComponent<LegendProps> {
|
||||
renderLegendItem(s: any) {
|
||||
return (
|
||||
<tr key={s.index} className="legend-item">
|
||||
<td>
|
||||
<div className="legend-swatch" style={{ backgroundColor: s.color }}></div>
|
||||
</td>
|
||||
<td>
|
||||
<SeriesName labels={s.labels} format={true} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<table className="graph-legend">
|
||||
<tbody>
|
||||
{this.props.series.map((s: any) => {
|
||||
return this.renderLegendItem(s);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
}
|
||||
const Legend: FC<LegendProps> = ({ series }) => {
|
||||
return (
|
||||
<table className="graph-legend">
|
||||
<tbody>
|
||||
{series.map((s: any) => (
|
||||
<tr key={s.index} className="legend-item">
|
||||
<td>
|
||||
<div className="legend-swatch" style={{ backgroundColor: s.color }}></div>
|
||||
</td>
|
||||
<td>
|
||||
<SeriesName labels={s.labels} format={true} />
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
|
||||
export default Legend;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import React, { FC } from 'react';
|
||||
import metricToSeriesName from './MetricFormat';
|
||||
|
||||
interface SeriesNameProps {
|
||||
@ -6,11 +6,9 @@ interface SeriesNameProps {
|
||||
format: boolean;
|
||||
}
|
||||
|
||||
class SeriesName extends PureComponent<SeriesNameProps> {
|
||||
renderFormatted(): React.ReactNode {
|
||||
const labels = this.props.labels!;
|
||||
|
||||
const labelNodes: React.ReactNode[] = [];
|
||||
const SeriesName: FC<SeriesNameProps> = ({ labels, format }) => {
|
||||
const renderFormatted = (): React.ReactElement => {
|
||||
const labelNodes: React.ReactElement[] = [];
|
||||
let first = true;
|
||||
for (const label in labels) {
|
||||
if (label === '__name__') {
|
||||
@ -31,31 +29,24 @@ class SeriesName extends PureComponent<SeriesNameProps> {
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className="legend-metric-name">{labels.__name__ || ''}</span>
|
||||
<span className="legend-metric-name">{labels!.__name__ || ''}</span>
|
||||
<span className="legend-label-brace">{'{'}</span>
|
||||
{labelNodes}
|
||||
<span className="legend-label-brace">{'}'}</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
if (labels === null) {
|
||||
return <>scalar</>;
|
||||
}
|
||||
|
||||
renderPlain() {
|
||||
const labels = this.props.labels!;
|
||||
return metricToSeriesName(labels);
|
||||
if (format) {
|
||||
return renderFormatted();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.labels === null) {
|
||||
return 'scalar';
|
||||
}
|
||||
|
||||
if (this.props.format) {
|
||||
return this.renderFormatted();
|
||||
}
|
||||
// Return a simple text node. This is much faster to scroll through
|
||||
// for longer lists (hundreds of items).
|
||||
return this.renderPlain();
|
||||
}
|
||||
}
|
||||
// Return a simple text node. This is much faster to scroll through
|
||||
// for longer lists (hundreds of items).
|
||||
return <>{metricToSeriesName(labels!)}</>;
|
||||
};
|
||||
|
||||
export default SeriesName;
|
||||
|
Loading…
Reference in New Issue
Block a user