import { FC, ReactNode, useEffect, useId, useState } from "react"; import { Table, Alert, Skeleton, Box, LoadingOverlay, SegmentedControl, ScrollArea, Group, Stack, } from "@mantine/core"; import { IconAlertTriangle, IconInfoCircle } from "@tabler/icons-react"; import { InstantQueryResult, InstantSample, RangeSamples, } from "../../api/responseTypes/query"; import SeriesName from "./SeriesName"; import { useAPIQuery } from "../../api/api"; import classes from "./DataTable.module.css"; import dayjs from "dayjs"; import timezone from "dayjs/plugin/timezone"; import { useAppSelector } from "../../state/hooks"; import { formatTimestamp } from "../../lib/formatTime"; import HistogramChart from "./HistogramChart"; import { Histogram } from "../../types/types"; import { bucketRangeString } from "./HistogramHelpers"; dayjs.extend(timezone); const maxFormattableSeries = 1000; const maxDisplayableSeries = 10000; const limitSeries = ( series: S[] ): S[] => { if (series.length > maxDisplayableSeries) { return series.slice(0, maxDisplayableSeries); } return series; }; export interface DataTableProps { expr: string; evalTime: number | null; retriggerIdx: number; } const DataTable: FC = ({ expr, evalTime, retriggerIdx }) => { const [scale, setScale] = useState("exponential"); const { data, error, isFetching, isLoading, refetch } = useAPIQuery({ key: useId(), path: "/query", params: { query: expr, time: `${(evalTime !== null ? evalTime : Date.now()) / 1000}`, }, enabled: expr !== "", }); useEffect(() => { expr !== "" && refetch(); }, [retriggerIdx, refetch, expr, evalTime]); const useLocalTime = useAppSelector((state) => state.settings.useLocalTime); // Show a skeleton only on the first load, not on subsequent ones. if (isLoading) { return ( {Array.from(Array(5), (_, i) => ( ))} ); } if (error) { return ( } > {error.message} ); } if (data === undefined) { return No data queried yet; } const { result, resultType } = data.data; if (result.length === 0) { return ( }> This query returned no data. ); } const doFormat = result.length <= maxFormattableSeries; 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} x-axis scale: {histogramTable(s.histogram[1])} )} )) ) : resultType === "matrix" ? ( limitSeries(result).map((s, idx) => ( {s.values && s.values.map((v, idx) => (
{v[1]} @{" "} { {v[0]} }
))}
)) ) : resultType === "scalar" ? ( Scalar value {result[1]} ) : resultType === "string" ? ( String value {result[1]} ) : ( } > Invalid result value type )}
); }; const histogramTable = (h: Histogram): ReactNode => ( Bucket range Count {h.buckets?.map((b, i) => ( {bucketRangeString(b)} {b[3]} ))}
); export default DataTable;