diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index ef155e87be0..af320c4c6ec 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -10,6 +10,7 @@ import { DataSourceApi, DataSourceRef, DefaultTimeZone, + getNextRefId, IntervalValues, LogsDedupStrategy, LogsSortOrder, @@ -27,8 +28,6 @@ import store from 'app/core/store'; import { ExpressionDatasourceUID } from 'app/features/expressions/types'; import { QueryOptions, QueryTransaction } from 'app/types/explore'; -import { getNextRefIdChar } from './query'; - export const DEFAULT_UI_STATE = { dedupStrategy: LogsDedupStrategy.none, }; @@ -192,12 +191,12 @@ export async function generateEmptyQuery( defaultQuery = datasourceInstance.getDefaultQuery?.(CoreApp.Explore); } - return { ...defaultQuery, refId: getNextRefIdChar(queries), key: generateKey(index), datasource: datasourceRef }; + return { ...defaultQuery, refId: getNextRefId(queries), key: generateKey(index), datasource: datasourceRef }; } export const generateNewKeyAndAddRefIdIfMissing = (target: DataQuery, queries: DataQuery[], index = 0): DataQuery => { const key = generateKey(index); - const refId = target.refId || getNextRefIdChar(queries); + const refId = target.refId || getNextRefId(queries); return { ...target, refId, key }; }; @@ -218,7 +217,7 @@ export async function ensureQueries( const key = generateKey(index); let refId = query.refId; if (!refId) { - refId = getNextRefIdChar(allQueries); + refId = getNextRefId(allQueries); } // if a query has a datasource, validate it and only add it if valid diff --git a/public/app/core/utils/query.test.ts b/public/app/core/utils/query.test.ts index c0dc74e2af7..7347f870105 100644 --- a/public/app/core/utils/query.test.ts +++ b/public/app/core/utils/query.test.ts @@ -1,39 +1,11 @@ import { DataQuery } from '@grafana/data'; -import { getNextRefIdChar, queryIsEmpty } from './query'; +import { queryIsEmpty } from './query'; export interface TestQuery extends DataQuery { name?: string; } -function dataQueryHelper(ids: string[]): DataQuery[] { - return ids.map((letter) => { - return { refId: letter }; - }); -} - -const singleDataQuery: DataQuery[] = dataQueryHelper('ABCDE'.split('')); -const outOfOrderDataQuery: DataQuery[] = dataQueryHelper('ABD'.split('')); -const singleExtendedDataQuery: DataQuery[] = dataQueryHelper('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')); - -describe('Get next refId char', () => { - it('should return next char', () => { - expect(getNextRefIdChar(singleDataQuery)).toEqual('F'); - }); - - it('should get first char', () => { - expect(getNextRefIdChar([])).toEqual('A'); - }); - - it('should get the first available character if a query has been deleted out of order', () => { - expect(getNextRefIdChar(outOfOrderDataQuery)).toEqual('C'); - }); - - it('should append a new char and start from AA when Z is reached', () => { - expect(getNextRefIdChar(singleExtendedDataQuery)).toEqual('AA'); - }); -}); - describe('queryIsEmpty', () => { it('should return true if query only includes props that are defined in the DataQuery interface', () => { const testQuery: DataQuery = { refId: 'A' }; diff --git a/public/app/core/utils/query.ts b/public/app/core/utils/query.ts index ef75c918ce1..6e5f84146d8 100644 --- a/public/app/core/utils/query.ts +++ b/public/app/core/utils/query.ts @@ -1,14 +1,4 @@ -import { DataQuery, DataSourceRef } from '@grafana/data'; - -// @deprecated use the `getNextRefId` function from grafana/data instead -export const getNextRefIdChar = (queries: DataQuery[]): string => { - for (let num = 0; ; num++) { - const refId = getRefId(num); - if (!queries.some((query) => query.refId === refId)) { - return refId; - } - } -}; +import { DataQuery, DataSourceRef, getNextRefId } from '@grafana/data'; // This function checks if the query has defined properties beyond those defined in the DataQuery interface. export function queryIsEmpty(query: DataQuery): boolean { @@ -30,7 +20,7 @@ export function queryIsEmpty(query: DataQuery): boolean { export function addQuery(queries: DataQuery[], query?: Partial, datasource?: DataSourceRef): DataQuery[] { const q: DataQuery = { ...query, - refId: getNextRefIdChar(queries), + refId: getNextRefId(queries), hide: false, }; @@ -53,16 +43,6 @@ export function isLocalUrl(url: string) { return !url.match(/^http/); } -function getRefId(num: number): string { - const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - if (num < letters.length) { - return letters[num]; - } else { - return getRefId(Math.floor(num / letters.length) - 1) + letters[num % letters.length]; - } -} - /** * Returns the input value for non empty string and undefined otherwise * diff --git a/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/reducer.ts b/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/reducer.ts index 7072e664d14..1ecb1465426 100644 --- a/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/reducer.ts +++ b/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/reducer.ts @@ -1,7 +1,6 @@ import { createAction, createReducer } from '@reduxjs/toolkit'; -import { DataQuery, getDefaultRelativeTimeRange, rangeUtil, RelativeTimeRange } from '@grafana/data'; -import { getNextRefIdChar } from 'app/core/utils/query'; +import { DataQuery, getDefaultRelativeTimeRange, getNextRefId, rangeUtil, RelativeTimeRange } from '@grafana/data'; import { findDataSourceFromExpressionRecursive } from 'app/features/alerting/unified/utils/dataSourceFromExpression'; import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource'; import { isExpressionQuery } from 'app/features/expressions/guards'; @@ -213,7 +212,7 @@ const addQuery = ( queries: AlertQuery[], queryToAdd: Pick ): AlertQuery[] => { - const refId = getNextRefIdChar(queries); + const refId = getNextRefId(queries); const query: AlertQuery = { ...queryToAdd, refId, diff --git a/public/app/features/alerting/unified/utils/rule-form.ts b/public/app/features/alerting/unified/utils/rule-form.ts index 8efbb441727..9d304f3b5df 100644 --- a/public/app/features/alerting/unified/utils/rule-form.ts +++ b/public/app/features/alerting/unified/utils/rule-form.ts @@ -5,6 +5,7 @@ import { DataSourceInstanceSettings, DataSourceRef, getDefaultRelativeTimeRange, + getNextRefId, IntervalValues, rangeUtil, RelativeTimeRange, @@ -16,7 +17,6 @@ import { config, getDataSourceSrv } from '@grafana/runtime'; import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; import { sceneGraph, VizPanel } from '@grafana/scenes'; import { DataSourceJsonData } from '@grafana/schema'; -import { getNextRefIdChar } from 'app/core/utils/query'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { getDashboardSceneFor, @@ -568,12 +568,12 @@ export const panelToRuleFormValues = async ( } if (!queries.find((query) => query.datasourceUid === ExpressionDatasourceUID)) { - const [reduceExpression, _thresholdExpression] = getDefaultExpressions(getNextRefIdChar(queries), '-'); + const [reduceExpression, _thresholdExpression] = getDefaultExpressions(getNextRefId(queries), '-'); queries.push(reduceExpression); const [_reduceExpression, thresholdExpression] = getDefaultExpressions( reduceExpression.refId, - getNextRefIdChar(queries) + getNextRefId(queries) ); queries.push(thresholdExpression); } @@ -638,12 +638,12 @@ export const scenesPanelToRuleFormValues = async (vizPanel: VizPanel): Promise

query.datasourceUid === ExpressionDatasourceUID)) { - const [reduceExpression, _thresholdExpression] = getDefaultExpressions(getNextRefIdChar(grafanaQueries), '-'); + const [reduceExpression, _thresholdExpression] = getDefaultExpressions(getNextRefId(grafanaQueries), '-'); grafanaQueries.push(reduceExpression); const [_reduceExpression, thresholdExpression] = getDefaultExpressions( reduceExpression.refId, - getNextRefIdChar(grafanaQueries) + getNextRefId(grafanaQueries) ); grafanaQueries.push(thresholdExpression); } diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 97d58089a15..492d34afd2e 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -19,12 +19,12 @@ import { getPanelOptionsWithDefaults, isStandardFieldProp, restoreCustomOverrideRules, + getNextRefId, } from '@grafana/data'; import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; import { LibraryPanel, LibraryPanelRef } from '@grafana/schema'; import config from 'app/core/config'; import { safeStringifyValue } from 'app/core/utils/explore'; -import { getNextRefIdChar } from 'app/core/utils/query'; import { QueryGroupOptions } from 'app/types'; import { PanelOptionsChangedEvent, @@ -281,7 +281,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { if (this.targets && isArray(this.targets)) { for (const query of this.targets) { if (!query.refId) { - query.refId = getNextRefIdChar(this.targets); + query.refId = getNextRefId(this.targets); } } } @@ -564,7 +564,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { addQuery(query?: Partial) { query = query || { refId: 'A' }; - query.refId = getNextRefIdChar(this.targets); + query.refId = getNextRefId(this.targets); this.targets.push(query as DataQuery); this.configRev++; } diff --git a/public/app/features/explore/QueryRows.tsx b/public/app/features/explore/QueryRows.tsx index 6911ca3a49b..59ad9d32208 100644 --- a/public/app/features/explore/QueryRows.tsx +++ b/public/app/features/explore/QueryRows.tsx @@ -1,10 +1,9 @@ import { createSelector } from '@reduxjs/toolkit'; import React, { useCallback, useMemo } from 'react'; -import { CoreApp } from '@grafana/data'; +import { CoreApp, getNextRefId } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; import { DataQuery } from '@grafana/schema'; -import { getNextRefIdChar } from 'app/core/utils/query'; import { useDispatch, useSelector } from 'app/types'; import { getDatasourceSrv } from '../plugins/datasource_srv'; @@ -58,7 +57,7 @@ export const QueryRows = ({ exploreId }: Props) => { const onAddQuery = useCallback( (query: DataQuery) => { - onChange([...queries, { ...query, refId: getNextRefIdChar(queries) }]); + onChange([...queries, { ...query, refId: getNextRefId(queries) }]); }, [onChange, queries] ); diff --git a/public/app/features/explore/utils/queries.ts b/public/app/features/explore/utils/queries.ts index 1bb03a45d63..25dc126d8d5 100644 --- a/public/app/features/explore/utils/queries.ts +++ b/public/app/features/explore/utils/queries.ts @@ -1,5 +1,5 @@ +import { getNextRefId } from '@grafana/data'; import { DataQuery } from '@grafana/schema'; -import { getNextRefIdChar } from 'app/core/utils/query'; /** * Makes sure all the queries have unique (and valid) refIds @@ -19,7 +19,7 @@ export function withUniqueRefIds(queries: DataQuery[]): DataQuery[] { return query; } - const refId = getNextRefIdChar(queries); + const refId = getNextRefId(queries); refIds.add(refId); const newQuery = { diff --git a/public/app/features/query/state/updateQueries.ts b/public/app/features/query/state/updateQueries.ts index dbeb4cc2d3e..e8464ac40f5 100644 --- a/public/app/features/query/state/updateQueries.ts +++ b/public/app/features/query/state/updateQueries.ts @@ -1,8 +1,7 @@ -import { CoreApp, DataSourceApi, hasQueryExportSupport, hasQueryImportSupport } from '@grafana/data'; +import { CoreApp, DataSourceApi, getNextRefId, hasQueryExportSupport, hasQueryImportSupport } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; import { isExpressionReference } from '@grafana/runtime/src/utils/DataSourceWithBackend'; import { DataQuery } from '@grafana/schema'; -import { getNextRefIdChar } from 'app/core/utils/query'; export async function updateQueries( nextDS: DataSourceApi, @@ -49,7 +48,7 @@ export async function updateQueries( currUid = templateSrv.replace(currentQuery.datasource.uid); } if (currUid === nextUid && currIsTemplate === nextIsTemplate) { - currentQuery.refId = getNextRefIdChar(reduced); + currentQuery.refId = getNextRefId(reduced); return reduced.concat([currentQuery]); } }