From fb34916d1e126e8ff86803481eb1ab8ee16617fc Mon Sep 17 00:00:00 2001 From: Matias Chomicki Date: Tue, 9 Jan 2024 10:49:27 +0100 Subject: [PATCH 01/16] Logs navigation: derive current page index (#80167) * Logs navigation: derive current page index * Formatting --- .../explore/Logs/LogsNavigation.test.tsx | 37 +++++++++++++++++++ .../features/explore/Logs/LogsNavigation.tsx | 18 ++++----- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/public/app/features/explore/Logs/LogsNavigation.test.tsx b/public/app/features/explore/Logs/LogsNavigation.test.tsx index d045191b060..3e0e2178745 100644 --- a/public/app/features/explore/Logs/LogsNavigation.test.tsx +++ b/public/app/features/explore/Logs/LogsNavigation.test.tsx @@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event'; import React, { ComponentProps } from 'react'; import { LogsSortOrder } from '@grafana/data'; +import { DataQuery } from '@grafana/schema'; import LogsNavigation from './LogsNavigation'; @@ -93,6 +94,42 @@ describe('LogsNavigation', () => { expect(onChangeTimeMock).toHaveBeenCalledWith({ from: 1637319338000, to: 1637322938000 }); }); + it('should correctly display the active page', async () => { + const queries: DataQuery[] = []; + const { rerender } = setup({ + absoluteRange: { from: 1704737384139, to: 1704737684139 }, + visibleRange: { from: 1704737384207, to: 1704737683316 }, + queries, + logsSortOrder: LogsSortOrder.Descending, + }); + + expect(await screen.findByTestId('page1')).toBeInTheDocument(); + expect(screen.getByTestId('page1').firstChild).toHaveClass('selectedBg'); + + expect(screen.queryByTestId('page2')).not.toBeInTheDocument(); + + await userEvent.click(screen.getByTestId('olderLogsButton')); + + rerender( + + ); + + expect(await screen.findByTestId('page1')).toBeInTheDocument(); + expect(screen.getByTestId('page1').firstChild).not.toHaveClass('selectedBg'); + + expect(await screen.findByTestId('page2')).toBeInTheDocument(); + expect(screen.getByTestId('page2').firstChild).toHaveClass('selectedBg'); + + expect(screen.queryByTestId('page3')).not.toBeInTheDocument(); + }); + it('should reset the scroll when pagination is clicked', async () => { const scrollToTopLogsMock = jest.fn(); setup({ scrollToTopLogs: scrollToTopLogsMock }); diff --git a/public/app/features/explore/Logs/LogsNavigation.tsx b/public/app/features/explore/Logs/LogsNavigation.tsx index 0c731315dd3..f9f498a566a 100644 --- a/public/app/features/explore/Logs/LogsNavigation.tsx +++ b/public/app/features/explore/Logs/LogsNavigation.tsx @@ -1,6 +1,6 @@ import { css } from '@emotion/css'; import { isEqual } from 'lodash'; -import React, { memo, useCallback, useEffect, useRef, useState } from 'react'; +import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { AbsoluteTimeRange, GrafanaTheme2, LogsSortOrder } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; @@ -41,7 +41,6 @@ function LogsNavigation({ addResultsToCache, }: Props) { const [pages, setPages] = useState([]); - const [currentPageIndex, setCurrentPageIndex] = useState(0); // These refs are to determine, if we want to clear up logs navigation when totally new query is run const expectedQueriesRef = useRef(); @@ -50,6 +49,14 @@ function LogsNavigation({ // e.g. if last 5 min selected, always run 5 min range const rangeSpanRef = useRef(0); + const currentPageIndex = useMemo( + () => + pages.findIndex((page) => { + return page.queryRange.to === absoluteRange.to; + }), + [absoluteRange.to, pages] + ); + const oldestLogsFirst = logsSortOrder === LogsSortOrder.Ascending; const onFirstPage = oldestLogsFirst ? currentPageIndex === pages.length - 1 : currentPageIndex === 0; const onLastPage = oldestLogsFirst ? currentPageIndex === 0 : currentPageIndex === pages.length - 1; @@ -64,7 +71,6 @@ function LogsNavigation({ if (!isEqual(expectedRangeRef.current, absoluteRange) || !isEqual(expectedQueriesRef.current, queries)) { clearCache(); setPages([newPage]); - setCurrentPageIndex(0); expectedQueriesRef.current = queries; rangeSpanRef.current = absoluteRange.to - absoluteRange.from; } else { @@ -73,14 +79,8 @@ function LogsNavigation({ newPages = pages.filter((page) => !isEqual(newPage.queryRange, page.queryRange)); // Sort pages based on logsOrder so they visually align with displayed logs newPages = [...newPages, newPage].sort((a, b) => sortPages(a, b, logsSortOrder)); - // Set new pages - return newPages; }); - - // Set current page index - const index = newPages.findIndex((page) => page.queryRange.to === absoluteRange.to); - setCurrentPageIndex(index); } addResultsToCache(); }, [visibleRange, absoluteRange, logsSortOrder, queries, clearCache, addResultsToCache]); From 68ba6cc67bd9475c6a4060a90b849d3aa18153a1 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 9 Jan 2024 10:00:00 +0000 Subject: [PATCH 02/16] Chore: some type fixes (#80094) * some type fixes * few more fixes * more * fix unit test --- .betterer.results | 100 +++++------------- .../app/features/templating/template_srv.ts | 6 +- .../tempo/traceql/autocomplete.test.ts | 4 +- .../plugins/datasource/zipkin/QueryField.tsx | 2 +- .../plugins/datasource/zipkin/datasource.ts | 4 +- .../alertlist/AlertListMigrationHandler.ts | 2 +- .../panel/annolist/AnnoListPanel.test.tsx | 6 +- .../plugins/panel/annolist/AnnoListPanel.tsx | 17 +-- public/app/plugins/panel/annolist/module.tsx | 4 +- .../plugins/panel/dashlist/migrations.test.ts | 2 +- .../plugins/panel/debug/EventBusLogger.tsx | 2 +- .../app/plugins/panel/geomap/utils/layers.ts | 4 +- .../app/plugins/panel/geomap/utils/tooltip.ts | 2 +- .../app/plugins/panel/histogram/Histogram.tsx | 4 +- .../app/plugins/panel/nodeGraph/usePanning.ts | 4 +- .../app/plugins/panel/nodeGraph/utils.test.ts | 2 + public/app/plugins/panel/nodeGraph/utils.ts | 18 ++-- .../app/plugins/panel/stat/StatMigrations.ts | 2 +- public/app/plugins/panel/table-old/module.ts | 17 +-- .../plugins/panel/timeseries/migrations.ts | 4 +- .../app/plugins/panel/xychart/AutoEditor.tsx | 2 +- public/app/plugins/panel/xychart/dims.ts | 13 ++- public/test/specs/helpers.ts | 2 +- 23 files changed, 90 insertions(+), 133 deletions(-) diff --git a/.betterer.results b/.betterer.results index 24e6321e7e2..e2d8f86b1dd 100644 --- a/.betterer.results +++ b/.betterer.results @@ -4374,12 +4374,9 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], - [0, 0, 0, "Do not use any type assertions.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Do not use any type assertions.", "15"] + [0, 0, 0, "Do not use any type assertions.", "10"], + [0, 0, 0, "Do not use any type assertions.", "11"], + [0, 0, 0, "Do not use any type assertions.", "12"] ], "public/app/features/trails/SelectMetricTrailView.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -5947,24 +5944,16 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/plugins/datasource/tempo/traceql/autocomplete.test.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/plugins/datasource/zipkin/ConfigEditor.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/plugins/datasource/zipkin/QueryField.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/zipkin/datasource.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/zipkin/utils/testResponse.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6003,8 +5992,7 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/alertlist/UnifiedAlertList.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -6036,18 +6024,11 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/annolist/AnnoListPanel.test.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/annolist/AnnoListPanel.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] - ], - "public/app/plugins/panel/annolist/module.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Styles should be written using objects.", "1"] ], "public/app/plugins/panel/barchart/BarChartPanel.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -6094,9 +6075,6 @@ exports[`better eslint`] = { "public/app/plugins/panel/canvas/globalStyles.ts:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], - "public/app/plugins/panel/dashlist/migrations.test.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/panel/dashlist/styles.ts:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -6117,8 +6095,7 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/debug/EventBusLogger.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/gauge/GaugeMigrations.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -6168,8 +6145,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/geomap/utils/layers.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/panel/geomap/utils/tooltip.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -6246,9 +6222,7 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "16"] ], "public/app/plugins/panel/histogram/Histogram.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/plugins/panel/live/LiveChannelEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6330,13 +6304,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/plugins/panel/nodeGraph/usePanning.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "public/app/plugins/panel/nodeGraph/utils.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/plugins/panel/piechart/PieChart.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -6349,8 +6316,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/stat/StatMigrations.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/panel/state-timeline/migrations.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6403,14 +6369,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Unexpected any. Specify a different type.", "18"] + [0, 0, 0, "Unexpected any. Specify a different type.", "11"] ], "public/app/plugins/panel/table-old/renderer.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6485,17 +6444,15 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/timeseries/migrations.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"] + [0, 0, 0, "Do not use any type assertions.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Do not use any type assertions.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"], + [0, 0, 0, "Unexpected any. Specify a different type.", "9"] ], "public/app/plugins/panel/timeseries/plugins/ThresholdDragHandle.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -6569,14 +6526,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] ], - "public/app/plugins/panel/xychart/dims.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"] - ], "public/app/plugins/panel/xychart/scatter.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -6693,8 +6642,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"] + [0, 0, 0, "Unexpected any. Specify a different type.", "10"] ] }` }; diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index a255e9384ae..9aa3133080c 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -69,7 +69,7 @@ export class TemplateSrv implements BaseTemplateSrv { * * Use getVariables function instead */ - get variables(): any[] { + get variables(): TypedVariableModel[] { deprecationWarning('template_srv.ts', 'variables', 'getVariables'); return this.getVariables(); } @@ -84,7 +84,7 @@ export class TemplateSrv implements BaseTemplateSrv { } updateIndex() { - const existsOrEmpty = (value: any) => value || value === ''; + const existsOrEmpty = (value: unknown) => value || value === ''; this.index = this._variables.reduce((acc, currentValue) => { if (currentValue.current && (currentValue.current.isNone || existsOrEmpty(currentValue.current.value))) { @@ -360,7 +360,7 @@ export class TemplateSrv implements BaseTemplateSrv { }); } - isAllValue(value: any) { + isAllValue(value: unknown) { return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE); } diff --git a/public/app/plugins/datasource/tempo/traceql/autocomplete.test.ts b/public/app/plugins/datasource/tempo/traceql/autocomplete.test.ts index ad15cc0c95b..4b2e6b0d5f5 100644 --- a/public/app/plugins/datasource/tempo/traceql/autocomplete.test.ts +++ b/public/app/plugins/datasource/tempo/traceql/autocomplete.test.ts @@ -409,12 +409,12 @@ function setup(value: string, offset: number, tagsV1?: string[], tagsV2?: Scope[ EnumMember: 2, }, }, - } as any; + } as unknown as typeof monacoTypes; provider.editor = { getModel() { return model; }, - } as any; + } as unknown as monacoTypes.editor.IStandaloneCodeEditor; return { provider, model } as unknown as { provider: CompletionProvider; model: monacoTypes.editor.ITextModel }; } diff --git a/public/app/plugins/datasource/zipkin/QueryField.tsx b/public/app/plugins/datasource/zipkin/QueryField.tsx index df9a83970e8..3a809b72453 100644 --- a/public/app/plugins/datasource/zipkin/QueryField.tsx +++ b/public/app/plugins/datasource/zipkin/QueryField.tsx @@ -183,7 +183,7 @@ type OptionsState = { // Exported for tests export function useLoadOptions(datasource: ZipkinDatasource) { const isMounted = useMountedState(); - const [allOptions, setAllOptions] = useState({} as OptionsState); + const [allOptions, setAllOptions] = useState({}); const [, fetchSpans] = useAsyncFn( async function findSpans(service: string): Promise { diff --git a/public/app/plugins/datasource/zipkin/datasource.ts b/public/app/plugins/datasource/zipkin/datasource.ts index 6fa69c83834..4a7657335d4 100644 --- a/public/app/plugins/datasource/zipkin/datasource.ts +++ b/public/app/plugins/datasource/zipkin/datasource.ts @@ -61,7 +61,7 @@ export class ZipkinDatasource extends DataSourceApi return of(emptyDataQueryResponse); } - async metadataRequest(url: string, params?: Record): Promise { + async metadataRequest(url: string, params?: Record) { const res = await lastValueFrom(this.request(url, params, { hideFromInspector: true })); return res.data; } @@ -100,7 +100,7 @@ export class ZipkinDatasource extends DataSourceApi private request( apiUrl: string, - data?: any, + data?: unknown, options?: Partial ): Observable> { const params = data ? urlUtil.serializeParams(data) : ''; diff --git a/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts b/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts index 2fccfa8ddb5..c36cd742e89 100644 --- a/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts +++ b/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts @@ -16,7 +16,7 @@ export const alertListPanelMigrationHandler = ( tags: panel.options.tags ?? panel.dashboardTags ?? [], stateFilter: panel.options.stateFilter ?? - panel.stateFilter?.reduce((filterObj: any, curFilter: any) => ({ ...filterObj, [curFilter]: true }), {}) ?? + panel.stateFilter?.reduce((filterObj: object, curFilter: any) => ({ ...filterObj, [curFilter]: true }), {}) ?? {}, }; diff --git a/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx b/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx index f42c57ff7b7..d231be044a5 100644 --- a/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx +++ b/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx @@ -30,7 +30,7 @@ const defaultOptions: Options = { tags: ['tag A', 'tag B'], }; -const defaultResult: any = { +const defaultResult = { text: 'Result text', userId: 1, login: 'Result login', @@ -40,7 +40,7 @@ const defaultResult: any = { time: Date.UTC(2021, 0, 1, 0, 0, 0, 0), panelId: 13, dashboardId: 14, // deliberately different from panelId - id: 14, + id: '14', uid: '7MeksYbmk', dashboardUID: '7MeksYbmk', url: '/d/asdkjhajksd/some-dash', @@ -55,7 +55,7 @@ async function setupTestContext({ const getMock = jest.spyOn(backendSrv, 'get'); getMock.mockResolvedValue(results); - const dash: any = { uid: 'srx16xR4z', formatDate: (time: number) => new Date(time).toISOString() }; + const dash = { uid: 'srx16xR4z', formatDate: (time: number) => new Date(time).toISOString() }; const dashSrv: any = { getCurrent: () => dash }; setDashboardSrv(dashSrv); const pushSpy = jest.spyOn(locationService, 'push'); diff --git a/public/app/plugins/panel/annolist/AnnoListPanel.tsx b/public/app/plugins/panel/annolist/AnnoListPanel.tsx index 252e353dccc..2e637d7c3bf 100644 --- a/public/app/plugins/panel/annolist/AnnoListPanel.tsx +++ b/public/app/plugins/panel/annolist/AnnoListPanel.tsx @@ -90,7 +90,11 @@ export class AnnoListPanel extends PureComponent { const { options } = this.props; const { queryUser, queryTags } = this.state; - const params: any = { + const params: { + tags: typeof options.tags; + limit: typeof options.limit; + type: string; + } & Record = { tags: options.tags, limit: options.limit, type: 'annotation', // Skip the Annotations that are really alerts. (Use the alerts panel!) @@ -139,15 +143,12 @@ export class AnnoListPanel extends PureComponent { const dashboardSrv = getDashboardSrv(); const current = dashboardSrv.getCurrent(); - const params: any = { + const params = { from: this._timeOffset(anno.time, options.navigateBefore, true), to: this._timeOffset(anno.timeEnd ?? anno.time, options.navigateAfter, false), + viewPanel: options.navigateToPanel ? anno.panelId : undefined, }; - if (options.navigateToPanel) { - params.viewPanel = anno.panelId; - } - if (current?.uid === anno.dashboardUID) { locationService.partial(params); return; @@ -157,8 +158,8 @@ export class AnnoListPanel extends PureComponent { if (result && result.length && result[0].uid === anno.dashboardUID) { const dash = result[0]; const url = new URL(dash.url, window.location.origin); - url.searchParams.set('from', params.from); - url.searchParams.set('to', params.to); + url.searchParams.set('from', String(params.from)); + url.searchParams.set('to', String(params.to)); locationService.push(locationUtil.stripBaseFromUrl(url.toString())); return; } diff --git a/public/app/plugins/panel/annolist/module.tsx b/public/app/plugins/panel/annolist/module.tsx index d719e221fb6..e914b3fad98 100644 --- a/public/app/plugins/panel/annolist/module.tsx +++ b/public/app/plugins/panel/annolist/module.tsx @@ -95,9 +95,9 @@ export const plugin = new PanelPlugin(AnnoListPanel) }); }) // TODO, we should support this directly in the plugin infrastructure - .setPanelChangeHandler((panel: PanelModel, prevPluginId: string, prevOptions: unknown) => { + .setPanelChangeHandler((panel: PanelModel, prevPluginId, prevOptions) => { if (prevPluginId === 'ryantxu-annolist-panel') { - return prevOptions as Options; + return prevOptions; } return panel.options; diff --git a/public/app/plugins/panel/dashlist/migrations.test.ts b/public/app/plugins/panel/dashlist/migrations.test.ts index 62f1f51172a..607c5b9c7a6 100644 --- a/public/app/plugins/panel/dashlist/migrations.test.ts +++ b/public/app/plugins/panel/dashlist/migrations.test.ts @@ -19,7 +19,7 @@ describe('dashlist migrations', () => { const basePanelModel = wellFormedPanelModel({}); basePanelModel.pluginVersion = '5.1'; - const angularPanel: PanelModel & AngularModel = { + const angularPanel: PanelModel & AngularModel = { ...basePanelModel, // pluginVersion: '5.1', starred: true, diff --git a/public/app/plugins/panel/debug/EventBusLogger.tsx b/public/app/plugins/panel/debug/EventBusLogger.tsx index c13501abd61..32bedcf6bd9 100644 --- a/public/app/plugins/panel/debug/EventBusLogger.tsx +++ b/public/app/plugins/panel/debug/EventBusLogger.tsx @@ -52,7 +52,7 @@ export class EventBusLoggerPanel extends PureComponent { eventObserver: PartialObserver = { next: (event: BusEvent) => { - const origin = event.origin as any; + const origin: any = event.origin; this.history.add({ key: counter++, type: event.type, diff --git a/public/app/plugins/panel/geomap/utils/layers.ts b/public/app/plugins/panel/geomap/utils/layers.ts index 75a2357c388..834517fa7df 100644 --- a/public/app/plugins/panel/geomap/utils/layers.ts +++ b/public/app/plugins/panel/geomap/utils/layers.ts @@ -154,6 +154,6 @@ export async function initLayer( return state; } -export const getMapLayerState = (l: any) => { - return l?.__state as MapLayerState; +export const getMapLayerState = (l: any): MapLayerState => { + return l?.__state; }; diff --git a/public/app/plugins/panel/geomap/utils/tooltip.ts b/public/app/plugins/panel/geomap/utils/tooltip.ts index aeb3722a008..9ce1696fb01 100644 --- a/public/app/plugins/panel/geomap/utils/tooltip.ts +++ b/public/app/plugins/panel/geomap/utils/tooltip.ts @@ -62,7 +62,7 @@ export const pointerMoveListener = (evt: MapBrowserEvent, panel: Geo panel.map.forEachFeatureAtPixel( pixel, (feature, layer, geo) => { - const s: MapLayerState = getMapLayerState(layer); + const s = getMapLayerState(layer); //match hover layer to layer in layers //check if the layer show tooltip is enabled //then also pass the list of tooltip fields if exists diff --git a/public/app/plugins/panel/histogram/Histogram.tsx b/public/app/plugins/panel/histogram/Histogram.tsx index 29852eb5728..922d19433f9 100644 --- a/public/app/plugins/panel/histogram/Histogram.tsx +++ b/public/app/plugins/panel/histogram/Histogram.tsx @@ -287,7 +287,9 @@ export class Histogram extends React.Component { } prepState(props: HistogramProps, withConfig = true) { - let state: State = null as any; + let state: State = { + alignedData: [], + }; const { alignedFrame } = props; if (alignedFrame) { diff --git a/public/app/plugins/panel/nodeGraph/usePanning.ts b/public/app/plugins/panel/nodeGraph/usePanning.ts index 995646b15b4..41daf7daf12 100644 --- a/public/app/plugins/panel/nodeGraph/usePanning.ts +++ b/public/app/plugins/panel/nodeGraph/usePanning.ts @@ -184,10 +184,10 @@ function inBounds(value: number, min: number | undefined, max: number | undefine } // The issue here is that TouchEvent is undefined while using instanceof in Firefox and Safari -// which will throw an exception but if it's (event as TouchEvent).changedTouches it will be undefined +// which will throw an exception but if it's event.changedTouches it will be undefined // and the if check will fail so it will go to the else but will not throw an exception function getEventXY(event: Event): { x: number; y: number } { - if ((event as TouchEvent).changedTouches && event instanceof TouchEvent) { + if ('changedTouches' in event && event instanceof TouchEvent) { return { x: event.changedTouches[0].clientX, y: event.changedTouches[0].clientY }; } else if (event instanceof MouseEvent) { return { x: event.clientX, y: event.clientY }; diff --git a/public/app/plugins/panel/nodeGraph/utils.test.ts b/public/app/plugins/panel/nodeGraph/utils.test.ts index b920dfe59c8..00fcf3be24c 100644 --- a/public/app/plugins/panel/nodeGraph/utils.test.ts +++ b/public/app/plugins/panel/nodeGraph/utils.test.ts @@ -275,6 +275,7 @@ function makeNodeDatum(options: Partial = {}) { config: { color: { fixedColor: 'green', + mode: 'fixed', }, }, name: 'arc__success', @@ -285,6 +286,7 @@ function makeNodeDatum(options: Partial = {}) { config: { color: { fixedColor: 'red', + mode: 'fixed', }, }, name: 'arc__errors', diff --git a/public/app/plugins/panel/nodeGraph/utils.ts b/public/app/plugins/panel/nodeGraph/utils.ts index 728026b95d0..e634ea2581d 100644 --- a/public/app/plugins/panel/nodeGraph/utils.ts +++ b/public/app/plugins/panel/nodeGraph/utils.ts @@ -370,7 +370,7 @@ function makeNode(index: number) { } function nodesFrame() { - const fields: any = { + const fields = { [NodeGraphDataFrameFieldNames.id]: { values: [], type: FieldType.string, @@ -394,17 +394,17 @@ function nodesFrame() { [NodeGraphDataFrameFieldNames.arc + 'success']: { values: [], type: FieldType.number, - config: { color: { fixedColor: 'green' } }, + config: { color: { mode: FieldColorModeId.Fixed, fixedColor: 'green' } }, }, [NodeGraphDataFrameFieldNames.arc + 'errors']: { values: [], type: FieldType.number, - config: { color: { fixedColor: 'red' } }, + config: { color: { mode: FieldColorModeId.Fixed, fixedColor: 'red' } }, }, [NodeGraphDataFrameFieldNames.color]: { values: [], type: FieldType.number, - config: { color: { mode: 'continuous-GrYlRd' } }, + config: { color: { mode: FieldColorModeId.ContinuousGrYlRd } }, }, [NodeGraphDataFrameFieldNames.icon]: { values: [], @@ -418,8 +418,8 @@ function nodesFrame() { return new MutableDataFrame({ name: 'nodes', - fields: Object.keys(fields).map((key) => ({ - ...fields[key], + fields: Object.entries(fields).map(([key, value]) => ({ + ...value, name: key, })), }); @@ -440,7 +440,7 @@ export function makeEdgesDataFrame( } function edgesFrame() { - const fields: any = { + const fields = { [NodeGraphDataFrameFieldNames.id]: { values: [], type: FieldType.string, @@ -465,8 +465,8 @@ function edgesFrame() { return new MutableDataFrame({ name: 'edges', - fields: Object.keys(fields).map((key) => ({ - ...fields[key], + fields: Object.entries(fields).map(([key, value]) => ({ + ...value, name: key, })), }); diff --git a/public/app/plugins/panel/stat/StatMigrations.ts b/public/app/plugins/panel/stat/StatMigrations.ts index 4eb5bbdb6c8..2708ef74412 100644 --- a/public/app/plugins/panel/stat/StatMigrations.ts +++ b/public/app/plugins/panel/stat/StatMigrations.ts @@ -6,7 +6,7 @@ import { Options } from './panelcfg.gen'; // This is called when the panel changes from another panel export const statPanelChangedHandler = ( - panel: PanelModel> | any, + panel: PanelModel>, prevPluginId: string, prevOptions: any ) => { diff --git a/public/app/plugins/panel/table-old/module.ts b/public/app/plugins/panel/table-old/module.ts index e6fa9c8ca75..82d6903929e 100644 --- a/public/app/plugins/panel/table-old/module.ts +++ b/public/app/plugins/panel/table-old/module.ts @@ -1,7 +1,9 @@ +import { IScope, IAngularStatic } from 'angular'; import $ from 'jquery'; import { defaults } from 'lodash'; import { isTableData, PanelEvents, PanelPlugin } from '@grafana/data'; +import { AnnotationsSrv } from 'app/angular/services/annotations_srv'; import config from 'app/core/config'; import { applyFilterFromTable } from 'app/features/variables/adhoc/actions'; import { MetricsPanelCtrl } from 'app/plugins/sdk'; @@ -56,9 +58,9 @@ export class TablePanelCtrl extends MetricsPanelCtrl { static $inject = ['$scope', '$injector', 'annotationsSrv', '$sanitize']; constructor( - $scope: any, - $injector: any, - private annotationsSrv: any, + $scope: IScope, + $injector: IAngularStatic['injector'], + private annotationsSrv: AnnotationsSrv, private $sanitize: any ) { super($scope, $injector); @@ -101,12 +103,11 @@ export class TablePanelCtrl extends MetricsPanelCtrl { panel: this.panel, range: this.range, }) - .then((anno: any) => { + .then((anno) => { this.loading = false; this.dataRaw = anno; this.pageIndex = 0; this.render(); - return { data: this.dataRaw }; // Not used }); } @@ -170,7 +171,7 @@ export class TablePanelCtrl extends MetricsPanelCtrl { this.render(); } - link(scope: any, elem: JQuery, attrs: any, ctrl: TablePanelCtrl) { + link(scope: IScope, elem: JQuery, attrs: any, ctrl: TablePanelCtrl) { let data: any; const panel = ctrl.panel; let pageCount = 0; @@ -191,7 +192,7 @@ export class TablePanelCtrl extends MetricsPanelCtrl { tbodyElem.html(ctrl.renderer.render(ctrl.pageIndex)); } - function switchPage(e: any) { + function switchPage(e: JQueryEventObject) { const el = $(e.currentTarget); ctrl.pageIndex = parseInt(el.text(), 10) - 1; renderPanel(); @@ -263,7 +264,7 @@ export class TablePanelCtrl extends MetricsPanelCtrl { unbindDestroy(); }); - ctrl.events.on(PanelEvents.render, (renderData: any) => { + ctrl.events.on(PanelEvents.render, (renderData: unknown) => { data = renderData || data; if (data) { renderPanel(); diff --git a/public/app/plugins/panel/timeseries/migrations.ts b/public/app/plugins/panel/timeseries/migrations.ts index fa138cd89a7..eecf50a36e3 100644 --- a/public/app/plugins/panel/timeseries/migrations.ts +++ b/public/app/plugins/panel/timeseries/migrations.ts @@ -399,7 +399,7 @@ export function graphToTimeseriesOptions(angular: any): { // timeRegions migration if (angular.timeRegions?.length) { - let regions: any[] = angular.timeRegions.map((old: GraphTimeRegionConfig, idx: number) => ({ + let regions = angular.timeRegions.map((old: GraphTimeRegionConfig, idx: number) => ({ name: `T${idx + 1}`, color: old.colorMode !== 'custom' ? old.colorMode : old.fillColor, line: old.line, @@ -684,7 +684,7 @@ function validNumber(val: unknown): number | undefined { return undefined; } -function getReducersFromLegend(obj: Record): string[] { +function getReducersFromLegend(obj: Record): string[] { const ids: string[] = []; for (const key of Object.keys(obj)) { const r = fieldReducers.getIfExists(key); diff --git a/public/app/plugins/panel/xychart/AutoEditor.tsx b/public/app/plugins/panel/xychart/AutoEditor.tsx index 9048cbf9ca1..66dcd0f3209 100644 --- a/public/app/plugins/panel/xychart/AutoEditor.tsx +++ b/public/app/plugins/panel/xychart/AutoEditor.tsx @@ -45,7 +45,7 @@ export const AutoEditor = ({ value, onChange, context }: StandardEditorProps false; } const m = getSimpleFieldMatcher(f); - return (field) => !m(field, undefined as any, undefined as any); + return (field) => !m(field, { fields: [], length: 0 }, []); } diff --git a/public/test/specs/helpers.ts b/public/test/specs/helpers.ts index ebce099682d..ad14ee1d4f2 100644 --- a/public/test/specs/helpers.ts +++ b/public/test/specs/helpers.ts @@ -101,7 +101,7 @@ export function ControllerTestContext(this: any) { }); }; - this.setIsUtc = (isUtc: any = false) => { + this.setIsUtc = (isUtc = false) => { self.isUtc = isUtc; }; } From cb43246fcb843022bd40a62a7fcbef0da06c3ed8 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 9 Jan 2024 10:06:57 +0000 Subject: [PATCH 03/16] Chore: update renovate config to automerge >v1 patch updates (#80092) update renovate config to automerge >v1 patch updates --- .github/renovate.json5 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 331453813b3..3784d1c50f1 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -15,10 +15,10 @@ "postUpdateOptions": ["yarnDedupeHighest"], "packageRules": [ { + "allowedVersions": ">=1", + "automerge": true, "matchUpdateTypes": ["patch"], - "excludePackagePatterns": ["^@?storybook", "^@locker"], - "extends": ["schedule:monthly"], - "groupName": "Monthly patch updates" + "excludePackagePatterns": ["^@?storybook", "^@locker"] }, { "matchPackagePatterns": ["^@?storybook"], From 229c1f417f7d1af17b5efd17cc4864e997b020de Mon Sep 17 00:00:00 2001 From: Konrad Lalik Date: Tue, 9 Jan 2024 11:08:28 +0100 Subject: [PATCH 04/16] Alerting: Disable export all rules button when no GMA rules (#80126) Disable export button when no GMA rules --- .../alerting/unified/MoreActionsRuleButtons.tsx | 14 +++++++++++--- public/app/features/alerting/unified/RuleList.tsx | 7 +++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/public/app/features/alerting/unified/MoreActionsRuleButtons.tsx b/public/app/features/alerting/unified/MoreActionsRuleButtons.tsx index d3fd6005336..7e6754a30c5 100644 --- a/public/app/features/alerting/unified/MoreActionsRuleButtons.tsx +++ b/public/app/features/alerting/unified/MoreActionsRuleButtons.tsx @@ -10,9 +10,11 @@ import { logInfo, LogMessages } from './Analytics'; import { GrafanaRulesExporter } from './components/export/GrafanaRulesExporter'; import { AlertingAction, useAlertingAbility } from './hooks/useAbilities'; -interface Props {} +interface Props { + enableExport?: boolean; +} -export function MoreActionsRuleButtons({}: Props) { +export function MoreActionsRuleButtons({ enableExport }: Props) { const [createRuleSupported, createRuleAllowed] = useAlertingAbility(AlertingAction.CreateAlertRule); const [createCloudRuleSupported, createCloudRuleAllowed] = useAlertingAbility(AlertingAction.CreateExternalAlertRule); const [exportRulesSupported, exportRulesAllowed] = useAlertingAbility(AlertingAction.ExportGrafanaManagedRules); @@ -40,7 +42,13 @@ export function MoreActionsRuleButtons({}: Props) { if (canExportRules) { menuItems.push( - + ); } diff --git a/public/app/features/alerting/unified/RuleList.tsx b/public/app/features/alerting/unified/RuleList.tsx index dfc7078d9aa..518bf4c3df2 100644 --- a/public/app/features/alerting/unified/RuleList.tsx +++ b/public/app/features/alerting/unified/RuleList.tsx @@ -24,7 +24,7 @@ import { useFilteredRules, useRulesFilter } from './hooks/useFilteredRules'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; import { fetchAllPromAndRulerRulesAction } from './state/actions'; import { RULE_LIST_POLL_INTERVAL_MS } from './utils/constants'; -import { getAllRulesSourceNames } from './utils/datasource'; +import { getAllRulesSourceNames, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; const VIEWS = { groups: RuleListGroupView, @@ -77,6 +77,9 @@ const RuleList = withErrorBoundary( return noRules && state.dispatched; }); + const grafanaRules = useUnifiedAlertingSelector((state) => state.rulerRules[GRAFANA_RULES_SOURCE_NAME]?.result); + const hasGrafanaRules = Object.keys(grafanaRules ?? {}).length > 0; + const limitAlerts = hasActiveFilters ? undefined : LIMIT_ALERTS; // Trigger data refresh only when the RULE_LIST_POLL_INTERVAL_MS elapsed since the previous load FINISHED const [_, fetchRules] = useAsyncFn(async () => { @@ -126,7 +129,7 @@ const RuleList = withErrorBoundary( - + From adb7295babaac378b3cf09d45b0ad5459af949f6 Mon Sep 17 00:00:00 2001 From: Mihai Doarna Date: Tue, 9 Jan 2024 12:14:39 +0200 Subject: [PATCH 05/16] Auth: Send an empty http response without the json header in SSO Settings API (#80197) send an empty http response without the json header --- pkg/services/ssosettings/api/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/services/ssosettings/api/api.go b/pkg/services/ssosettings/api/api.go index 33866df7547..87b86563e1e 100644 --- a/pkg/services/ssosettings/api/api.go +++ b/pkg/services/ssosettings/api/api.go @@ -177,7 +177,7 @@ func (api *Api) updateProviderSettings(c *contextmodel.ReqContext) response.Resp return response.ErrOrFallback(http.StatusInternalServerError, "Failed to update provider settings", err) } - return response.JSON(http.StatusNoContent, nil) + return response.Respond(http.StatusNoContent, nil) } // swagger:route DELETE /v1/sso-settings/{key} sso_settings removeProviderSettings @@ -209,7 +209,7 @@ func (api *Api) removeProviderSettings(c *contextmodel.ReqContext) response.Resp return response.Error(http.StatusInternalServerError, "Failed to delete provider settings", err) } - return response.JSON(http.StatusNoContent, nil) + return response.Respond(http.StatusNoContent, nil) } // swagger:parameters getProviderSettings From 76ca1c63796ecdd421112e1d3d79dc7fa3be3fae Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 9 Jan 2024 10:35:16 +0000 Subject: [PATCH 06/16] Chore: Update lockfile resolution to newer version of `follow-redirects` (#80199) update lockfile resolution to newer version of follow-redirects --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b2dd9bedef4..e418d5a0d3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16517,12 +16517,12 @@ __metadata: linkType: hard "follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0": - version: 1.15.3 - resolution: "follow-redirects@npm:1.15.3" + version: 1.15.4 + resolution: "follow-redirects@npm:1.15.4" peerDependenciesMeta: debug: optional: true - checksum: 60d98693f4976892f8c654b16ef6d1803887a951898857ab0cdc009570b1c06314ad499505b7a040ac5b98144939f8597766e5e6a6859c0945d157b473aa6f5f + checksum: 2e8f5f259a6b02dfa8dc199e08431848a7c3beed32eb4c19945966164a52c89f07b86c3afcc32ebe4279cf0a960520e45a63013d6350309c5ec90133c5d9351a languageName: node linkType: hard From 40e4d3deb5c7cef2cc245563d6b9a1e8ad360961 Mon Sep 17 00:00:00 2001 From: Ezequiel Victorero Date: Tue, 9 Jan 2024 07:43:31 -0300 Subject: [PATCH 07/16] UI: Hide additional separator when time picker is hidden (#80168) UI: Hide additional separator when time range is hidden --- .../app/features/dashboard/components/DashNav/DashNav.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index 1cdac7b5cc6..c5629a17980 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -251,7 +251,7 @@ export const DashNav = React.memo((props) => { }; const renderRightActions = () => { - const { dashboard, onAddPanel, isFullscreen, kioskMode } = props; + const { dashboard, onAddPanel, isFullscreen, kioskMode, hideTimePicker } = props; const { canSave, canEdit, showSettings, canShare } = dashboard.meta; const { snapshot } = dashboard; const snapshotUrl = snapshot && snapshot.originalUrl; @@ -335,7 +335,10 @@ export const DashNav = React.memo((props) => { buttons.push(); } - buttons.push(); + // if the timepicker is hidden, we don't need to add this separator + if (!hideTimePicker) { + buttons.push(); + } buttons.push(renderTimeControls()); From 0f8d4db934a0428afc1e6142be3b32a3f9b45b20 Mon Sep 17 00:00:00 2001 From: Sven Grossmann Date: Tue, 9 Jan 2024 11:56:48 +0100 Subject: [PATCH 08/16] Log Context: Add highlighted words to log rows (#80119) * Log Context: Add highlighted words to log rows * Update public/app/features/logs/components/log-context/LogRowContextModal.tsx Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> --------- Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> --- .../log-context/LogRowContextModal.test.tsx | 111 ++++++++++++++++++ .../log-context/LogRowContextModal.tsx | 5 +- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/public/app/features/logs/components/log-context/LogRowContextModal.test.tsx b/public/app/features/logs/components/log-context/LogRowContextModal.test.tsx index f36f51b8ad3..a7995848129 100644 --- a/public/app/features/logs/components/log-context/LogRowContextModal.test.tsx +++ b/public/app/features/logs/components/log-context/LogRowContextModal.test.tsx @@ -292,6 +292,117 @@ describe('LogRowContextModal', () => { }); }); + it('should highlight the same `foo123` searchwords', async () => { + const dfBeforeNs = createDataFrame({ + fields: [ + { + name: 'time', + type: FieldType.time, + values: [1, 1], + }, + { + name: 'message', + type: FieldType.string, + values: ['this contains foo123', 'this contains foo123'], + }, + { + name: 'tsNs', + type: FieldType.string, + values: ['1', '2'], + }, + ], + }); + const dfNowNs = createDataFrame({ + fields: [ + { + name: 'time', + type: FieldType.time, + values: [1], + }, + { + name: 'message', + type: FieldType.string, + values: ['this contains foo123'], + }, + { + name: 'tsNs', + type: FieldType.string, + values: ['2'], + }, + ], + }); + const dfAfterNs = createDataFrame({ + fields: [ + { + name: 'time', + type: FieldType.time, + values: [1, 1], + }, + { + name: 'message', + type: FieldType.string, + values: ['this contains foo123', 'this contains foo123'], + }, + { + name: 'tsNs', + type: FieldType.string, + values: ['2', '3'], + }, + ], + }); + + let uniqueRefIdCounter = 1; + const logs = dataFrameToLogsModel([dfNowNs]); + const row = logs.rows[0]; + row.searchWords = ['foo123']; + const getRowContext = jest.fn().mockImplementation(async (_, options) => { + uniqueRefIdCounter += 1; + const refId = `refid_${uniqueRefIdCounter}`; + if (uniqueRefIdCounter === 2) { + return { + data: [ + { + refId, + ...dfBeforeNs, + }, + ], + }; + } else if (uniqueRefIdCounter === 3) { + return { + data: [ + { + refId, + ...dfAfterNs, + }, + ], + }; + } + return { data: [] }; + }); + + render( + {}} + getRowContext={getRowContext} + timeZone={timeZone} + logsSortOrder={LogsSortOrder.Descending} + /> + ); + + // there need to be 3 lines with that message, all `foo123` should be highlighted + await waitFor(() => { + expect(screen.getAllByText('foo123').length).toBe(3); + for (const el of screen.getAllByText('foo123')) { + // highlights are done in `` tags + expect(el.tagName).toBe('MARK'); + } + // test that the rest is not in a MARK + expect(screen.getAllByText('this contains')[0].tagName).not.toBe('MARK'); + }); + }); + it('should show a split view button', async () => { const getRowContextQuery = jest.fn().mockResolvedValue({ datasource: { uid: 'test-uid' } }); diff --git a/public/app/features/logs/components/log-context/LogRowContextModal.tsx b/public/app/features/logs/components/log-context/LogRowContextModal.tsx index 0759c8ac287..8daf1cb5edd 100644 --- a/public/app/features/logs/components/log-context/LogRowContextModal.tsx +++ b/public/app/features/logs/components/log-context/LogRowContextModal.tsx @@ -363,7 +363,10 @@ export const LogRowContextModal: React.FunctionComponent + // apply the original row's searchWords to all the rows for highlighting + !r.searchWords || !r.searchWords?.length ? { ...r, searchWords: row.searchWords } : r + ); const [older, newer] = partition(newRows, (newRow) => newRow.timeEpochNs > row.timeEpochNs); const newAbove = logsSortOrder === LogsSortOrder.Ascending ? newer : older; const newBelow = logsSortOrder === LogsSortOrder.Ascending ? older : newer; From 58f4533382b854ced975579e55f284da38fc5f54 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 9 Jan 2024 11:00:46 +0000 Subject: [PATCH 09/16] Chore: Better renovate config (#80202) * better config * allow react-hook-form updates --- .github/renovate.json5 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 3784d1c50f1..81146e045c2 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -7,7 +7,6 @@ "history", // we should bump this together with react-router-dom (see https://github.com/grafana/grafana/issues/76744) "react-router-dom", // we should bump this together with history (see https://github.com/grafana/grafana/issues/76744) "monaco-editor", // due to us exposing this via @grafana/ui/CodeEditor's props bumping can break plugins - "react-hook-form", // due to us exposing these hooks via @grafana/ui form components bumping can break plugins ], "includePaths": ["package.json", "packages/**", "public/app/plugins/**"], "ignorePaths": ["emails/**", "plugins-bundled/**", "**/mocks/**", "packages/grafana-e2e/**"], @@ -15,8 +14,8 @@ "postUpdateOptions": ["yarnDedupeHighest"], "packageRules": [ { - "allowedVersions": ">=1", "automerge": true, + "matchCurrentVersion": "!/^0/", "matchUpdateTypes": ["patch"], "excludePackagePatterns": ["^@?storybook", "^@locker"] }, From 314cdaf618cf54ba46b8b3109475196aeb3c495f Mon Sep 17 00:00:00 2001 From: Joey <90795735+joey-grafana@users.noreply.github.com> Date: Tue, 9 Jan 2024 11:40:39 +0000 Subject: [PATCH 10/16] Pyroscope: Decouple frontend (#80066) * Decouple query options * Decouple Variable support * Fix after merge --- .../QueryEditor/QueryOptionGroup.tsx | 82 +++++++++++++++++++ .../QueryEditor/QueryOptions.tsx | 2 +- .../VariableSupport.ts | 19 ++--- 3 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx new file mode 100644 index 00000000000..dfd42c81bf5 --- /dev/null +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptionGroup.tsx @@ -0,0 +1,82 @@ +import { css } from '@emotion/css'; +import React from 'react'; +import { useToggle } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Collapse, useStyles2, Stack } from '@grafana/ui'; + +export interface Props { + title: string; + collapsedInfo: string[]; + children: React.ReactNode; +} + +export function QueryOptionGroup({ title, children, collapsedInfo }: Props) { + const [isOpen, toggleOpen] = useToggle(false); + const styles = useStyles2(getStyles); + + return ( +
+ +
{title}
+ {!isOpen && ( +
+ {collapsedInfo.map((x, i) => ( + {x} + ))} +
+ )} + + } + > +
{children}
+
+
+ ); +} + +const getStyles = (theme: GrafanaTheme2) => { + return { + collapse: css({ + backgroundColor: 'unset', + border: 'unset', + marginBottom: 0, + + ['> button']: { + padding: theme.spacing(0, 1), + }, + }), + wrapper: css({ + width: '100%', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'baseline', + }), + title: css({ + flexGrow: 1, + overflow: 'hidden', + fontSize: theme.typography.bodySmall.fontSize, + fontWeight: theme.typography.fontWeightMedium, + margin: 0, + }), + description: css({ + color: theme.colors.text.secondary, + fontSize: theme.typography.bodySmall.fontSize, + fontWeight: theme.typography.bodySmall.fontWeight, + paddingLeft: theme.spacing(2), + gap: theme.spacing(2), + display: 'flex', + }), + body: css({ + display: 'flex', + gap: theme.spacing(2), + flexWrap: 'wrap', + }), + }; +}; diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptions.tsx b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptions.tsx index 71a4a7f1f88..b31b6d42281 100644 --- a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptions.tsx +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptions.tsx @@ -5,10 +5,10 @@ import { CoreApp, GrafanaTheme2, SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; import { useStyles2, RadioButtonGroup, MultiSelect, Input } from '@grafana/ui'; -import { QueryOptionGroup } from '../../prometheus/querybuilder/shared/QueryOptionGroup'; import { Query } from '../types'; import { EditorField } from './EditorField'; +import { QueryOptionGroup } from './QueryOptionGroup'; import { Stack } from './Stack'; export interface Props { diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/VariableSupport.ts b/public/app/plugins/datasource/grafana-pyroscope-datasource/VariableSupport.ts index 80038991d82..99a3e24a394 100644 --- a/public/app/plugins/datasource/grafana-pyroscope-datasource/VariableSupport.ts +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/VariableSupport.ts @@ -2,8 +2,6 @@ import { from, map, Observable, of } from 'rxjs'; import { CustomVariableSupport, DataQueryRequest, DataQueryResponse, MetricFindValue } from '@grafana/data'; -import { getTimeSrv, TimeSrv } from '../../../features/dashboard/services/TimeSrv'; - import { VariableQueryEditor } from './VariableQueryEditor'; import { PyroscopeDataSource } from './datasource'; import { ProfileTypeMessage, VariableQuery } from './types'; @@ -15,10 +13,7 @@ export interface DataAPI { } export class VariableSupport extends CustomVariableSupport { - constructor( - private readonly dataAPI: DataAPI, - private readonly timeSrv: TimeSrv = getTimeSrv() - ) { + constructor(private readonly dataAPI: DataAPI) { super(); } @@ -26,9 +21,7 @@ export class VariableSupport extends CustomVariableSupport query(request: DataQueryRequest): Observable { if (request.targets[0].type === 'profileType') { - return from( - this.dataAPI.getProfileTypes(this.timeSrv.timeRange().from.valueOf(), this.timeSrv.timeRange().to.valueOf()) - ).pipe( + return from(this.dataAPI.getProfileTypes(request.range.from.valueOf(), request.range.to.valueOf())).pipe( map((values) => { return { data: values.map((v) => ({ text: v.label, value: v.id })) }; }) @@ -42,8 +35,8 @@ export class VariableSupport extends CustomVariableSupport return from( this.dataAPI.getLabelNames( request.targets[0].profileTypeId + '{}', - this.timeSrv.timeRange().from.valueOf(), - this.timeSrv.timeRange().to.valueOf() + request.range.from.valueOf(), + request.range.to.valueOf() ) ).pipe( map((values) => { @@ -60,8 +53,8 @@ export class VariableSupport extends CustomVariableSupport this.dataAPI.getLabelValues( request.targets[0].profileTypeId + '{}', request.targets[0].labelName, - this.timeSrv.timeRange().from.valueOf(), - this.timeSrv.timeRange().to.valueOf() + request.range.from.valueOf(), + request.range.to.valueOf() ) ).pipe( map((values) => { From c045a9f3954f34d75e1c155fc0935e07eb5ad905 Mon Sep 17 00:00:00 2001 From: Giuseppe Guerra Date: Tue, 9 Jan 2024 14:23:03 +0100 Subject: [PATCH 11/16] Plugins: Fix symlinks inside plugins path not being followed (#80205) * Plugins: Loader: Fix symlinks not followed when loading external plugins * Add test case --- pkg/plugins/manager/sources/sources.go | 2 +- pkg/plugins/manager/sources/sources_test.go | 37 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/pkg/plugins/manager/sources/sources.go b/pkg/plugins/manager/sources/sources.go index 01de0145f30..2693bcd74b6 100644 --- a/pkg/plugins/manager/sources/sources.go +++ b/pkg/plugins/manager/sources/sources.go @@ -51,7 +51,7 @@ func (s *Service) externalPluginSources() []plugins.PluginSource { var pluginDirs []string for _, dir := range d { - if dir.IsDir() { + if dir.IsDir() || dir.Type()&os.ModeSymlink == os.ModeSymlink { pluginDirs = append(pluginDirs, filepath.Join(pluginsPath, dir.Name())) } } diff --git a/pkg/plugins/manager/sources/sources_test.go b/pkg/plugins/manager/sources/sources_test.go index 433bc25d665..f4a941ddf0b 100644 --- a/pkg/plugins/manager/sources/sources_test.go +++ b/pkg/plugins/manager/sources/sources_test.go @@ -78,4 +78,41 @@ func TestSources_List(t *testing.T) { require.False(t, exists) require.Equal(t, plugins.Signature{}, sig) }) + + t.Run("Plugin sources are populated with symbolic links", func(t *testing.T) { + testdata, err := filepath.Abs("../testdata") + require.NoError(t, err) + + cfg := &setting.Cfg{ + StaticRootPath: testdata, + PluginsPath: filepath.Join(testdata, "symbolic-plugin-dirs"), + BundledPluginsPath: filepath.Join(testdata, "unsigned-panel"), + } + s := ProvideService(cfg) + ctx := context.Background() + srcs := s.List(ctx) + uris := map[plugins.Class]map[string]struct{}{} + for _, s := range srcs { + class := s.PluginClass(ctx) + if _, exists := uris[class]; !exists { + uris[class] = map[string]struct{}{} + } + for _, uri := range s.PluginURIs(ctx) { + uris[class][uri] = struct{}{} + } + } + + require.Equal(t, uris[plugins.ClassCore], map[string]struct{}{ + filepath.Join(testdata, "app", "plugins", "datasource"): {}, + filepath.Join(testdata, "app", "plugins", "panel"): {}, + }, "should include core plugins") + + require.Equal(t, uris[plugins.ClassBundled], map[string]struct{}{ + filepath.Join(testdata, "unsigned-panel"): {}, + }, "should include bundle plugin") + + require.Equal(t, uris[plugins.ClassExternal], map[string]struct{}{ + filepath.Join(testdata, "symbolic-plugin-dirs", "plugin"): {}, + }, "should include external symlinked plugin") + }) } From 3332562900bdebd9ee9abc65b76ee8c91b477b5f Mon Sep 17 00:00:00 2001 From: Mihai Doarna Date: Tue, 9 Jan 2024 15:27:55 +0200 Subject: [PATCH 12/16] Auth: use Empty() for sending empty http responses in SSO Settings API (#80200) use Empty() for sending empty http response --- pkg/services/ssosettings/api/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/services/ssosettings/api/api.go b/pkg/services/ssosettings/api/api.go index 87b86563e1e..9794b08468a 100644 --- a/pkg/services/ssosettings/api/api.go +++ b/pkg/services/ssosettings/api/api.go @@ -177,7 +177,7 @@ func (api *Api) updateProviderSettings(c *contextmodel.ReqContext) response.Resp return response.ErrOrFallback(http.StatusInternalServerError, "Failed to update provider settings", err) } - return response.Respond(http.StatusNoContent, nil) + return response.Empty(http.StatusNoContent) } // swagger:route DELETE /v1/sso-settings/{key} sso_settings removeProviderSettings @@ -209,7 +209,7 @@ func (api *Api) removeProviderSettings(c *contextmodel.ReqContext) response.Resp return response.Error(http.StatusInternalServerError, "Failed to delete provider settings", err) } - return response.Respond(http.StatusNoContent, nil) + return response.Empty(http.StatusNoContent) } // swagger:parameters getProviderSettings From ecc667c9a55d35fe4240e7609724365e2e6a708d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Tue, 9 Jan 2024 15:54:21 +0100 Subject: [PATCH 13/16] postgres: add snapshot tests (#79794) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * postgres: add snapshot tests * fixed wrong comment Co-authored-by: Zoltán Bedi --------- Co-authored-by: Zoltán Bedi --- .../postgres_snapshot_test.go | 205 +++++++++++++++ .../testdata/table/simple.golden.jsonc | 112 ++++++++ .../testdata/table/simple.sql | 18 ++ .../timestamp_convert_bigint.golden.jsonc | 113 ++++++++ .../table/timestamp_convert_bigint.sql | 14 + .../timestamp_convert_integer.golden.jsonc | 92 +++++++ .../table/timestamp_convert_integer.sql | 12 + .../testdata/table/types_char.golden.jsonc | 140 ++++++++++ .../testdata/table/types_char.sql | 16 ++ .../table/types_datetime.golden.jsonc | 226 ++++++++++++++++ .../testdata/table/types_datetime.sql | 44 ++++ .../testdata/table/types_numeric.golden.jsonc | 188 ++++++++++++++ .../testdata/table/types_numeric.sql | 20 ++ .../testdata/table/types_other.golden.jsonc | 123 +++++++++ .../testdata/table/types_other.sql | 15 ++ .../7x_compat_metric_label.golden.jsonc | 93 +++++++ .../time_series/7x_compat_metric_label.sql | 19 ++ .../convert_to_float64.golden.jsonc | 245 ++++++++++++++++++ .../time_series/convert_to_float64.sql | 30 +++ .../time_series/fill_null.golden.jsonc | 107 ++++++++ .../testdata/time_series/fill_null.sql | 15 ++ .../time_series/fill_previous.golden.jsonc | 107 ++++++++ .../testdata/time_series/fill_previous.sql | 15 ++ .../time_series/fill_value.golden.jsonc | 107 ++++++++ .../testdata/time_series/fill_value.sql | 15 ++ .../testdata/time_series/simple.golden.jsonc | 99 +++++++ .../testdata/time_series/simple.sql | 18 ++ 27 files changed, 2208 insertions(+) create mode 100644 pkg/tsdb/grafana-postgresql-datasource/postgres_snapshot_test.go create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.sql create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.golden.jsonc create mode 100644 pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.sql diff --git a/pkg/tsdb/grafana-postgresql-datasource/postgres_snapshot_test.go b/pkg/tsdb/grafana-postgresql-datasource/postgres_snapshot_test.go new file mode 100644 index 00000000000..11d82425164 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/postgres_snapshot_test.go @@ -0,0 +1,205 @@ +package postgres + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "testing" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" + "github.com/grafana/grafana-plugin-sdk-go/experimental" + "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/tsdb/sqleng" + + _ "github.com/lib/pq" +) + +var updateGoldenFiles = false + +// These tests require a real postgres database: +// - make devenv sources=potgres_tests +// - either set the env variable GRAFANA_TEST_DB = postgres +// - or set `forceRun := true` below +// +// The tests require a PostgreSQL db named grafanadstest and a user/password grafanatest/grafanatest! +// Use the docker/blocks/postgres_tests/docker-compose.yaml to spin up a +// preconfigured Postgres server suitable for running these tests. +func TestIntegrationPostgresSnapshots(t *testing.T) { + // the logic in this function is copied from postgres_tests.go + shouldRunTest := func() bool { + if testing.Short() { + return false + } + + testDbName, present := os.LookupEnv("GRAFANA_TEST_DB") + + if present && testDbName == "postgres" { + return true + } + + return false + } + + if !shouldRunTest() { + t.Skip() + } + + openDB := func() *sql.DB { + host := os.Getenv("POSTGRES_HOST") + if host == "" { + host = "localhost" + } + port := os.Getenv("POSTGRES_PORT") + if port == "" { + port = "5432" + } + + connStr := fmt.Sprintf("user=grafanatest password=grafanatest host=%s port=%s dbname=grafanadstest sslmode=disable", + host, port) + + db, err := sql.Open("postgres", connStr) + require.NoError(t, err) + return db + } + + sqlQueryCommentRe := regexp.MustCompile(`^-- (.+)\n`) + + readSqlFile := func(path string) (string, string) { + // the file-path is not coming from the outside, + // it is hardcoded in this file. + //nolint:gosec + sqlBytes, err := os.ReadFile(path) + require.NoError(t, err) + + sql := string(sqlBytes) + + // first line of the file contains the sql query to run, commented out + match := sqlQueryCommentRe.FindStringSubmatch(sql) + require.Len(t, match, 2) + + rawSQL := strings.TrimSpace(match[1]) + + return rawSQL, sql + } + + makeQuery := func(rawSQL string, format string) backend.QueryDataRequest { + queryData := map[string]string{ + "rawSql": rawSQL, + "format": format, + } + + queryBytes, err := json.Marshal(queryData) + require.NoError(t, err) + + return backend.QueryDataRequest{ + Queries: []backend.DataQuery{ + { + JSON: queryBytes, + RefID: "A", + TimeRange: backend.TimeRange{ + From: time.Date(2023, 12, 24, 14, 15, 0, 0, time.UTC), + To: time.Date(2023, 12, 24, 14, 45, 0, 0, time.UTC), + }, + }, + }, + } + } + + tt := []struct { + name string + format string + }{ + {format: "time_series", name: "simple"}, + {format: "time_series", name: "7x_compat_metric_label"}, + {format: "time_series", name: "convert_to_float64"}, + {format: "time_series", name: "fill_null"}, + {format: "time_series", name: "fill_previous"}, + {format: "time_series", name: "fill_value"}, + {format: "table", name: "simple"}, + {format: "table", name: "types_numeric"}, + {format: "table", name: "types_char"}, + {format: "table", name: "types_datetime"}, + {format: "table", name: "types_other"}, + {format: "table", name: "timestamp_convert_bigint"}, + {format: "table", name: "timestamp_convert_integer"}, + } + + for _, test := range tt { + require.True(t, test.format == "table" || test.format == "time_series") + t.Run(test.name, func(t *testing.T) { + origInterpolate := sqleng.Interpolate + t.Cleanup(func() { + sqleng.Interpolate = origInterpolate + }) + + sqleng.Interpolate = func(query backend.DataQuery, timeRange backend.TimeRange, timeInterval string, sql string) (string, error) { + return sql, nil + } + + db := openDB() + + t.Cleanup((func() { + _, err := db.Exec("DROP TABLE tbl") + require.NoError(t, err) + err = db.Close() + require.NoError(t, err) + })) + + cfg := setting.NewCfg() + cfg.DataPath = t.TempDir() + + jsonData := sqleng.JsonData{ + MaxOpenConns: 0, + MaxIdleConns: 2, + ConnMaxLifetime: 14400, + Timescaledb: false, + ConfigurationMethod: "file-path", + } + + dsInfo := sqleng.DataSourceInfo{ + JsonData: jsonData, + DecryptedSecureJSONData: map[string]string{}, + } + + config := sqleng.DataPluginConfiguration{ + DSInfo: dsInfo, + MetricColumnTypes: []string{"UNKNOWN", "TEXT", "VARCHAR", "CHAR"}, + RowLimit: 1000000, + } + + queryResultTransformer := postgresQueryResultTransformer{} + + logger := log.New() + handler, err := sqleng.NewQueryDataHandler(cfg, db, config, &queryResultTransformer, newPostgresMacroEngine(dsInfo.JsonData.Timescaledb), + logger) + + require.NoError(t, err) + + sqlFilePath := filepath.Join("testdata", test.format, test.name+".sql") + goldenFileName := filepath.Join(test.format, test.name+".golden") + + rawSQL, sql := readSqlFile(sqlFilePath) + + _, err = db.Exec(sql) + require.NoError(t, err) + + query := makeQuery(rawSQL, test.format) + + result, err := handler.QueryData(context.Background(), &query) + require.Len(t, result.Responses, 1) + response, found := result.Responses["A"] + require.True(t, found) + require.NoError(t, err) + experimental.CheckGoldenJSONResponse(t, "testdata", goldenFileName, &response, updateGoldenFiles) + }) + } +} diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.golden.jsonc new file mode 100644 index 00000000000..68803e3e77e --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.golden.jsonc @@ -0,0 +1,112 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 10 Rows +// +-------------------------------+------------------+-----------------+ +// | Name: time | Name: v | Name: c | +// | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*float64 | Type: []*string | +// +-------------------------------+------------------+-----------------+ +// | 2023-12-24 14:30:03 +0000 UTC | 10 | a | +// | 2023-12-24 14:30:03 +0000 UTC | 110 | b | +// | 2023-12-24 14:31:03 +0000 UTC | 20 | a | +// | 2023-12-24 14:31:03 +0000 UTC | 120 | b | +// | 2023-12-24 14:32:03 +0000 UTC | 30 | a | +// | 2023-12-24 14:32:03 +0000 UTC | 130 | b | +// | 2023-12-24 14:33:03 +0000 UTC | 40 | a | +// | 2023-12-24 14:33:03 +0000 UTC | 140 | b | +// | 2023-12-24 14:34:03 +0000 UTC | 50 | a | +// | 2023-12-24 14:34:03 +0000 UTC | 150 | b | +// +-------------------------------+------------------+-----------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "c", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703428203000, + 1703428203000, + 1703428263000, + 1703428263000, + 1703428323000, + 1703428323000, + 1703428383000, + 1703428383000, + 1703428443000, + 1703428443000 + ], + [ + 10, + 110, + 20, + 120, + 30, + 130, + 40, + 140, + 50, + 150 + ], + [ + "a", + "b", + "a", + "b", + "a", + "b", + "a", + "b", + "a", + "b" + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.sql new file mode 100644 index 00000000000..b89651e591d --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/simple.sql @@ -0,0 +1,18 @@ +-- SELECT * FROM tbl +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v double precision, + c text +); + +INSERT INTO tbl ("time", v, c) VALUES +('2023-12-24 14:30:03 UTC', 10, 'a'), +('2023-12-24 14:30:03 UTC', 110, 'b'), +('2023-12-24 14:31:03 UTC', 20, 'a'), +('2023-12-24 14:31:03 UTC', 120, 'b'), +('2023-12-24 14:32:03 UTC', 30, 'a'), +('2023-12-24 14:32:03 UTC', 130, 'b'), +('2023-12-24 14:33:03 UTC', 40, 'a'), +('2023-12-24 14:33:03 UTC', 140, 'b'), +('2023-12-24 14:34:03 UTC', 50, 'a'), +('2023-12-24 14:34:03 UTC', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.golden.jsonc new file mode 100644 index 00000000000..091a0cba0d1 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.golden.jsonc @@ -0,0 +1,113 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 4 Fields by 4 Rows +// +--------------------------------------+-----------------------------------+---------------------+-----------------------------------+ +// | Name: reallyt | Name: time | Name: n | Name: timeend | +// | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*int64 | Type: []*time.Time | +// +--------------------------------------+-----------------------------------+---------------------+-----------------------------------+ +// | 2023-12-24 14:21:27 +0000 UTC | 2023-12-21 13:21:27 +0100 CET | 1703161287 | 2023-12-21 13:21:52 +0100 CET | +// | 2023-12-24 14:21:27.724 +0000 UTC | 2023-12-21 13:21:27.724 +0100 CET | 1703161287724 | 2023-12-21 13:21:52.522 +0100 CET | +// | 2023-12-24 14:21:27.724919 +0000 UTC | 2023-12-21 13:21:27.724 +0100 CET | 1703161287724919000 | 2023-12-21 13:21:52.522 +0100 CET | +// | null | null | null | null | +// +--------------------------------------+-----------------------------------+---------------------+-----------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "reallyt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "timeend", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703427687000, + 1703427687724, + 1703427687724, + null + ], + [ + 1703161287000, + 1703161287724, + 1703161287724, + null + ], + [ + 1703161287, + 1703161287724, + 1703161287724919000, + null + ], + [ + 1703161312000, + 1703161312522, + 1703161312522, + null + ] + ], + "nanos": [ + [ + 0, + 0, + 919000, + 0 + ], + null, + null, + null + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.sql new file mode 100644 index 00000000000..7d0764270ec --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_bigint.sql @@ -0,0 +1,14 @@ +-- SELECT * FROM tbl +-- the time-field and time-end field gets converted to time.Time +CREATE TEMPORARY TABLE tbl ( + reallyt timestamp with time zone, -- reference real timestamp + "time" bigint, + n bigint, -- normal number, it should not get converted to a timestamp + timeend bigint +); + +INSERT INTO tbl (reallyt, "time", n, timeend) VALUES +('2023-12-24T14:21:27 UTC', 1703161287, 1703161287, 1703161312), +('2023-12-24T14:21:27.724 UTC', 1703161287724, 1703161287724, 1703161312522), +('2023-12-24T14:21:27.724919 UTC', 1703161287724919000, 1703161287724919000, 1703161312522186000), +(NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.golden.jsonc new file mode 100644 index 00000000000..afee29019e5 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.golden.jsonc @@ -0,0 +1,92 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 4 Fields by 2 Rows +// +-------------------------------+-------------------------------+----------------+-------------------------------+ +// | Name: reallyt | Name: time | Name: n | Name: timeend | +// | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*int32 | Type: []*time.Time | +// +-------------------------------+-------------------------------+----------------+-------------------------------+ +// | 2023-12-24 14:21:27 +0000 UTC | 2023-12-21 13:21:27 +0100 CET | 1703161287 | 2023-12-21 13:21:52 +0100 CET | +// | null | null | null | null | +// +-------------------------------+-------------------------------+----------------+-------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "reallyt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "int32", + "nullable": true + } + }, + { + "name": "timeend", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703427687000, + null + ], + [ + 1703161287000, + null + ], + [ + 1703161287, + null + ], + [ + 1703161312000, + null + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.sql new file mode 100644 index 00000000000..0d45dd898c8 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/timestamp_convert_integer.sql @@ -0,0 +1,12 @@ +-- SELECT * FROM tbl +-- the time-field and time-end field gets converted to time.Time +CREATE TEMPORARY TABLE tbl ( + reallyt timestamp with time zone, -- reference real timestamp + "time" integer, -- 32bits, seconds-as-number is highest we can go, milliseconds-as-number does not fit + n integer, -- normal number, it should not get converted to a timestamp + timeend integer +); + +INSERT INTO tbl (reallyt, "time", n, timeend) VALUES +('2023-12-24T14:21:27 UTC', 1703161287, 1703161287, 1703161312), +(NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.golden.jsonc new file mode 100644 index 00000000000..fb9afae7675 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.golden.jsonc @@ -0,0 +1,140 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 8 Fields by 2 Rows +// +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+ +// | Name: cv | Name: cvnn | Name: c | Name: cnn | Name: bpc | Name: bpcnn | Name: t | Name: tnn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | +// +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+ +// | one | two | three | four | five | six | seven | eight | +// | null | xtwo | null | xfour | null | xsix | null | xeight | +// +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "cv", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "cvnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "c", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "cnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "bpc", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "bpcnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "t", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "tnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + "one", + null + ], + [ + "two", + "xtwo" + ], + [ + "three ", + null + ], + [ + "four ", + "xfour " + ], + [ + "five", + null + ], + [ + "six", + "xsix" + ], + [ + "seven", + null + ], + [ + "eight", + "xeight" + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.sql new file mode 100644 index 00000000000..34551aa9442 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_char.sql @@ -0,0 +1,16 @@ +-- SELECT * FROM tbl +-- test all character-based postgres data types +CREATE TEMPORARY TABLE tbl ( + cv character varying(10), + cvnn character varying(10) NOT NULL, + c character(10), + cnn character(10) NOT NULL, + bpc bpchar, + bpcnn bpchar NOT NULL, + t text, + tnn text NOT NULL +); + +INSERT INTO tbl (cv, cvnn, c, cnn, bpc, bpcnn, t, tnn) VALUES +('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'), +(NULL, 'xtwo', NULL, 'xfour', NULL, 'xsix', NULL, 'xeight'); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.golden.jsonc new file mode 100644 index 00000000000..48e55e7b077 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.golden.jsonc @@ -0,0 +1,226 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 12 Fields by 2 Rows +// +----------------------------------------+----------------------------------------+--------------------------------------+--------------------------------------+---------------------------------+---------------------------------+--------------------------------------+--------------------------------------+----------------------------------------+----------------------------------------+-----------------+-----------------+ +// | Name: ts | Name: tsnn | Name: tsz | Name: tsznn | Name: d | Name: dnn | Name: t | Name: tnn | Name: tz | Name: tznn | Name: i | Name: inn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*string | Type: []*string | +// +----------------------------------------+----------------------------------------+--------------------------------------+--------------------------------------+---------------------------------+---------------------------------+--------------------------------------+--------------------------------------+----------------------------------------+----------------------------------------+-----------------+-----------------+ +// | 2023-11-15 05:06:07.123456 +0000 +0000 | 2023-11-15 05:06:08.123456 +0000 +0000 | 2021-07-22 11:22:33.654321 +0000 UTC | 2021-07-22 11:22:34.654321 +0000 UTC | 2023-12-20 00:00:00 +0000 +0000 | 2023-12-21 00:00:00 +0000 +0000 | 0000-01-01 12:34:56.234567 +0000 UTC | 0000-01-01 12:34:57.234567 +0000 UTC | 0000-01-01 23:12:36.765432 +0100 +0100 | 0000-01-01 23:12:37.765432 +0100 +0100 | 00:00:00.987654 | 00:00:00.887654 | +// | null | 2023-11-15 05:06:09.123456 +0000 +0000 | null | 2021-07-22 11:22:35.654321 +0000 UTC | null | 2023-12-22 00:00:00 +0000 +0000 | null | 0000-01-01 12:34:58.234567 +0000 UTC | null | 0000-01-01 23:12:38.765432 +0100 +0100 | null | 00:00:00.787654 | +// +----------------------------------------+----------------------------------------+--------------------------------------+--------------------------------------+---------------------------------+---------------------------------+--------------------------------------+--------------------------------------+----------------------------------------+----------------------------------------+-----------------+-----------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "ts", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tsnn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tsz", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tsznn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "d", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "dnn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "t", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tnn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tz", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tznn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "i", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "inn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1700024767123, + null + ], + [ + 1700024768123, + 1700024769123 + ], + [ + 1626952953654, + null + ], + [ + 1626952954654, + 1626952955654 + ], + [ + 1703030400000, + null + ], + [ + 1703116800000, + 1703203200000 + ], + [ + -62167173903766, + null + ], + [ + -62167173902766, + -62167173901766 + ], + [ + -62167139243235, + null + ], + [ + -62167139242235, + -62167139241235 + ], + [ + "00:00:00.987654", + null + ], + [ + "00:00:00.887654", + "00:00:00.787654" + ] + ], + "nanos": [ + [ + 456000, + 0 + ], + [ + 456000, + 456000 + ], + [ + 321000, + 0 + ], + [ + 321000, + 321000 + ], + null, + null, + [ + 567000, + 0 + ], + [ + 567000, + 567000 + ], + [ + 432000, + 0 + ], + [ + 432000, + 432000 + ], + null, + null + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.sql new file mode 100644 index 00000000000..d81b3ca235b --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_datetime.sql @@ -0,0 +1,44 @@ +-- SELECT * FROM tbl +-- test all date/time-based postgres data types +CREATE TEMPORARY TABLE tbl ( + ts timestamp, + tsnn timestamp NOT NULL, + tsz timestamp with time zone, + tsznn timestamp with time zone NOT NULL, + d date, + dnn date NOT NULL, + t time, + tnn time NOT NULL, + tz time with time zone, + tznn time with time zone NOT NULL, + i interval, + inn interval NOT NULL +); + +INSERT INTO tbl (ts, tsnn, tsz, tsznn, d, dnn, t, tnn, tz, tznn, i, inn) VALUES ( +'2023-11-15 05:06:07.123456', +'2023-11-15 05:06:08.123456', +'2021-07-22 13:22:33.654321 Europe/Berlin', +'2021-07-22 13:22:34.654321 Europe/Berlin', +'2023-12-20', +'2023-12-21', +'12:34:56.234567', +'12:34:57.234567', +'23:12:36.765432+1', +'23:12:37.765432+1', +'987654 microsecond', +'887654 microsecond' +), ( +NULL, +'2023-11-15 05:06:09.123456', +NULL, +'2021-07-22 13:22:35.654321 Europe/Berlin', +NULL, +'2023-12-22', +NULL, +'12:34:58.234567', +NULL, +'23:12:38.765432+1', +NULL, +'787654 microsecond' +); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.golden.jsonc new file mode 100644 index 00000000000..d8ac6c700a6 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.golden.jsonc @@ -0,0 +1,188 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 12 Fields by 2 Rows +// +----------------+----------------+----------------+----------------+----------------+----------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// | Name: i16 | Name: i16nn | Name: i32 | Name: i32nn | Name: i64 | Name: i64nn | Name: n | Name: nnn | Name: f32 | Name: f32nn | Name: f64 | Name: f64nn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*int16 | Type: []*int16 | Type: []*int32 | Type: []*int32 | Type: []*int64 | Type: []*int64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | +// +----------------+----------------+----------------+----------------+----------------+----------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// | 1 | 2 | 3 | 4 | 5 | 6 | 81.75 | 7065.25 | 30.75 | 14.625 | 21.5625 | 14.25 | +// | null | 22 | null | 44 | null | 66 | null | 169.75 | null | 77.125 | null | 215.8125 | +// +----------------+----------------+----------------+----------------+----------------+----------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "i16", + "type": "number", + "typeInfo": { + "frame": "int16", + "nullable": true + } + }, + { + "name": "i16nn", + "type": "number", + "typeInfo": { + "frame": "int16", + "nullable": true + } + }, + { + "name": "i32", + "type": "number", + "typeInfo": { + "frame": "int32", + "nullable": true + } + }, + { + "name": "i32nn", + "type": "number", + "typeInfo": { + "frame": "int32", + "nullable": true + } + }, + { + "name": "i64", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i64nn", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "nnn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f32", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f32nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f64", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f64nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1, + null + ], + [ + 2, + 22 + ], + [ + 3, + null + ], + [ + 4, + 44 + ], + [ + 5, + null + ], + [ + 6, + 66 + ], + [ + 81.75, + null + ], + [ + 7065.25, + 169.75 + ], + [ + 30.75, + null + ], + [ + 14.625, + 77.125 + ], + [ + 21.5625, + null + ], + [ + 14.25, + 215.8125 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.sql new file mode 100644 index 00000000000..cd8a5c15f51 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_numeric.sql @@ -0,0 +1,20 @@ +-- SELECT * FROM tbl +-- test all numeric postgres data types +CREATE TEMPORARY TABLE tbl ( + i16 smallint, + i16nn smallint NOT NULL, + i32 integer, + i32nn integer NOT NULL, + i64 bigint, + i64nn bigint NOT NULL, + n numeric(7, 2), + nnn numeric(7,2) NOT NULL, + f32 real, + f32nn real NOT NULL, + f64 double precision, + f64nn double precision NOT NULL +); + +INSERT INTO tbl (i16, i16nn, i32, i32nn, i64, i64nn, n, nnn, f32, f32nn, f64, f64nn) VALUES +(1, 2, 3, 4, 5, 6, 81.75, 7065.25, 30.75, 14.625, 21.5625, 14.25), +(NULL, 22, NULL, 44, NULL, 66, NULL, 169.75, NULL, 77.125, NULL, 215.8125); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.golden.jsonc new file mode 100644 index 00000000000..f0eb0ba9404 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.golden.jsonc @@ -0,0 +1,123 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 6 Fields by 3 Rows +// +-----------------+-----------------+-----------------+-----------------+---------------+---------------+ +// | Name: m | Name: mnn | Name: bt | Name: btnn | Name: bl | Name: blnn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*bool | Type: []*bool | +// +-----------------+-----------------+-----------------+-----------------+---------------+---------------+ +// | $12.34 | $23.45 | ABCD | EFGH | true | true | +// | $12.34 | $23.45 | QRST | UVWX | false | false | +// | null | $34.56 | null | abcd | null | true | +// +-----------------+-----------------+-----------------+-----------------+---------------+---------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "m", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "mnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "bt", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "btnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "bl", + "type": "boolean", + "typeInfo": { + "frame": "bool", + "nullable": true + } + }, + { + "name": "blnn", + "type": "boolean", + "typeInfo": { + "frame": "bool", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + "$12.34", + "$12.34", + null + ], + [ + "$23.45", + "$23.45", + "$34.56" + ], + [ + "ABCD", + "QRST", + null + ], + [ + "EFGH", + "UVWX", + "abcd" + ], + [ + true, + false, + null + ], + [ + true, + false, + true + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.sql new file mode 100644 index 00000000000..0d8c2e87920 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/table/types_other.sql @@ -0,0 +1,15 @@ +-- SELECT * FROM tbl +-- test the less used postgres data types +CREATE TEMPORARY TABLE tbl ( + m money, + mnn money NOT NULL, + bt bytea, + btnn bytea NOT NULL, + bl boolean, + blnn boolean NOT NULL +); + +INSERT INTO tbl (m, mnn, bt, btnn, bl, blnn) VALUES +(12.34, 23.45, '\x41424344'::bytea, '\x45464748'::bytea, TRUE, TRUE), +(12.34, 23.45, '\x51525354'::bytea, '\x55565758'::bytea, FALSE, FALSE), +(NULL, 34.56, NULL, '\x61626364'::bytea, NULL, TRUE); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.golden.jsonc new file mode 100644 index 00000000000..4bbf17b8425 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.golden.jsonc @@ -0,0 +1,93 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 5 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: a | Name: b | +// | Labels: | Labels: | Labels: | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:30:03 +0000 UTC | 10 | 110 | +// | 2023-12-24 14:31:03 +0000 UTC | 20 | 120 | +// | 2023-12-24 14:32:03 +0000 UTC | 30 | 130 | +// | 2023-12-24 14:33:03 +0000 UTC | 40 | 140 | +// | 2023-12-24 14:34:03 +0000 UTC | 50 | 150 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "a", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "b", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703428203000, + 1703428263000, + 1703428323000, + 1703428383000, + 1703428443000 + ], + [ + 10, + 20, + 30, + 40, + 50 + ], + [ + 110, + 120, + 130, + 140, + 150 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.sql new file mode 100644 index 00000000000..8e3256f4789 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/7x_compat_metric_label.sql @@ -0,0 +1,19 @@ +-- SELECT * FROM tbl +-- there's special backward-compat code which handles a field named 'metric' +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v double precision, + metric text +); + +INSERT INTO tbl ("time", v, metric) VALUES +('2023-12-24 14:30:03 UTC', 10, 'a'), +('2023-12-24 14:30:03 UTC', 110, 'b'), +('2023-12-24 14:31:03 UTC', 20, 'a'), +('2023-12-24 14:31:03 UTC', 120, 'b'), +('2023-12-24 14:32:03 UTC', 30, 'a'), +('2023-12-24 14:32:03 UTC', 130, 'b'), +('2023-12-24 14:33:03 UTC', 40, 'a'), +('2023-12-24 14:33:03 UTC', 140, 'b'), +('2023-12-24 14:34:03 UTC', 50, 'a'), +('2023-12-24 14:34:03 UTC', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.golden.jsonc new file mode 100644 index 00000000000..22ed2df857e --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.golden.jsonc @@ -0,0 +1,245 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 11 Fields by 1 Rows +// +-------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+ +// | Name: Time | Name: v1 | Name: v1nn | Name: v2 | Name: v2nn | Name: x1 | Name: x1nn | Name: x2 | Name: x2nn | Name: x3 | Name: x3nn | +// | Labels: | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | Labels: c1=one, c1nn=two, c2=three, c2nn=four, c3=five , c3nn=six | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | +// +-------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+ +// | 2023-12-21 11:30:03 +0000 UTC | 10.1 | 11.1 | 12.1 | 13.1 | 101 | 102 | 103 | 104 | 105 | 106 | +// +-------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v1", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "v1nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "v2", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "v2nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "x1", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "x1nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "x2", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "x2nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "x3", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + }, + { + "name": "x3nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "one", + "c1nn": "two", + "c2": "three", + "c2nn": "four", + "c3": "five ", + "c3nn": "six " + } + } + ] + }, + "data": { + "values": [ + [ + 1703158203000 + ], + [ + 10.1 + ], + [ + 11.1 + ], + [ + 12.1 + ], + [ + 13.1 + ], + [ + 101 + ], + [ + 102 + ], + [ + 103 + ], + [ + 104 + ], + [ + 105 + ], + [ + 106 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.sql new file mode 100644 index 00000000000..de8f7650bd3 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/convert_to_float64.sql @@ -0,0 +1,30 @@ +-- SELECT * FROM tbl +-- in timeseries mode, most fields gets converted to float6 +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v1 double precision, + v1nn double precision NOT NULL, + v2 real, + v2nn real NOT NULL, + c1 text, + c1nn text NOT NULL, + c2 varchar(10), + c2nn varchar(10) NOT NULL, + c3 char(10), + c3nn char(10) NOT NULL, + x1 smallint, + x1nn smallint NOT NULL, + x2 integer, + x2nn integer NOT NULL, + x3 bigint, + x3nn bigint NOT NULL +); + +INSERT INTO tbl ("time", +v1, v1nn, v2, v2nn, +c1, c1nn, c2, c2nn, c3, c3nn, +x1, x1nn, x2, x2nn, x3, x3nn) VALUES +('2023-12-21 11:30:03 UTC', +10.1, 11.1, 12.1, 13.1, +'one', 'two', 'three', 'four', 'five', 'six', +101, 102, 103, 104, 105, 106); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.golden.jsonc new file mode 100644 index 00000000000..dda7e197384 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.golden.jsonc @@ -0,0 +1,107 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT floor(extract(epoch from \"time\")/300)*300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 15:15:00 +0100 CET | null | null | +// | 2023-12-24 15:20:00 +0100 CET | 15 | 115 | +// | 2023-12-24 15:25:00 +0100 CET | null | null | +// | 2023-12-24 15:30:00 +0100 CET | null | null | +// | 2023-12-24 15:35:00 +0100 CET | 50 | 150 | +// | 2023-12-24 15:40:00 +0100 CET | null | null | +// | 2023-12-24 15:45:00 +0100 CET | null | null | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT floor(extract(epoch from \"time\")/300)*300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + null, + 15, + null, + null, + 50, + null, + null + ], + [ + null, + 115, + null, + null, + 150, + null, + null + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.sql new file mode 100644 index 00000000000..d3ae81dad8f --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_null.sql @@ -0,0 +1,15 @@ +-- SELECT $__timeGroup("time",5m,NULL),c,avg(v) AS "v" FROM tbl GROUP BY 1,2 ORDER BY 1,2 +-- tests fill-mode=null +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v double precision, + c text +); + +INSERT INTO tbl ("time", v, c) VALUES +('2023-12-24 14:21:03 UTC', 10, 'a'), +('2023-12-24 14:21:03 UTC', 110, 'b'), +('2023-12-24 14:23:03 UTC', 20, 'a'), +('2023-12-24 14:23:03 UTC', 120, 'b'), +('2023-12-24 14:39:03 UTC', 50, 'a'), +('2023-12-24 14:39:03 UTC', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.golden.jsonc new file mode 100644 index 00000000000..71b4e5371aa --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.golden.jsonc @@ -0,0 +1,107 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT floor(extract(epoch from \"time\")/300)*300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 15:15:00 +0100 CET | null | null | +// | 2023-12-24 15:20:00 +0100 CET | 15 | 115 | +// | 2023-12-24 15:25:00 +0100 CET | 15 | 115 | +// | 2023-12-24 15:30:00 +0100 CET | 15 | 115 | +// | 2023-12-24 15:35:00 +0100 CET | 50 | 150 | +// | 2023-12-24 15:40:00 +0100 CET | 50 | 150 | +// | 2023-12-24 15:45:00 +0100 CET | 50 | 150 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT floor(extract(epoch from \"time\")/300)*300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + null, + 15, + 15, + 15, + 50, + 50, + 50 + ], + [ + null, + 115, + 115, + 115, + 150, + 150, + 150 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.sql new file mode 100644 index 00000000000..625155a9e78 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_previous.sql @@ -0,0 +1,15 @@ +-- SELECT $__timeGroup("time",5m,previous),c,avg(v) AS "v" FROM tbl GROUP BY 1,2 ORDER BY 1,2 +-- tests fill-mode=previous +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v double precision, + c text +); + +INSERT INTO tbl ("time", v, c) VALUES +('2023-12-24 14:21:03 UTC', 10, 'a'), +('2023-12-24 14:21:03 UTC', 110, 'b'), +('2023-12-24 14:23:03 UTC', 20, 'a'), +('2023-12-24 14:23:03 UTC', 120, 'b'), +('2023-12-24 14:39:03 UTC', 50, 'a'), +('2023-12-24 14:39:03 UTC', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.golden.jsonc new file mode 100644 index 00000000000..56c9a1239b5 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.golden.jsonc @@ -0,0 +1,107 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT floor(extract(epoch from \"time\")/300)*300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 15:15:00 +0100 CET | 27 | 27 | +// | 2023-12-24 15:20:00 +0100 CET | 15 | 115 | +// | 2023-12-24 15:25:00 +0100 CET | 27 | 27 | +// | 2023-12-24 15:30:00 +0100 CET | 27 | 27 | +// | 2023-12-24 15:35:00 +0100 CET | 50 | 150 | +// | 2023-12-24 15:40:00 +0100 CET | 27 | 27 | +// | 2023-12-24 15:45:00 +0100 CET | 27 | 27 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT floor(extract(epoch from \"time\")/300)*300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + 27, + 15, + 27, + 27, + 50, + 27, + 27 + ], + [ + 27, + 115, + 27, + 27, + 150, + 27, + 27 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.sql new file mode 100644 index 00000000000..a986288e241 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/fill_value.sql @@ -0,0 +1,15 @@ +-- SELECT $__timeGroup("time",5m,27),c,avg(v) AS "v" FROM tbl GROUP BY 1,2 ORDER BY 1,2 +-- tests fill-mode=value +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v double precision, + c text +); + +INSERT INTO tbl ("time", v, c) VALUES +('2023-12-24 14:21:03 UTC', 10, 'a'), +('2023-12-24 14:21:03 UTC', 110, 'b'), +('2023-12-24 14:23:03 UTC', 20, 'a'), +('2023-12-24 14:23:03 UTC', 120, 'b'), +('2023-12-24 14:39:03 UTC', 50, 'a'), +('2023-12-24 14:39:03 UTC', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.golden.jsonc b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.golden.jsonc new file mode 100644 index 00000000000..c8075f2b65b --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.golden.jsonc @@ -0,0 +1,99 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 5 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:30:03 +0000 UTC | 10 | 110 | +// | 2023-12-24 14:31:03 +0000 UTC | 20 | 120 | +// | 2023-12-24 14:32:03 +0000 UTC | 30 | 130 | +// | 2023-12-24 14:33:03 +0000 UTC | 40 | 140 | +// | 2023-12-24 14:34:03 +0000 UTC | 50 | 150 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703428203000, + 1703428263000, + 1703428323000, + 1703428383000, + 1703428443000 + ], + [ + 10, + 20, + 30, + 40, + 50 + ], + [ + 110, + 120, + 130, + 140, + 150 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.sql b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.sql new file mode 100644 index 00000000000..b89651e591d --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/testdata/time_series/simple.sql @@ -0,0 +1,18 @@ +-- SELECT * FROM tbl +CREATE TEMPORARY TABLE tbl ( + "time" timestamp with time zone, + v double precision, + c text +); + +INSERT INTO tbl ("time", v, c) VALUES +('2023-12-24 14:30:03 UTC', 10, 'a'), +('2023-12-24 14:30:03 UTC', 110, 'b'), +('2023-12-24 14:31:03 UTC', 20, 'a'), +('2023-12-24 14:31:03 UTC', 120, 'b'), +('2023-12-24 14:32:03 UTC', 30, 'a'), +('2023-12-24 14:32:03 UTC', 130, 'b'), +('2023-12-24 14:33:03 UTC', 40, 'a'), +('2023-12-24 14:33:03 UTC', 140, 'b'), +('2023-12-24 14:34:03 UTC', 50, 'a'), +('2023-12-24 14:34:03 UTC', 150, 'b'); \ No newline at end of file From df204a9563a842a9837fbe67e03cca07ae0482fc Mon Sep 17 00:00:00 2001 From: Sven Grossmann Date: Tue, 9 Jan 2024 16:07:04 +0100 Subject: [PATCH 14/16] Loki: Add documentation for `label` derived field (#80218) --- .../datasources/loki/configure-loki-data-source.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/sources/datasources/loki/configure-loki-data-source.md b/docs/sources/datasources/loki/configure-loki-data-source.md index 81ec007efbe..bae45a99498 100644 --- a/docs/sources/datasources/loki/configure-loki-data-source.md +++ b/docs/sources/datasources/loki/configure-loki-data-source.md @@ -91,9 +91,9 @@ To troubleshoot configuration and other issues, check the log file located at `/ ### Derived fields -Derived Fields are used to extract new fields from a log message and create a link from the value of the field. +Derived Fields are used to extract new fields from your logs and create a link from the value of the field. -For example, you can link to your tracing backend directly from your logs, or link to a user profile page if the log line contains a corresponding userId. +For example, you can link to your tracing backend directly from your logs, or link to a user profile page if the log line contains a corresponding `userId`. These links appear in the [log details][]. You can add multiple derived fields. @@ -106,7 +106,11 @@ Each derived field consists of the following: - **Name** - Sets the field name. Displayed as a label in the log details. -- **Regex** - Defines a regular expression to parse a part of the log message and capture it as the value of the new field. Can contain only one capture group. +- **Type** - Defines the type of the derived field. It can be either: + + - **Regex**: A regular expression to parse a part of the log message and capture it as the value of the new field. Can contain only one capture group. + + - **Label**: A label from the selected log line. This can be any type of label - indexed, parsed or structured metadata. The label's value will be used as the value of the derived field. - **URL/query** Sets the full link URL if the link is external, or a query for the target data source if the link is internal. You can interpolate the value from the field with the `${__value.raw}` macro. From 35e3988d4a0e4bc2931cd36e20ef419ed72ab2ff Mon Sep 17 00:00:00 2001 From: Victor Marin <36818606+mdvictor@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:26:46 +0200 Subject: [PATCH 15/16] Add versions tab in dashboard settings (#80190) --- .../settings/VersionsEditView.tsx | 36 +++++++++++++++++++ .../dashboard-scene/settings/utils.ts | 8 +++++ 2 files changed, 44 insertions(+) create mode 100644 public/app/features/dashboard-scene/settings/VersionsEditView.tsx diff --git a/public/app/features/dashboard-scene/settings/VersionsEditView.tsx b/public/app/features/dashboard-scene/settings/VersionsEditView.tsx new file mode 100644 index 00000000000..1805a00096a --- /dev/null +++ b/public/app/features/dashboard-scene/settings/VersionsEditView.tsx @@ -0,0 +1,36 @@ +import React from 'react'; + +import { PageLayoutType } from '@grafana/data'; +import { SceneComponentProps, SceneObjectBase } from '@grafana/scenes'; +import { Page } from 'app/core/components/Page/Page'; + +import { DashboardScene } from '../scene/DashboardScene'; +import { getDashboardSceneFor } from '../utils/utils'; + +import { DashboardEditView, DashboardEditViewState, useDashboardEditPageNav } from './utils'; + +export interface VersionsEditViewState extends DashboardEditViewState {} + +export class VersionsEditView extends SceneObjectBase implements DashboardEditView { + public static Component = VersionsEditorSettingsListView; + + public getUrlKey(): string { + return 'versions'; + } + + public getDashboard(): DashboardScene { + return getDashboardSceneFor(this); + } +} + +function VersionsEditorSettingsListView({ model }: SceneComponentProps) { + const dashboard = model.getDashboard(); + + const { navModel, pageNav } = useDashboardEditPageNav(dashboard, model.getUrlKey()); + + return ( + +
TODO
+
+ ); +} diff --git a/public/app/features/dashboard-scene/settings/utils.ts b/public/app/features/dashboard-scene/settings/utils.ts index 55956d5b545..7a2db429433 100644 --- a/public/app/features/dashboard-scene/settings/utils.ts +++ b/public/app/features/dashboard-scene/settings/utils.ts @@ -12,6 +12,7 @@ import { AnnotationsEditView } from './AnnotationsEditView'; import { DashboardLinksEditView } from './DashboardLinksEditView'; import { GeneralSettingsEditView } from './GeneralSettingsEditView'; import { VariablesEditView } from './VariablesEditView'; +import { VersionsEditView } from './VersionsEditView'; export interface DashboardEditViewState extends SceneObjectState {} @@ -54,6 +55,11 @@ export function useDashboardEditPageNav(dashboard: DashboardScene, currentEditVi url: locationUtil.getUrlForPartial(location, { editview: 'links', editIndex: null }), active: currentEditView === 'links', }, + { + text: t('dashboard-settings.versions.title', 'Versions'), + url: locationUtil.getUrlForPartial(location, { editview: 'versions', editIndex: null }), + active: currentEditView === 'versions', + }, ], parentItem: dashboardPageNav, }; @@ -69,6 +75,8 @@ export function createDashboardEditViewFor(editview: string): DashboardEditView return new VariablesEditView({}); case 'links': return new DashboardLinksEditView({}); + case 'versions': + return new VersionsEditView({}); case 'settings': default: return new GeneralSettingsEditView({}); From a449df34553ca03ef72e8dc17cec1229d1778ae6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:32:24 +0000 Subject: [PATCH 16/16] Update dependency @cypress/webpack-preprocessor to v6.0.1 (#80217) * Update dependency @cypress/webpack-preprocessor to v6.0.1 * fix type errors * restore old checksum for scenes --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Ashley Harrison --- package.json | 2 +- .../src/components/Button/Button.tsx | 6 +- .../components/Select/resetSelectStyles.ts | 4 +- .../src/themes/GlobalStyles/elements.ts | 4 +- packages/grafana-ui/src/themes/mixins.ts | 7 +- .../PanelEditor/OptionsPaneItemOverrides.tsx | 7 +- yarn.lock | 904 +----------------- 7 files changed, 43 insertions(+), 891 deletions(-) diff --git a/package.json b/package.json index 4227473f8e4..a3f507860d0 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@betterer/betterer": "5.4.0", "@betterer/cli": "5.4.0", "@betterer/eslint": "5.4.0", - "@cypress/webpack-preprocessor": "6.0.0", + "@cypress/webpack-preprocessor": "6.0.1", "@emotion/eslint-plugin": "11.11.0", "@grafana/eslint-config": "6.0.1", "@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules", diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx index b2f8bf3bf32..7423a05a4d3 100644 --- a/packages/grafana-ui/src/components/Button/Button.tsx +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -1,4 +1,4 @@ -import { css, CSSObject, cx } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react'; import { GrafanaTheme2, ThemeRichColor } from '@grafana/data'; @@ -224,7 +224,7 @@ export const getButtonStyles = (props: StyleProps) => { }; }; -function getButtonVariantStyles(theme: GrafanaTheme2, color: ThemeRichColor, fill: ButtonFill): CSSObject { +function getButtonVariantStyles(theme: GrafanaTheme2, color: ThemeRichColor, fill: ButtonFill) { let outlineBorderColor = color.border; let borderColor = 'transparent'; let hoverBorderColor = 'transparent'; @@ -293,7 +293,7 @@ function getButtonVariantStyles(theme: GrafanaTheme2, color: ThemeRichColor, fil } function getPropertiesForDisabled(theme: GrafanaTheme2, variant: ButtonVariant, fill: ButtonFill) { - const disabledStyles: CSSObject = { + const disabledStyles = { cursor: 'not-allowed', boxShadow: 'none', color: theme.colors.text.disabled, diff --git a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts index 3f1e31abff7..0449fd94e06 100644 --- a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts +++ b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts @@ -13,7 +13,7 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { groupHeading: () => ({}), indicatorsContainer: () => ({}), indicatorSeparator: () => ({}), - input: function (originalStyles: CSSObjectWithLabel): CSSObjectWithLabel { + input: function (originalStyles: CSSObjectWithLabel) { return { ...originalStyles, color: 'inherit', @@ -37,7 +37,7 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { multiValueRemove: () => ({}), noOptionsMessage: () => ({}), option: () => ({}), - placeholder: (originalStyles: CSSObjectWithLabel): CSSObjectWithLabel => ({ + placeholder: (originalStyles: CSSObjectWithLabel) => ({ ...originalStyles, color: theme.colors.text.secondary, }), diff --git a/packages/grafana-ui/src/themes/GlobalStyles/elements.ts b/packages/grafana-ui/src/themes/GlobalStyles/elements.ts index bb8278efe4e..a37f5561b25 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/elements.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/elements.ts @@ -1,4 +1,4 @@ -import { css, CSSObject } from '@emotion/react'; +import { css } from '@emotion/react'; import { GrafanaTheme2, ThemeTypographyVariant } from '@grafana/data'; @@ -144,7 +144,7 @@ export function getElementStyles(theme: GrafanaTheme2) { }); } -export function getVariantStyles(variant: ThemeTypographyVariant): CSSObject { +export function getVariantStyles(variant: ThemeTypographyVariant) { return { margin: 0, fontSize: variant.fontSize, diff --git a/packages/grafana-ui/src/themes/mixins.ts b/packages/grafana-ui/src/themes/mixins.ts index e633ae2a983..537ccaea44c 100644 --- a/packages/grafana-ui/src/themes/mixins.ts +++ b/packages/grafana-ui/src/themes/mixins.ts @@ -1,4 +1,3 @@ -import { CSSObject } from '@emotion/css'; import tinycolor from 'tinycolor2'; import { GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; @@ -55,14 +54,14 @@ export const focusCss = (theme: GrafanaTheme | GrafanaTheme2) => { transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);`; }; -export function getMouseFocusStyles(theme: GrafanaTheme | GrafanaTheme2): CSSObject { +export function getMouseFocusStyles(theme: GrafanaTheme | GrafanaTheme2) { return { outline: 'none', boxShadow: `none`, }; } -export function getFocusStyles(theme: GrafanaTheme2): CSSObject { +export function getFocusStyles(theme: GrafanaTheme2) { return { outline: '2px dotted transparent', outlineOffset: '2px', @@ -74,7 +73,7 @@ export function getFocusStyles(theme: GrafanaTheme2): CSSObject { } // max-width is set up based on .grafana-tooltip class that's used in dashboard -export const getTooltipContainerStyles = (theme: GrafanaTheme2): CSSObject => ({ +export const getTooltipContainerStyles = (theme: GrafanaTheme2) => ({ overflow: 'hidden', background: theme.colors.background.secondary, boxShadow: theme.shadows.z2, diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx index 1e3fff28ca8..83e0c93c7a8 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx @@ -1,4 +1,4 @@ -import { css, CSSObject } from '@emotion/css'; +import { css } from '@emotion/css'; import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; @@ -25,12 +25,11 @@ export function OptionsPaneItemOverrides({ overrides }: Props) { } const getStyles = (theme: GrafanaTheme2) => { - const common: CSSObject = { + const common = { width: 8, height: 8, borderRadius: theme.shape.radius.circle, marginLeft: theme.spacing(1), - position: 'relative', top: '-1px', }; @@ -40,10 +39,12 @@ const getStyles = (theme: GrafanaTheme2) => { }), rule: css({ ...common, + position: 'relative', backgroundColor: theme.colors.primary.main, }), data: css({ ...common, + position: 'relative', backgroundColor: theme.colors.warning.main, }), }; diff --git a/yarn.lock b/yarn.lock index e418d5a0d3e..cd86bc79bd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,7 +12,7 @@ __metadata: languageName: node linkType: hard -"@adobe/css-tools@npm:^4.3.0, @adobe/css-tools@npm:^4.3.1": +"@adobe/css-tools@npm:^4.3.1": version: 4.3.1 resolution: "@adobe/css-tools@npm:4.3.1" checksum: 039a42ffdd41ecf3abcaf09c9fef0ffd634ccbe81c04002fc989e74564eba99bb19169a8f48dadf6442aa2c5c9f0925a7b27ec5c36a1ed1a3515fe77d6930996 @@ -1904,9 +1904,9 @@ __metadata: languageName: node linkType: hard -"@cypress/webpack-preprocessor@npm:6.0.0": - version: 6.0.0 - resolution: "@cypress/webpack-preprocessor@npm:6.0.0" +"@cypress/webpack-preprocessor@npm:6.0.1": + version: 6.0.1 + resolution: "@cypress/webpack-preprocessor@npm:6.0.1" dependencies: bluebird: "npm:3.7.1" debug: "npm:^4.3.4" @@ -1916,7 +1916,7 @@ __metadata: "@babel/preset-env": ^7.0.0 babel-loader: ^8.3 || ^9 webpack: ^4 || ^5 - checksum: 9237c4d6752913c96cb8ca2bbda1d5e1b2c5778c668e23e751d79c3a5323dbe1f2bbecf5ffcc9ffc2906d08f57b0c93da3853d4b1115669ba78b9296256e9b11 + checksum: 2c8423c7b0808a04c1b12d4f26fbac55ba488d22f55396822d3ad76735c1f60573e31935c4250afe87150260d592f88e2678a0a34ae569cc8e4bb7af1ab65aaa languageName: node linkType: hard @@ -2748,19 +2748,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.0": - version: 2.0.2 - resolution: "@floating-ui/react-dom@npm:2.0.2" - dependencies: - "@floating-ui/dom": "npm:^1.5.1" - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 63a26f3c36f00a2bdede202cb7a3be74b3c6599463c0a069745f6aed3181a33ce72936158209f6fd1c284d85fd494aa656e6cbc4266c096f3189ce1c13f83dfe - languageName: node - linkType: hard - -"@floating-ui/react-dom@npm:^2.0.3": +"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.3": version: 2.0.4 resolution: "@floating-ui/react-dom@npm:2.0.4" dependencies: @@ -2786,14 +2774,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.1.3": - version: 0.1.4 - resolution: "@floating-ui/utils@npm:0.1.4" - checksum: 9729bfa9b41a0dfa002f637c38b2b6f9f208d2b938ed3bcd24493abc08afb6ee107bab2b8aadaa2d131eecbc9511e810920c4665c5e6ee83ba97502413c0968e - languageName: node - linkType: hard - -"@floating-ui/utils@npm:^0.1.5": +"@floating-ui/utils@npm:^0.1.3, @floating-ui/utils@npm:^0.1.5": version: 0.1.6 resolution: "@floating-ui/utils@npm:0.1.6" checksum: 450ec4ecc1dd8161b1904d4e1e9d95e653cc06f79af6c3b538b79efb10541d90bcc88646ab3cdffc5b92e00c4804ca727b025d153ad285f42dbbb39aec219ec9 @@ -3695,20 +3676,6 @@ __metadata: languageName: node linkType: hard -"@jest/console@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/console@npm:29.6.4" - dependencies: - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - jest-message-util: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - slash: "npm:^3.0.0" - checksum: c482f87a43bb2c48da79c53ad4157542a67c6c90972a8615b852f889da73fd4bcd2a2b85d41b1c867e3df7e7f55e83b4ac91f226511d5645bc20f6498f114c0d - languageName: node - linkType: hard - "@jest/console@npm:^29.7.0": version: 29.7.0 resolution: "@jest/console@npm:29.7.0" @@ -3764,47 +3731,6 @@ __metadata: languageName: node linkType: hard -"@jest/core@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/core@npm:29.6.4" - dependencies: - "@jest/console": "npm:^29.6.4" - "@jest/reporters": "npm:^29.6.4" - "@jest/test-result": "npm:^29.6.4" - "@jest/transform": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.2.1" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" - jest-changed-files: "npm:^29.6.3" - jest-config: "npm:^29.6.4" - jest-haste-map: "npm:^29.6.4" - jest-message-util: "npm:^29.6.3" - jest-regex-util: "npm:^29.6.3" - jest-resolve: "npm:^29.6.4" - jest-resolve-dependencies: "npm:^29.6.4" - jest-runner: "npm:^29.6.4" - jest-runtime: "npm:^29.6.4" - jest-snapshot: "npm:^29.6.4" - jest-util: "npm:^29.6.3" - jest-validate: "npm:^29.6.3" - jest-watcher: "npm:^29.6.4" - micromatch: "npm:^4.0.4" - pretty-format: "npm:^29.6.3" - slash: "npm:^3.0.0" - strip-ansi: "npm:^6.0.0" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: a1e47946d715a1735f89fdf9fcf6e99278cef691ac893db4c13e283f753a5c62cec47d68d4f3d7fe823aac0fc603257740f630591e8029846e83f451456a4716 - languageName: node - linkType: hard - "@jest/environment@npm:^29.3.1, @jest/environment@npm:^29.7.0": version: 29.7.0 resolution: "@jest/environment@npm:29.7.0" @@ -3817,27 +3743,6 @@ __metadata: languageName: node linkType: hard -"@jest/environment@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/environment@npm:29.6.4" - dependencies: - "@jest/fake-timers": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - jest-mock: "npm:^29.6.3" - checksum: 8c31ed7f3992f450b994684a2a92d2a023e5e182773e13ea7c627edd25598279d5d1a958bea970e3868bc4d45e20881ddcf9bf9af9425f87d38959141f42693d - languageName: node - linkType: hard - -"@jest/expect-utils@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/expect-utils@npm:29.6.4" - dependencies: - jest-get-type: "npm:^29.6.3" - checksum: 47f17bb3262175600130c698fdaaa680ec7f4612bfdb3f4f9f03e0252c341f31135ae854246f5548453634deef949533aa35b3638cfa776ce5596fd4bd8f1c6e - languageName: node - linkType: hard - "@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" @@ -3847,16 +3752,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/expect@npm:29.6.4" - dependencies: - expect: "npm:^29.6.4" - jest-snapshot: "npm:^29.6.4" - checksum: e6564697562885e2b96294740a507e82e76b9f0af83f6101e2979a8650ec14055452e0ea68c154f92ef93ef83b258f1a45aa39df4e0f472e5ff5c4468de4170f - languageName: node - linkType: hard - "@jest/expect@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect@npm:29.7.0" @@ -3881,32 +3776,6 @@ __metadata: languageName: node linkType: hard -"@jest/fake-timers@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/fake-timers@npm:29.6.4" - dependencies: - "@jest/types": "npm:^29.6.3" - "@sinonjs/fake-timers": "npm:^10.0.2" - "@types/node": "npm:*" - jest-message-util: "npm:^29.6.3" - jest-mock: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - checksum: 87df3df08111adb51a425edcbd6a454ec5bf1fec582946d04e68616d669fadad64fefee3ddb05b3c91984e47e718917fac907015095c55c2acd58e4f863b0523 - languageName: node - linkType: hard - -"@jest/globals@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/globals@npm:29.6.4" - dependencies: - "@jest/environment": "npm:^29.6.4" - "@jest/expect": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - jest-mock: "npm:^29.6.3" - checksum: a41b18871a248151264668a38b13cb305f03db112bfd89ec44e858af0e79066e0b03d6b68c8baf1ec6c578be6fdb87519389c83438608b91471d17a5724858e0 - languageName: node - linkType: hard - "@jest/globals@npm:^29.7.0": version: 29.7.0 resolution: "@jest/globals@npm:29.7.0" @@ -3919,43 +3788,6 @@ __metadata: languageName: node linkType: hard -"@jest/reporters@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/reporters@npm:29.6.4" - dependencies: - "@bcoe/v8-coverage": "npm:^0.2.3" - "@jest/console": "npm:^29.6.4" - "@jest/test-result": "npm:^29.6.4" - "@jest/transform": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@jridgewell/trace-mapping": "npm:^0.3.18" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - collect-v8-coverage: "npm:^1.0.0" - exit: "npm:^0.1.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - istanbul-lib-coverage: "npm:^3.0.0" - istanbul-lib-instrument: "npm:^6.0.0" - istanbul-lib-report: "npm:^3.0.0" - istanbul-lib-source-maps: "npm:^4.0.0" - istanbul-reports: "npm:^3.1.3" - jest-message-util: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - jest-worker: "npm:^29.6.4" - slash: "npm:^3.0.0" - string-length: "npm:^4.0.1" - strip-ansi: "npm:^6.0.0" - v8-to-istanbul: "npm:^9.0.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: ba6f6d9f621ef80cc8f2fae001f2c9b9e9186f2b570d386b2cfaf298a391332cf65121f72b700e037c9fb7813af4230f821f5f2e0c71c2bd3d301bfa2aa9b935 - languageName: node - linkType: hard - "@jest/reporters@npm:^29.7.0": version: 29.7.0 resolution: "@jest/reporters@npm:29.7.0" @@ -4013,18 +3845,6 @@ __metadata: languageName: node linkType: hard -"@jest/test-result@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/test-result@npm:29.6.4" - dependencies: - "@jest/console": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/istanbul-lib-coverage": "npm:^2.0.0" - collect-v8-coverage: "npm:^1.0.0" - checksum: d0dd2beaa4e9f3e7cebec44de1ab09a1020e77e4742c018f91bf281d49b824875a6d8f86408fdde195f53dd1ba8b7943b2843a9f002c5b0286f8933c21e65527 - languageName: node - linkType: hard - "@jest/test-result@npm:^29.7.0": version: 29.7.0 resolution: "@jest/test-result@npm:29.7.0" @@ -4037,18 +3857,6 @@ __metadata: languageName: node linkType: hard -"@jest/test-sequencer@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/test-sequencer@npm:29.6.4" - dependencies: - "@jest/test-result": "npm:^29.6.4" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.4" - slash: "npm:^3.0.0" - checksum: f0f09dc5c1cc190ae8944531072b598746c725c81d2810f47d4459a2d3113b3658469ff4e59cd028b221e4f2d015e0b968940e9ae08d800b2e8911590fbc184e - languageName: node - linkType: hard - "@jest/test-sequencer@npm:^29.7.0": version: 29.7.0 resolution: "@jest/test-sequencer@npm:29.7.0" @@ -4084,29 +3892,6 @@ __metadata: languageName: node linkType: hard -"@jest/transform@npm:^29.6.4": - version: 29.6.4 - resolution: "@jest/transform@npm:29.6.4" - dependencies: - "@babel/core": "npm:^7.11.6" - "@jest/types": "npm:^29.6.3" - "@jridgewell/trace-mapping": "npm:^0.3.18" - babel-plugin-istanbul: "npm:^6.1.1" - chalk: "npm:^4.0.0" - convert-source-map: "npm:^2.0.0" - fast-json-stable-stringify: "npm:^2.1.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.4" - jest-regex-util: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - micromatch: "npm:^4.0.4" - pirates: "npm:^4.0.4" - slash: "npm:^3.0.0" - write-file-atomic: "npm:^4.0.2" - checksum: cba6b5a59de89b4446c0c0dc6ca08ea52fb1308caeaa72c70a232a1b81d178cad1a2fcce4e25db95d7623c03c34a244bdfe6769cc6ac71b8c3fcd2838bab583e - languageName: node - linkType: hard - "@jest/types@npm:^26.6.2": version: 26.6.2 resolution: "@jest/types@npm:26.6.2" @@ -4986,14 +4771,14 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api@npm:1.6.0, @opentelemetry/api@npm:^1.0.0": +"@opentelemetry/api@npm:1.6.0": version: 1.6.0 resolution: "@opentelemetry/api@npm:1.6.0" checksum: b8daefad2c862ed4e1e6b50df8946f08339a27aa83ac3b081bd4ed92e9ae2c365ecfc200f936ce08a1278b9a3c4103b5f33c2c19a495f68e245f727bba41af75 languageName: node linkType: hard -"@opentelemetry/api@npm:^1.7.0": +"@opentelemetry/api@npm:^1.0.0, @opentelemetry/api@npm:^1.7.0": version: 1.7.0 resolution: "@opentelemetry/api@npm:1.7.0" checksum: bcf7afa7051dcd4583898a68f8a57fb4c85b5cedddf7b6eb3616595c0b3bcd7f5448143b8355b00935a755de004d6285489f8e132f34127efe7b1be404622a3e @@ -7931,7 +7716,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:6.1.4": +"@testing-library/jest-dom@npm:6.1.4, @testing-library/jest-dom@npm:^6.1.2": version: 6.1.4 resolution: "@testing-library/jest-dom@npm:6.1.4" dependencies: @@ -7961,36 +7746,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:^6.1.2": - version: 6.1.2 - resolution: "@testing-library/jest-dom@npm:6.1.2" - dependencies: - "@adobe/css-tools": "npm:^4.3.0" - "@babel/runtime": "npm:^7.9.2" - aria-query: "npm:^5.0.0" - chalk: "npm:^3.0.0" - css.escape: "npm:^1.5.1" - dom-accessibility-api: "npm:^0.5.6" - lodash: "npm:^4.17.15" - redent: "npm:^3.0.0" - peerDependencies: - "@jest/globals": ">= 28" - "@types/jest": ">= 28" - jest: ">= 28" - vitest: ">= 0.32" - peerDependenciesMeta: - "@jest/globals": - optional: true - "@types/jest": - optional: true - jest: - optional: true - vitest: - optional: true - checksum: 36e27f9011dd60de8936d3edb2a81753ef7a370480019e571c6e85b935b5fa2aba47244104badf6d6b636fd170fdee5c0fdd92fb3630957d4a6f11d302b57398 - languageName: node - linkType: hard - "@testing-library/react-hooks@npm:^8.0.1": version: 8.0.1 resolution: "@testing-library/react-hooks@npm:8.0.1" @@ -8758,7 +8513,7 @@ __metadata: languageName: node linkType: hard -"@types/hoist-non-react-statics@npm:3.3.1, @types/hoist-non-react-statics@npm:^3.3.0": +"@types/hoist-non-react-statics@npm:3.3.1": version: 3.3.1 resolution: "@types/hoist-non-react-statics@npm:3.3.1" dependencies: @@ -8768,7 +8523,7 @@ __metadata: languageName: node linkType: hard -"@types/hoist-non-react-statics@npm:^3.3.1": +"@types/hoist-non-react-statics@npm:^3.3.0, @types/hoist-non-react-statics@npm:^3.3.1": version: 3.3.4 resolution: "@types/hoist-non-react-statics@npm:3.3.4" dependencies: @@ -11246,23 +11001,6 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^29.6.4": - version: 29.6.4 - resolution: "babel-jest@npm:29.6.4" - dependencies: - "@jest/transform": "npm:^29.6.4" - "@types/babel__core": "npm:^7.1.14" - babel-plugin-istanbul: "npm:^6.1.1" - babel-preset-jest: "npm:^29.6.3" - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - slash: "npm:^3.0.0" - peerDependencies: - "@babel/core": ^7.8.0 - checksum: 1e26438368719336d3cb6144b68155f4837154b38d917180b9d0a2344e17dacb59b1213e593005fa7f63041052ad0e38cd1fb1de1c6b54f7d353f617a2ad20cf - languageName: node - linkType: hard - "babel-loader@npm:9.1.3, babel-loader@npm:^9.0.0": version: 9.1.3 resolution: "babel-loader@npm:9.1.3" @@ -13165,16 +12903,6 @@ __metadata: languageName: node linkType: hard -"css-in-js-utils@npm:^2.0.0": - version: 2.0.1 - resolution: "css-in-js-utils@npm:2.0.1" - dependencies: - hyphenate-style-name: "npm:^1.0.2" - isobject: "npm:^3.0.1" - checksum: ebd76577ac87d0881a7adcb1b1fadad1153c41b61d67e5b9b725fc4c861b90405a4472c26fdea140145d634412a54373f9a9f2c7714a84faa6b2178bcde77239 - languageName: node - linkType: hard - "css-in-js-utils@npm:^3.1.0": version: 3.1.0 resolution: "css-in-js-utils@npm:3.1.0" @@ -13458,7 +13186,7 @@ __metadata: languageName: node linkType: hard -"csstype@npm:3.1.2, csstype@npm:^3.0.2, csstype@npm:^3.0.6": +"csstype@npm:3.1.2": version: 3.1.2 resolution: "csstype@npm:3.1.2" checksum: 1f39c541e9acd9562996d88bc9fb62d1cb234786ef11ed275567d4b2bd82e1ceacde25debc8de3d3b4871ae02c2933fa02614004c97190711caebad6347debc2 @@ -13472,7 +13200,7 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.1.2": +"csstype@npm:^3.0.2, csstype@npm:^3.1.2": version: 3.1.3 resolution: "csstype@npm:3.1.3" checksum: f593cce41ff5ade23f44e77521e3a1bcc2c64107041e1bf6c3c32adc5187d0d60983292fda326154d20b01079e24931aa5b08e4467cc488b60bb1e7f6d478ade @@ -14165,20 +13893,13 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.0": +"deepmerge@npm:^4.0, deepmerge@npm:^4.2.2": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" checksum: 058d9e1b0ff1a154468bf3837aea436abcfea1ba1d165ddaaf48ca93765fdd01a30d33c36173da8fbbed951dd0a267602bc782fe288b0fc4b7e1e7091afc4529 languageName: node linkType: hard -"deepmerge@npm:^4.2.2": - version: 4.2.2 - resolution: "deepmerge@npm:4.2.2" - checksum: 0e58ed14f530d08f9b996cfc3a41b0801691620235bc5e1883260e3ed1c1b4a1dfb59f865770e45d5dfb1d7ee108c4fc10c2f85e822989d4123490ea90be2545 - languageName: node - linkType: hard - "default-browser-id@npm:3.0.0": version: 3.0.0 resolution: "default-browser-id@npm:3.0.0" @@ -15986,19 +15707,6 @@ __metadata: languageName: node linkType: hard -"expect@npm:^29.6.4": - version: 29.6.4 - resolution: "expect@npm:29.6.4" - dependencies: - "@jest/expect-utils": "npm:^29.6.4" - jest-get-type: "npm:^29.6.3" - jest-matcher-utils: "npm:^29.6.4" - jest-message-util: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - checksum: 1e9224ce01de2bcd861b5a2b9409cc316c4f298beaa2c4ffb8a907a593e15ddff905506676f2b1f20d31fb1c0919a4527310b37b6d93f2ba4c4f77bf9881a90e - languageName: node - linkType: hard - "expose-loader@npm:4.1.0": version: 4.1.0 resolution: "expose-loader@npm:4.1.0" @@ -16137,7 +15845,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.0.3, fast-glob@npm:^3.3.1": +"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.1": version: 3.3.1 resolution: "fast-glob@npm:3.3.1" dependencies: @@ -16150,19 +15858,6 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9": - version: 3.3.0 - resolution: "fast-glob@npm:3.3.0" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 4cd74914f13eab48dd1a0d16051aa102c13d30ea8a79c991563ea3111a37ff6d888518964291d52d723e7ad2a946149ce9f13d27ad9a07a1e4e1aefb4717ed29 - languageName: node - linkType: hard - "fast-json-parse@npm:^1.0.3": version: 1.0.3 resolution: "fast-json-parse@npm:1.0.3" @@ -17386,20 +17081,13 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:4.2.11": +"graceful-fs@npm:4.2.11, graceful-fs@npm:^4.0.0, graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 languageName: node linkType: hard -"graceful-fs@npm:^4.0.0, graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": - version: 4.2.10 - resolution: "graceful-fs@npm:4.2.10" - checksum: 0c83c52b62c68a944dcfb9d66b0f9f10f7d6e3d081e8067b9bfdc9e5f3a8896584d576036f82915773189eec1eba599397fc620e75c03c0610fb3d67c6713c1a - languageName: node - linkType: hard - "grafana@workspace:.": version: 0.0.0-use.local resolution: "grafana@workspace:." @@ -17420,7 +17108,7 @@ __metadata: "@betterer/betterer": "npm:5.4.0" "@betterer/cli": "npm:5.4.0" "@betterer/eslint": "npm:5.4.0" - "@cypress/webpack-preprocessor": "npm:6.0.0" + "@cypress/webpack-preprocessor": "npm:6.0.1" "@daybrush/utils": "npm:1.13.0" "@emotion/css": "npm:11.11.2" "@emotion/eslint-plugin": "npm:11.11.0" @@ -18442,7 +18130,7 @@ __metadata: languageName: node linkType: hard -"hyphenate-style-name@npm:^1.0.2, hyphenate-style-name@npm:^1.0.3": +"hyphenate-style-name@npm:^1.0.3": version: 1.0.4 resolution: "hyphenate-style-name@npm:1.0.4" checksum: d37883e6b7e1be62e1ddae29cac83fa59fb93c068bc8eb1561585439adbad91dcf7e264ee2a82c4378fc58049f7bd853544a4a81bf00d4aff717f641052323e7 @@ -18615,7 +18303,7 @@ __metadata: languageName: node linkType: hard -"import-local@npm:3.1.0": +"import-local@npm:3.1.0, import-local@npm:^3.0.2": version: 3.1.0 resolution: "import-local@npm:3.1.0" dependencies: @@ -18627,18 +18315,6 @@ __metadata: languageName: node linkType: hard -"import-local@npm:^3.0.2": - version: 3.0.3 - resolution: "import-local@npm:3.0.3" - dependencies: - pkg-dir: "npm:^4.2.0" - resolve-cwd: "npm:^3.0.0" - bin: - import-local-fixture: fixtures/cli.js - checksum: 38ae57d35e7fd5f63b55895050c798d4dd590e4e2337e9ffa882fb3ea7a7716f3162c7300e382e0a733ca5d07b389fadff652c00fa7b072d5cb6ea34ca06b179 - languageName: node - linkType: hard - "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -18720,15 +18396,6 @@ __metadata: languageName: node linkType: hard -"inline-style-prefixer@npm:^6.0.0": - version: 6.0.1 - resolution: "inline-style-prefixer@npm:6.0.1" - dependencies: - css-in-js-utils: "npm:^2.0.0" - checksum: ceb5ddafe394e01494ba06129a19baa43a845a261126409279b5e7172cf6afc1e50e3d740aff057049c810d864758d50609d81de86eecdae8781e7a9703b2db0 - languageName: node - linkType: hard - "inline-style-prefixer@npm:^7.0.0": version: 7.0.0 resolution: "inline-style-prefixer@npm:7.0.0" @@ -18976,16 +18643,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.11.0": - version: 2.12.1 - resolution: "is-core-module@npm:2.12.1" - dependencies: - has: "npm:^1.0.3" - checksum: 35d5f90c95f7c737d287121e924bdfcad0a47b33efd7f89c58e9ab3810b43b1f1d377b641797326bde500e47edf5a7bf74a464e0c336a5c7e827b13fa41b57af - languageName: node - linkType: hard - -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": +"is-core-module@npm:^2.11.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": version: 2.13.1 resolution: "is-core-module@npm:2.13.1" dependencies: @@ -19392,20 +19050,7 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.3, is-typed-array@npm:^1.1.9": - version: 1.1.10 - resolution: "is-typed-array@npm:1.1.10" - dependencies: - available-typed-arrays: "npm:^1.0.5" - call-bind: "npm:^1.0.2" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-tostringtag: "npm:^1.0.0" - checksum: 2392b2473bbc994f5c30d6848e32bab3cab6c80b795aaec3020baf5419ff7df38fc11b3a043eb56d50f842394c578dbb204a7a29398099f895cf111c5b27f327 - languageName: node - linkType: hard - -"is-typed-array@npm:^1.1.12": +"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.12, is-typed-array@npm:^1.1.3, is-typed-array@npm:^1.1.9": version: 1.1.12 resolution: "is-typed-array@npm:1.1.12" dependencies: @@ -19664,17 +19309,6 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-changed-files@npm:29.6.3" - dependencies: - execa: "npm:^5.0.0" - jest-util: "npm:^29.6.3" - p-limit: "npm:^3.1.0" - checksum: ffcd0add3351c54ee0eb3ed88e2352ecf46d9118daed99ab0b73cb25502848a19db3ff3027f8b6ac1a168e158bc87d2d30adbd6c88119fad19f5f87357896f82 - languageName: node - linkType: hard - "jest-changed-files@npm:^29.7.0": version: 29.7.0 resolution: "jest-changed-files@npm:29.7.0" @@ -19686,34 +19320,6 @@ __metadata: languageName: node linkType: hard -"jest-circus@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-circus@npm:29.6.4" - dependencies: - "@jest/environment": "npm:^29.6.4" - "@jest/expect": "npm:^29.6.4" - "@jest/test-result": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - co: "npm:^4.6.0" - dedent: "npm:^1.0.0" - is-generator-fn: "npm:^2.0.0" - jest-each: "npm:^29.6.3" - jest-matcher-utils: "npm:^29.6.4" - jest-message-util: "npm:^29.6.3" - jest-runtime: "npm:^29.6.4" - jest-snapshot: "npm:^29.6.4" - jest-util: "npm:^29.6.3" - p-limit: "npm:^3.1.0" - pretty-format: "npm:^29.6.3" - pure-rand: "npm:^6.0.0" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.3" - checksum: 70dd56c1dec25a7499df85d942f27549ce257430b36597e984dbb3dac630a6707133e50a67285cbcf5564aace700e54748c6b7290136b188363678d0af8db17a - languageName: node - linkType: hard - "jest-circus@npm:^29.7.0": version: 29.7.0 resolution: "jest-circus@npm:29.7.0" @@ -19768,71 +19374,6 @@ __metadata: languageName: node linkType: hard -"jest-cli@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-cli@npm:29.6.4" - dependencies: - "@jest/core": "npm:^29.6.4" - "@jest/test-result": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - chalk: "npm:^4.0.0" - exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" - import-local: "npm:^3.0.2" - jest-config: "npm:^29.6.4" - jest-util: "npm:^29.6.3" - jest-validate: "npm:^29.6.3" - prompts: "npm:^2.0.1" - yargs: "npm:^17.3.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: 24b6ca6c8409433a8da621d91a7637ff67e606c0d6c18b606bbbc1a0c7f7e819b935ec1bc6c45c8e6892faf9f073c409f058cdf0ac454f9379ddb826175d40cf - languageName: node - linkType: hard - -"jest-config@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-config@npm:29.6.4" - dependencies: - "@babel/core": "npm:^7.11.6" - "@jest/test-sequencer": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - babel-jest: "npm:^29.6.4" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - deepmerge: "npm:^4.2.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - jest-circus: "npm:^29.6.4" - jest-environment-node: "npm:^29.6.4" - jest-get-type: "npm:^29.6.3" - jest-regex-util: "npm:^29.6.3" - jest-resolve: "npm:^29.6.4" - jest-runner: "npm:^29.6.4" - jest-util: "npm:^29.6.3" - jest-validate: "npm:^29.6.3" - micromatch: "npm:^4.0.4" - parse-json: "npm:^5.2.0" - pretty-format: "npm:^29.6.3" - slash: "npm:^3.0.0" - strip-json-comments: "npm:^3.1.1" - peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" - peerDependenciesMeta: - "@types/node": - optional: true - ts-node: - optional: true - checksum: 5d9019f046684bf45e87c01996197ccfb96936bca67242f59fdf40d9bd76622c97b5b57bbb257591e12edb941285662dac106f8f327910b26c822adda7057c6d - languageName: node - linkType: hard - "jest-config@npm:^29.7.0": version: 29.7.0 resolution: "jest-config@npm:29.7.0" @@ -19914,27 +19455,6 @@ __metadata: languageName: node linkType: hard -"jest-diff@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-diff@npm:29.6.4" - dependencies: - chalk: "npm:^4.0.0" - diff-sequences: "npm:^29.6.3" - jest-get-type: "npm:^29.6.3" - pretty-format: "npm:^29.6.3" - checksum: b1720b78d1de8e6efaf74425df57e749008049b7c2f8a60af73667fd886653bbc7ee69a452076073ad4b2e3d9d1cd6599bb9dc00a8fb69f02b9075423aafee3c - languageName: node - linkType: hard - -"jest-docblock@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-docblock@npm:29.6.3" - dependencies: - detect-newline: "npm:^3.0.0" - checksum: fa9d8d344f093659beb741e2efa22db663ef8c441200b74707da7749a8799a0022824166d7fdd972e773f7c4fab01227f1847e3315fa63584f539b7b78b285eb - languageName: node - linkType: hard - "jest-docblock@npm:^29.7.0": version: 29.7.0 resolution: "jest-docblock@npm:29.7.0" @@ -19944,19 +19464,6 @@ __metadata: languageName: node linkType: hard -"jest-each@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-each@npm:29.6.3" - dependencies: - "@jest/types": "npm:^29.6.3" - chalk: "npm:^4.0.0" - jest-get-type: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - pretty-format: "npm:^29.6.3" - checksum: e08c01ffba3c6254b6555b749eb7b2e55ca4f153d4e1d8ac15b7dcec4d5c06b150b9f9a272cf3cd622b3b2c495c2d5ee656165b9a93c1c06dcb1a82f13fa95e0 - languageName: node - linkType: hard - "jest-each@npm:^29.7.0": version: 29.7.0 resolution: "jest-each@npm:29.7.0" @@ -20012,20 +19519,6 @@ __metadata: languageName: node linkType: hard -"jest-environment-node@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-environment-node@npm:29.6.4" - dependencies: - "@jest/environment": "npm:^29.6.4" - "@jest/fake-timers": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - jest-mock: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - checksum: 7c7bb39a35eaff23eb553c5b7cae776c0622737e64bcd6b558b745012da1366d5f7e2de0a6f659c39f3869783c0b92a5a3dc64649638dbf8f3208c82832b6321 - languageName: node - linkType: hard - "jest-environment-node@npm:^29.7.0": version: 29.7.0 resolution: "jest-environment-node@npm:29.7.0" @@ -20070,29 +19563,6 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-haste-map@npm:29.6.4" - dependencies: - "@jest/types": "npm:^29.6.3" - "@types/graceful-fs": "npm:^4.1.3" - "@types/node": "npm:*" - anymatch: "npm:^3.0.3" - fb-watchman: "npm:^2.0.0" - fsevents: "npm:^2.3.2" - graceful-fs: "npm:^4.2.9" - jest-regex-util: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - jest-worker: "npm:^29.6.4" - micromatch: "npm:^4.0.4" - walker: "npm:^1.0.8" - dependenciesMeta: - fsevents: - optional: true - checksum: 5fb2dc9cd028b6d02a8d4dcaf81b790b60f9034a20b6a1deca9a4ad529741362cd1035020f3d94f6c160103b1ea3d46771f40a3330ab4d8d3c073d515e11b810 - languageName: node - linkType: hard - "jest-haste-map@npm:^29.7.0": version: 29.7.0 resolution: "jest-haste-map@npm:29.7.0" @@ -20128,16 +19598,6 @@ __metadata: languageName: node linkType: hard -"jest-leak-detector@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-leak-detector@npm:29.6.3" - dependencies: - jest-get-type: "npm:^29.6.3" - pretty-format: "npm:^29.6.3" - checksum: 27548fcfc7602fe1b88f8600185e35ffff71751f3631e52bbfdfc72776f5a13a430185cf02fc632b41320a74f99ae90e40ce101c8887509f0f919608a7175129 - languageName: node - linkType: hard - "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -20160,35 +19620,6 @@ __metadata: languageName: node linkType: hard -"jest-matcher-utils@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-matcher-utils@npm:29.6.4" - dependencies: - chalk: "npm:^4.0.0" - jest-diff: "npm:^29.6.4" - jest-get-type: "npm:^29.6.3" - pretty-format: "npm:^29.6.3" - checksum: de306e3592d316ff9725b8e2595c6a4bb9c05b1f296b3e73aef5cf945a4b4799dbfc3fc080e74f4e6259b65123a70b2dc3595db5cfcbaaa30ed3d37ec59551a0 - languageName: node - linkType: hard - -"jest-message-util@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-message-util@npm:29.6.3" - dependencies: - "@babel/code-frame": "npm:^7.12.13" - "@jest/types": "npm:^29.6.3" - "@types/stack-utils": "npm:^2.0.0" - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - micromatch: "npm:^4.0.4" - pretty-format: "npm:^29.6.3" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.3" - checksum: fe659a92a32e6f9c3fdb9b07792a2a362b3d091334eb230b12524ffb5023457ea39d7fc412187e4f245dbe394fd012591878a2b5932eaedd7e82d5c9b416035c - languageName: node - linkType: hard - "jest-message-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-message-util@npm:29.7.0" @@ -20217,17 +19648,6 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-mock@npm:29.6.3" - dependencies: - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - jest-util: "npm:^29.6.3" - checksum: 9da22e0edfb77b2ed2d4204f305b41a17c2133c0cb638ee81e875115ae6e01adf57681a0ab8f7c2b7e0cde7dcd916d62c7b5d28176c342bb80bbfcea8a168729 - languageName: node - linkType: hard - "jest-pnp-resolver@npm:^1.2.2": version: 1.2.2 resolution: "jest-pnp-resolver@npm:1.2.2" @@ -20247,16 +19667,6 @@ __metadata: languageName: node linkType: hard -"jest-resolve-dependencies@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-resolve-dependencies@npm:29.6.4" - dependencies: - jest-regex-util: "npm:^29.6.3" - jest-snapshot: "npm:^29.6.4" - checksum: 8a1616558e78213bc4c7c445e7188776f7d4940e3858684e0404c485bbc23e1e10093bf59640fbc4b88141f361f0c01e760eb2c79bf088ad1896971941869158 - languageName: node - linkType: hard - "jest-resolve-dependencies@npm:^29.7.0": version: 29.7.0 resolution: "jest-resolve-dependencies@npm:29.7.0" @@ -20267,23 +19677,6 @@ __metadata: languageName: node linkType: hard -"jest-resolve@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-resolve@npm:29.6.4" - dependencies: - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.4" - jest-pnp-resolver: "npm:^1.2.2" - jest-util: "npm:^29.6.3" - jest-validate: "npm:^29.6.3" - resolve: "npm:^1.20.0" - resolve.exports: "npm:^2.0.0" - slash: "npm:^3.0.0" - checksum: 63fcd739106363a8928a96131fd0fd7dfa8b052b70d0c3a3f1099f33666b2d9086880f01e714e46b1044f7d107caaae81fd1547bd2c149d6b7a06453d5cc14b3 - languageName: node - linkType: hard - "jest-resolve@npm:^29.7.0": version: 29.7.0 resolution: "jest-resolve@npm:29.7.0" @@ -20301,35 +19694,6 @@ __metadata: languageName: node linkType: hard -"jest-runner@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-runner@npm:29.6.4" - dependencies: - "@jest/console": "npm:^29.6.4" - "@jest/environment": "npm:^29.6.4" - "@jest/test-result": "npm:^29.6.4" - "@jest/transform": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - emittery: "npm:^0.13.1" - graceful-fs: "npm:^4.2.9" - jest-docblock: "npm:^29.6.3" - jest-environment-node: "npm:^29.6.4" - jest-haste-map: "npm:^29.6.4" - jest-leak-detector: "npm:^29.6.3" - jest-message-util: "npm:^29.6.3" - jest-resolve: "npm:^29.6.4" - jest-runtime: "npm:^29.6.4" - jest-util: "npm:^29.6.3" - jest-watcher: "npm:^29.6.4" - jest-worker: "npm:^29.6.4" - p-limit: "npm:^3.1.0" - source-map-support: "npm:0.5.13" - checksum: b51345e07b78b546dd192f734d1e5324f41fe5aceafba6a8238b3f38f3bcafa433ee9a5bdf41f853bed4279b044ce0621be75b33b840f4a9745b6c958220a21e - languageName: node - linkType: hard - "jest-runner@npm:^29.7.0": version: 29.7.0 resolution: "jest-runner@npm:29.7.0" @@ -20359,36 +19723,6 @@ __metadata: languageName: node linkType: hard -"jest-runtime@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-runtime@npm:29.6.4" - dependencies: - "@jest/environment": "npm:^29.6.4" - "@jest/fake-timers": "npm:^29.6.4" - "@jest/globals": "npm:^29.6.4" - "@jest/source-map": "npm:^29.6.3" - "@jest/test-result": "npm:^29.6.4" - "@jest/transform": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - cjs-module-lexer: "npm:^1.0.0" - collect-v8-coverage: "npm:^1.0.0" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.4" - jest-message-util: "npm:^29.6.3" - jest-mock: "npm:^29.6.3" - jest-regex-util: "npm:^29.6.3" - jest-resolve: "npm:^29.6.4" - jest-snapshot: "npm:^29.6.4" - jest-util: "npm:^29.6.3" - slash: "npm:^3.0.0" - strip-bom: "npm:^4.0.0" - checksum: e70669b5a439f5a26156b972462471fbac997e6779fe7421df000f5fe8f1f11abe0c7cb664edd1cf3849c3f2d8329dc7e8495ce89251352a6cabff9153dcf99a - languageName: node - linkType: hard - "jest-runtime@npm:^29.7.0": version: 29.7.0 resolution: "jest-runtime@npm:29.7.0" @@ -20419,34 +19753,6 @@ __metadata: languageName: node linkType: hard -"jest-snapshot@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-snapshot@npm:29.6.4" - dependencies: - "@babel/core": "npm:^7.11.6" - "@babel/generator": "npm:^7.7.2" - "@babel/plugin-syntax-jsx": "npm:^7.7.2" - "@babel/plugin-syntax-typescript": "npm:^7.7.2" - "@babel/types": "npm:^7.3.3" - "@jest/expect-utils": "npm:^29.6.4" - "@jest/transform": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - babel-preset-current-node-syntax: "npm:^1.0.0" - chalk: "npm:^4.0.0" - expect: "npm:^29.6.4" - graceful-fs: "npm:^4.2.9" - jest-diff: "npm:^29.6.4" - jest-get-type: "npm:^29.6.3" - jest-matcher-utils: "npm:^29.6.4" - jest-message-util: "npm:^29.6.3" - jest-util: "npm:^29.6.3" - natural-compare: "npm:^1.4.0" - pretty-format: "npm:^29.6.3" - semver: "npm:^7.5.3" - checksum: 998476c7ffef43cfe97ef9b786c6c6489440b0042537b0c1ad8b4366de73fc6b1ec16d148ef294b24b835d045c186b2543217e6906dd495b4d20112e85007168 - languageName: node - linkType: hard - "jest-snapshot@npm:^29.7.0": version: 29.7.0 resolution: "jest-snapshot@npm:29.7.0" @@ -20489,34 +19795,6 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-util@npm:29.6.3" - dependencies: - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - graceful-fs: "npm:^4.2.9" - picomatch: "npm:^2.2.3" - checksum: 455af2b5e064213b33b837a18ddd3d31878aee31ad40bbd599de2a4977f860a797e491cb94894e38bbd352cb7b31d41448b7ec3b346408613015411cd88ed57f - languageName: node - linkType: hard - -"jest-validate@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-validate@npm:29.6.3" - dependencies: - "@jest/types": "npm:^29.6.3" - camelcase: "npm:^6.2.0" - chalk: "npm:^4.0.0" - jest-get-type: "npm:^29.6.3" - leven: "npm:^3.1.0" - pretty-format: "npm:^29.6.3" - checksum: 4e0a3ef5a2c181f10dcd979ae62188166effd52d7aec7916deaa29b75b29bdf4e01b77375246c7c16032d95cb7364ceae69c5d146e4348ccdf8a3a43d1c6862c - languageName: node - linkType: hard - "jest-validate@npm:^29.7.0": version: 29.7.0 resolution: "jest-validate@npm:29.7.0" @@ -20531,22 +19809,6 @@ __metadata: languageName: node linkType: hard -"jest-watcher@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-watcher@npm:29.6.4" - dependencies: - "@jest/test-result": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.2.1" - chalk: "npm:^4.0.0" - emittery: "npm:^0.13.1" - jest-util: "npm:^29.6.3" - string-length: "npm:^4.0.1" - checksum: 01c008b2f3e76b024f9e9dd242ba5b172634a6b9bc201d7f27cb82563071f06ae87e3ae8db50336034264a98d20a45459068f089597c956a96959109527498c4 - languageName: node - linkType: hard - "jest-watcher@npm:^29.7.0": version: 29.7.0 resolution: "jest-watcher@npm:29.7.0" @@ -20597,18 +19859,6 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.6.4": - version: 29.6.4 - resolution: "jest-worker@npm:29.6.4" - dependencies: - "@types/node": "npm:*" - jest-util: "npm:^29.6.3" - merge-stream: "npm:^2.0.0" - supports-color: "npm:^8.0.0" - checksum: 52b2f238f21ff20dd4cb74ab85c1b32ba8ce5709355ae2f6d3e908a06ac0828658ab9d94562d752833d0e469f35517ceba9b68ca6b0d27fa1057115f065864ce - languageName: node - linkType: hard - "jest@npm:29.3.1": version: 29.3.1 resolution: "jest@npm:29.3.1" @@ -20628,7 +19878,7 @@ __metadata: languageName: node linkType: hard -"jest@npm:29.7.0": +"jest@npm:29.7.0, jest@npm:^29.6.4": version: 29.7.0 resolution: "jest@npm:29.7.0" dependencies: @@ -20647,25 +19897,6 @@ __metadata: languageName: node linkType: hard -"jest@npm:^29.6.4": - version: 29.6.4 - resolution: "jest@npm:29.6.4" - dependencies: - "@jest/core": "npm:^29.6.4" - "@jest/types": "npm:^29.6.3" - import-local: "npm:^3.0.2" - jest-cli: "npm:^29.6.4" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: d747e293bd63f583e7978ac0693ab7a019812fa44b9bf3b3fe20e75e8a343bcd8251d292326d73151dc0b8a2b5a974d878b3aa9ffb146dfa7980553f64a35b43 - languageName: node - linkType: hard - "jiti@npm:^1.18.2": version: 1.19.1 resolution: "jiti@npm:1.19.1" @@ -22212,7 +21443,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.0": +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.1": version: 9.0.3 resolution: "minimatch@npm:9.0.3" dependencies: @@ -22221,15 +21452,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.1 - resolution: "minimatch@npm:9.0.1" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: b4e98f4dc740dcf33999a99af23ae6e5e1c47632f296dc95cb649a282150f92378d41434bf64af4ea2e5975255a757d031c3bf014bad9214544ac57d97f3ba63 - languageName: node - linkType: hard - "minimist-options@npm:4.1.0": version: 4.1.0 resolution: "minimist-options@npm:4.1.0" @@ -22720,26 +21942,7 @@ __metadata: languageName: node linkType: hard -"nano-css@npm:^5.3.1": - version: 5.3.4 - resolution: "nano-css@npm:5.3.4" - dependencies: - css-tree: "npm:^1.1.2" - csstype: "npm:^3.0.6" - fastest-stable-stringify: "npm:^2.0.2" - inline-style-prefixer: "npm:^6.0.0" - rtl-css-js: "npm:^1.14.0" - sourcemap-codec: "npm:^1.4.8" - stacktrace-js: "npm:^2.0.2" - stylis: "npm:^4.0.6" - peerDependencies: - react: "*" - react-dom: "*" - checksum: 1fa15258ccf841d2dd4daed8a218f83be311e3239da280cff53fffac70008e6f12ebfb622c59dafd6e76721255fc8aa39e92bb7f63f33cb4d9a3936995d8e462 - languageName: node - linkType: hard - -"nano-css@npm:^5.6.1": +"nano-css@npm:^5.3.1, nano-css@npm:^5.6.1": version: 5.6.1 resolution: "nano-css@npm:5.6.1" dependencies: @@ -24733,17 +23936,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.6.3": - version: 29.6.3 - resolution: "pretty-format@npm:29.6.3" - dependencies: - "@jest/schemas": "npm:^29.6.3" - ansi-styles: "npm:^5.0.0" - react-is: "npm:^18.0.0" - checksum: 4a17a0953b3e2d334e628dc9ff11cfad988e6adb00c074bf9d10f3eb1919ad56b30d987148ac0ce1d0317ad392cd78b39a74b6cbac4e66af609f6127ad3aaaf0 - languageName: node - linkType: hard - "pretty-hrtime@npm:^1.0.3": version: 1.0.3 resolution: "pretty-hrtime@npm:1.0.3" @@ -27230,15 +26422,6 @@ __metadata: languageName: node linkType: hard -"rtl-css-js@npm:^1.14.0": - version: 1.14.2 - resolution: "rtl-css-js@npm:1.14.2" - dependencies: - "@babel/runtime": "npm:^7.1.2" - checksum: 4694e399003941e906cc1a4dceec21b4b3ad9e5b54065430c11a219b76b3bcd0b206f304d43adc870a1523ea18b46332fa983b91fadb917d06f2317c2518eee5 - languageName: node - linkType: hard - "rtl-css-js@npm:^1.16.1": version: 1.16.1 resolution: "rtl-css-js@npm:1.16.1" @@ -28093,13 +27276,6 @@ __metadata: languageName: node linkType: hard -"sourcemap-codec@npm:^1.4.8": - version: 1.4.8 - resolution: "sourcemap-codec@npm:1.4.8" - checksum: 6fc57a151e982b5c9468362690c6d062f3a0d4d8520beb68a82f319c79e7a4d7027eeb1e396de0ecc2cd19491e1d602b2d06fd444feac9b63dd43fea4c55a857 - languageName: node - linkType: hard - "space-separated-tokens@npm:^1.0.0": version: 1.1.5 resolution: "space-separated-tokens@npm:1.1.5" @@ -28788,7 +27964,7 @@ __metadata: languageName: node linkType: hard -"stylis@npm:4.2.0, stylis@npm:^4.0.6": +"stylis@npm:4.2.0": version: 4.2.0 resolution: "stylis@npm:4.2.0" checksum: 58359185275ef1f39c339ae94e598168aa6bb789f6cf0d52e726c1e7087a94e9c17f0385a28d34483dec1ffc2c75670ec714dc5603d99c3124ec83bc2b0a0f42 @@ -30789,7 +29965,7 @@ __metadata: languageName: node linkType: hard -"webpack-merge@npm:5.10.0": +"webpack-merge@npm:5.10.0, webpack-merge@npm:^5.7.3": version: 5.10.0 resolution: "webpack-merge@npm:5.10.0" dependencies: @@ -30800,16 +29976,6 @@ __metadata: languageName: node linkType: hard -"webpack-merge@npm:^5.7.3": - version: 5.9.0 - resolution: "webpack-merge@npm:5.9.0" - dependencies: - clone-deep: "npm:^4.0.1" - wildcard: "npm:^2.0.0" - checksum: d23dd1f0bad0b9821bf58443d2d29097d65cd9353046c2d8a6d7b57877ec19cf64be57cc7ef2a371a15cf9264fe6eaf8dea4015dc87487e664ffab2a28329d56 - languageName: node - linkType: hard - "webpack-sources@npm:^1.4.3": version: 1.4.3 resolution: "webpack-sources@npm:1.4.3" @@ -31024,7 +30190,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.11": +"which-typed-array@npm:^1.1.11, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": version: 1.1.11 resolution: "which-typed-array@npm:1.1.11" dependencies: @@ -31037,20 +30203,6 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": - version: 1.1.9 - resolution: "which-typed-array@npm:1.1.9" - dependencies: - available-typed-arrays: "npm:^1.0.5" - call-bind: "npm:^1.0.2" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-tostringtag: "npm:^1.0.0" - is-typed-array: "npm:^1.1.10" - checksum: 90ef760a09dcffc479138a6bc77fd2933a81a41d531f4886ae212f6edb54a0645a43a6c24de2c096aea910430035ac56b3d22a06f3d64e5163fa178d0f24e08e - languageName: node - linkType: hard - "which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1"