diff --git a/web/ui/mantine-ui/src/pages/query/DataTable.tsx b/web/ui/mantine-ui/src/pages/query/DataTable.tsx index 92c0607f2..2ba6c004a 100644 --- a/web/ui/mantine-ui/src/pages/query/DataTable.tsx +++ b/web/ui/mantine-ui/src/pages/query/DataTable.tsx @@ -1,4 +1,11 @@ -import { FC, ReactNode, useEffect, useId, useState } from "react"; +import { + FC, + ReactNode, + useEffect, + useId, + useLayoutEffect, + useState, +} from "react"; import { Table, Alert, @@ -10,6 +17,7 @@ import { Group, Stack, Text, + Anchor, } from "@mantine/core"; import { IconAlertTriangle, IconInfoCircle } from "@tabler/icons-react"; import { @@ -30,12 +38,13 @@ import { useSettings } from "../../state/settingsSlice"; dayjs.extend(timezone); const maxFormattableSeries = 1000; -const maxDisplayableSeries = 10000; +const maxDisplayableSeries = 1000; const limitSeries = ( - series: S[] + series: S[], + limit: boolean ): S[] => { - if (series.length > maxDisplayableSeries) { + if (limit && series.length > maxDisplayableSeries) { return series.slice(0, maxDisplayableSeries); } return series; @@ -49,6 +58,7 @@ export interface DataTableProps { const DataTable: FC = ({ expr, evalTime, retriggerIdx }) => { const [scale, setScale] = useState("exponential"); + const [limitResults, setLimitResults] = useState(true); const { data, error, isFetching, isLoading, refetch } = useAPIQuery({ @@ -65,6 +75,10 @@ const DataTable: FC = ({ expr, evalTime, retriggerIdx }) => { expr !== "" && refetch(); }, [retriggerIdx, refetch, expr, evalTime]); + useLayoutEffect(() => { + setLimitResults(true); + }, [data, isFetching]); + const { useLocalTime } = useSettings(); // Show a skeleton only on the first load, not on subsequent ones. @@ -106,105 +120,133 @@ const DataTable: FC = ({ expr, evalTime, retriggerIdx }) => { const doFormat = result.length <= maxFormattableSeries; + console.log("rendering with", result.length, limitResults); + return ( - - , - }} - styles={{ loader: { width: "100%", height: "100%" } }} - /> - - - {resultType === "vector" ? ( - limitSeries(result).map((s, idx) => ( - - - - - - {s.value && s.value[1]} - {s.histogram && ( - - - - - - Count: {s.histogram[1].count} - - - Sum: {s.histogram[1].sum} - + <> + {limitResults && + ["vector", "matrix"].includes(resultType) && + result.length > maxDisplayableSeries && ( + } + title="Showing limited results" + > + Fetched {data.data.result.length} metrics, only displaying first{" "} + {maxDisplayableSeries} for performance reasons. + setLimitResults(false)}> + Show all results + + + )} + {!doFormat && ( + } + > + Showing more than {maxFormattableSeries} series, turning off label + formatting for performance reasons. + + )} + + , + }} + styles={{ loader: { width: "100%", height: "100%" } }} + /> +
+ + {resultType === "vector" ? ( + limitSeries(result, limitResults).map((s, idx) => ( + + + + + + {s.value && s.value[1]} + {s.histogram && ( + + + + + + Count: {s.histogram[1].count} + + + Sum: {s.histogram[1].sum} + + + + x-axis scale: + + - - x-axis scale: - - - - {histogramTable(s.histogram[1])} - - )} - + {histogramTable(s.histogram[1])} + + )} + + + )) + ) : resultType === "matrix" ? ( + limitSeries(result, limitResults).map((s, idx) => ( + + + + + + {s.values && + s.values.map((v, idx) => ( +
+ {v[1]}{" "} + + @ {v[0]} + +
+ ))} +
+
+ )) + ) : resultType === "scalar" ? ( + + Scalar value + {result[1]} - )) - ) : resultType === "matrix" ? ( - limitSeries(result).map((s, idx) => ( - - - - - - {s.values && - s.values.map((v, idx) => ( -
- {v[1]}{" "} - - @ {v[0]} - -
- ))} -
+ ) : resultType === "string" ? ( + + String value + {result[1]} - )) - ) : resultType === "scalar" ? ( - - Scalar value - {result[1]} - - ) : resultType === "string" ? ( - - String value - {result[1]} - - ) : ( - } - > - Invalid result value type - - )} -
-
-
+ ) : ( + } + > + Invalid result value type + + )} + + + + ); };