diff --git a/CHANGELOG.md b/CHANGELOG.md index 69ca76ca8..32758f151 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog + +## 2.49.0-rc.2 / 2024-01-08 + +* [BUGFIX] UI: Fix scalar and string data type issues when querying introduced by heatmap feature. #13371 + ## 2.49.0-rc.1 / 2023-12-19 * [BUGFIX] SD: Fix Azure VM Scale Set NIC issue. #13283 diff --git a/VERSION b/VERSION index da758087a..05c0c2c41 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.49.0-rc.1 +2.49.0-rc.2 diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index a8933b8a5..92ad6b42b 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md", "dependencies": { - "@prometheus-io/lezer-promql": "0.49.0-rc.1", + "@prometheus-io/lezer-promql": "0.49.0-rc.2", "lru-cache": "^7.18.3" }, "devDependencies": { diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index ba2a1d1b2..2a27b18ef 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index 8e9b009c2..29597a88e 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "prometheus-io", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prometheus-io", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "workspaces": [ "react-app", "module/*" @@ -30,10 +30,10 @@ }, "module/codemirror-promql": { "name": "@prometheus-io/codemirror-promql", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "license": "Apache-2.0", "dependencies": { - "@prometheus-io/lezer-promql": "0.49.0-rc.1", + "@prometheus-io/lezer-promql": "0.49.0-rc.2", "lru-cache": "^7.18.3" }, "devDependencies": { @@ -70,7 +70,7 @@ }, "module/lezer-promql": { "name": "@prometheus-io/lezer-promql", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "license": "Apache-2.0", "devDependencies": { "@lezer/generator": "^1.5.1", @@ -20844,7 +20844,7 @@ }, "react-app": { "name": "@prometheus-io/app", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "dependencies": { "@codemirror/autocomplete": "^6.11.1", "@codemirror/commands": "^6.3.2", @@ -20862,7 +20862,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.49.0-rc.1", + "@prometheus-io/codemirror-promql": "0.49.0-rc.2", "bootstrap": "^4.6.2", "css.escape": "^1.5.1", "downshift": "^7.6.2", @@ -23551,7 +23551,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.49.0-rc.1", + "@prometheus-io/codemirror-promql": "0.49.0-rc.2", "@testing-library/react-hooks": "^7.0.2", "@types/enzyme": "^3.10.18", "@types/flot": "0.0.36", @@ -23602,7 +23602,7 @@ "@lezer/common": "^1.1.1", "@lezer/highlight": "^1.2.0", "@lezer/lr": "^1.3.14", - "@prometheus-io/lezer-promql": "0.49.0-rc.1", + "@prometheus-io/lezer-promql": "0.49.0-rc.2", "isomorphic-fetch": "^3.0.0", "lru-cache": "^7.18.3", "nock": "^13.4.0" diff --git a/web/ui/package.json b/web/ui/package.json index cbbf0d7ea..11a4c1ab1 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -28,5 +28,5 @@ "ts-jest": "^29.1.1", "typescript": "^4.9.5" }, - "version": "0.49.0-rc.1" + "version": "0.49.0-rc.2" } diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index 72d045031..ca94d8ed1 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.49.0-rc.1", + "version": "0.49.0-rc.2", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.11.1", @@ -19,7 +19,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.49.0-rc.1", + "@prometheus-io/codemirror-promql": "0.49.0-rc.2", "bootstrap": "^4.6.2", "css.escape": "^1.5.1", "downshift": "^7.6.2", 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 d6974cf90..1252b5bfc 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 901d7bb48..1885c7a80 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; } 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 000000000..26c44be68 --- /dev/null +++ b/web/ui/react-app/src/pages/graph/GraphHeatmapHelpers.test.ts @@ -0,0 +1,66 @@ +import { DataTableProps } from './DataTable'; +import { isHeatmapData } from './GraphHeatmapHelpers'; + +describe('GraphHeatmapHelpers', () => { + 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: [ + { + metric: { + __name__: 'my_gauge', + job: 'target', + }, + 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 true for valid heatmap data', () => { + const data = { + 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 d564959cb..d8b249c30 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');