From ea9708648434513cb543e00b745a2f4cff9570f5 Mon Sep 17 00:00:00 2001 From: machine424 Date: Fri, 15 Dec 2023 18:03:50 +0100 Subject: [PATCH 1/3] ui: create a reproduction for https://github.com/prometheus/prometheus/issues/13292 Signed-off-by: machine424 --- .../pages/graph/GraphHeatmapHelpers.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts diff --git a/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts new file mode 100644 index 0000000000..dfc7185872 --- /dev/null +++ b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts @@ -0,0 +1,27 @@ +import { isHeatmapData } from './GraphHeatmapHelpers'; + +describe('GraphHeatmapHelpers', () => { + it('isHeatmapData should return false for a vector', () => { + const data = { + resultType: 'vector', + result: [ + { + metric: { + __name__: 'my_gauge', + job: 'target', + }, + value: [1703091180.683, '6'], + }, + ], + }; + expect(isHeatmapData(data)).toBe(false); + }); + + it('isHeatmapData should return false for scalar resultType', () => { + const data = { + resultType: 'scalar', + result: [1703091180.125, '1703091180.125'], + }; + expect(isHeatmapData(data)).toBe(false); + }); +}); From c126c21baa217c9cdce55819acb6d3483f9cd572 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Thu, 4 Jan 2024 01:51:56 +0700 Subject: [PATCH 2/3] Fix DataTableProps['data'] for resultType string Signed-off-by: Kevin Mingtarja --- web/ui/react-app/src/pages/graph/DataTable.test.tsx | 4 ++-- web/ui/react-app/src/pages/graph/DataTable.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/ui/react-app/src/pages/graph/DataTable.test.tsx b/web/ui/react-app/src/pages/graph/DataTable.test.tsx index d6974cf906..1252b5bfcf 100755 --- a/web/ui/react-app/src/pages/graph/DataTable.test.tsx +++ b/web/ui/react-app/src/pages/graph/DataTable.test.tsx @@ -338,7 +338,7 @@ describe('DataTable', () => { const dataTableProps: DataTableProps = { data: { resultType: 'string', - result: 'string', + result: [1572098246.599, 'test'], }, useLocalTime: false, }; @@ -346,7 +346,7 @@ describe('DataTable', () => { it('renders a string row', () => { const table = dataTable.find(Table); const rows = table.find('tr'); - expect(rows.text()).toEqual('stringt'); + expect(rows.text()).toEqual('stringtest'); }); }); }); diff --git a/web/ui/react-app/src/pages/graph/DataTable.tsx b/web/ui/react-app/src/pages/graph/DataTable.tsx index 901d7bb48d..1885c7a80f 100644 --- a/web/ui/react-app/src/pages/graph/DataTable.tsx +++ b/web/ui/react-app/src/pages/graph/DataTable.tsx @@ -24,7 +24,7 @@ export interface DataTableProps { } | { resultType: 'string'; - result: string; + result: SampleValue; }; useLocalTime: boolean; } From 40941d450bd85a0ec31011951b40afc0101b744f Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Thu, 4 Jan 2024 02:48:54 +0700 Subject: [PATCH 3/3] Fix handling of scalar and string in isHeatmapData Signed-off-by: Kevin Mingtarja --- .../pages/graph/GraphHeatmapHelpers.test.ts | 55 ++++++++++++++++--- .../src/pages/graph/GraphHeatmapHelpers.ts | 8 ++- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts index dfc7185872..26c44be68b 100644 --- a/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts +++ b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts @@ -1,8 +1,23 @@ +import { DataTableProps } from './DataTable'; import { isHeatmapData } from './GraphHeatmapHelpers'; describe('GraphHeatmapHelpers', () => { - it('isHeatmapData should return false for a vector', () => { - const data = { + it('isHeatmapData should return false for scalar and string resultType', () => { + let data = { + resultType: 'scalar', + result: [1703091180.125, '1703091180.125'], + } as DataTableProps['data']; + expect(isHeatmapData(data)).toBe(false); + + data = { + resultType: 'string', + result: [1704305680.332, '2504'], + } as DataTableProps['data']; + expect(isHeatmapData(data)).toBe(false); + }); + + it('isHeatmapData should return false for a vector and matrix if length < 2', () => { + let data = { resultType: 'vector', result: [ { @@ -13,15 +28,39 @@ describe('GraphHeatmapHelpers', () => { value: [1703091180.683, '6'], }, ], - }; + } as DataTableProps['data']; + expect(isHeatmapData(data)).toBe(false); + + data = { + resultType: 'matrix', + result: [ + { + metric: {}, + values: [[1703091180.683, '6']], + }, + ], + } as DataTableProps['data']; expect(isHeatmapData(data)).toBe(false); }); - it('isHeatmapData should return false for scalar resultType', () => { + it('isHeatmapData should return true for valid heatmap data', () => { const data = { - resultType: 'scalar', - result: [1703091180.125, '1703091180.125'], - }; - expect(isHeatmapData(data)).toBe(false); + resultType: 'matrix', + result: [ + { + metric: { + le: '100', + }, + values: [[1703091180.683, '6']], + }, + { + metric: { + le: '1000', + }, + values: [[1703091190.683, '6.1']], + }, + ], + } as DataTableProps['data']; + expect(isHeatmapData(data)).toBe(true); }); }); diff --git a/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.ts b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.ts index d564959cb8..d8b249c308 100644 --- a/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.ts +++ b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.ts @@ -1,10 +1,12 @@ +import { DataTableProps } from './DataTable'; import { GraphProps, GraphSeries } from './Graph'; -export function isHeatmapData(data: GraphProps['data']) { - if (!data?.result?.length || data?.result?.length < 2) { +export function isHeatmapData(data: DataTableProps['data']) { + if (data?.resultType === 'scalar' || data?.resultType === 'string' || !data?.result?.length || data?.result?.length < 2) { return false; } - const result = data.result; + // Type assertion to prevent TS2349 error. + const result = data.result as GraphProps['data']['result']; const firstLabels = Object.keys(result[0].metric).filter((label) => label !== 'le'); return result.every(({ metric }) => { const labels = Object.keys(metric).filter((label) => label !== 'le');