From fffb5ca1e9f0caa431ef6be1bf81ca3c9281662c Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Sat, 2 Nov 2019 21:45:22 +0100 Subject: [PATCH] React UI: More conversions to Function Components (#6259) * React UI: More conversions to Function Components Signed-off-by: Julius Volz * Address chat feedback over Riot Signed-off-by: Julius Volz --- web/ui/react-app/src/DataTable.tsx | 154 ++++++++++++++-------------- web/ui/react-app/src/Legend.tsx | 46 ++++----- web/ui/react-app/src/SeriesName.tsx | 39 +++---- 3 files changed, 109 insertions(+), 130 deletions(-) diff --git a/web/ui/react-app/src/DataTable.tsx b/web/ui/react-app/src/DataTable.tsx index 9f1a52ceb..877a60228 100644 --- a/web/ui/react-app/src/DataTable.tsx +++ b/web/ui/react-app/src/DataTable.tsx @@ -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 { - limitSeries(series: InstantSample[] | RangeSamples[]): InstantSample[] | RangeSamples[] { - const maxSeries = 10000; +const limitSeries = (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 = ({ data }) => { + if (data === null) { + return No data queried yet; } - render() { - const data = this.props.data; + if (data.result === null || data.result.length === 0) { + return Empty query result; + } - if (data === null) { - return No data queried yet; - } - - if (data.result === null || data.result.length === 0) { - return Empty query result; - } - - 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 ( - - - - - {s.value[1]} - - ); - } - ); - 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 ( - + - {valueText} + {s.value[1]} ); - }); - limited = rows.length !== data.result.length; - break; - case 'scalar': - rows.push( - - scalar - {data.result[1]} + } + ); + 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 ( + + + + + {valueText} ); - break; - case 'string': - rows.push( - - scalar - {data.result[1]} - - ); - break; - default: - return Unsupported result value type; - } - - return ( - <> - {limited && ( - - Warning: Fetched {data.result.length} metrics, only displaying first {rows.length}. - - )} - - {rows} -
- - ); + }); + limited = rows.length !== data.result.length; + break; + case 'scalar': + rows.push( + + scalar + {data.result[1]} + + ); + break; + case 'string': + rows.push( + + scalar + {data.result[1]} + + ); + break; + default: + return Unsupported result value type; } -} + + return ( + <> + {limited && ( + + Warning: Fetched {data.result.length} metrics, only displaying first {rows.length}. + + )} + + {rows} +
+ + ); +}; export default DataTable; diff --git a/web/ui/react-app/src/Legend.tsx b/web/ui/react-app/src/Legend.tsx index 88cd2c4a0..b0f60c9e1 100644 --- a/web/ui/react-app/src/Legend.tsx +++ b/web/ui/react-app/src/Legend.tsx @@ -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 { - renderLegendItem(s: any) { - return ( - - -
- - - - - - ); - } - - render() { - return ( - - - {this.props.series.map((s: any) => { - return this.renderLegendItem(s); - })} - -
- ); - } -} +const Legend: FC = ({ series }) => { + return ( + + + {series.map((s: any) => ( + + + + + ))} + +
+
+
+ +
+ ); +}; export default Legend; diff --git a/web/ui/react-app/src/SeriesName.tsx b/web/ui/react-app/src/SeriesName.tsx index edbe1d97d..370a8dfef 100644 --- a/web/ui/react-app/src/SeriesName.tsx +++ b/web/ui/react-app/src/SeriesName.tsx @@ -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 { - renderFormatted(): React.ReactNode { - const labels = this.props.labels!; - - const labelNodes: React.ReactNode[] = []; +const SeriesName: FC = ({ 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 { return ( <> - {labels.__name__ || ''} + {labels!.__name__ || ''} {'{'} {labelNodes} {'}'} ); + }; + + 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;