From 1e7c27e6364b57725e15b3afee1d418e591b8e34 Mon Sep 17 00:00:00 2001 From: Connor Lindsey Date: Tue, 14 Mar 2023 09:12:46 -0600 Subject: [PATCH] Explore: Add range option to internal data links (#64063) * Add range option to internal data links * Add test for internal link time range --- .../src/field/fieldOverrides.test.ts | 60 +++++++++++++++++++ .../grafana-data/src/field/fieldOverrides.ts | 2 +- packages/grafana-data/src/types/dataLink.ts | 2 + 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/grafana-data/src/field/fieldOverrides.test.ts b/packages/grafana-data/src/field/fieldOverrides.test.ts index bd7f66666ea..8f615f704bf 100644 --- a/packages/grafana-data/src/field/fieldOverrides.test.ts +++ b/packages/grafana-data/src/field/fieldOverrides.test.ts @@ -1,4 +1,5 @@ import { ArrayDataFrame, MutableDataFrame, toDataFrame } from '../dataframe'; +import { rangeUtil } from '../datetime'; import { createTheme } from '../themes'; import { FieldMatcherID } from '../transformations'; import { @@ -665,6 +666,65 @@ describe('getLinksSupplier', () => { ); }); + it('handles time range on internal links', () => { + locationUtil.initialize({ + config: { appSubUrl: '' } as GrafanaConfig, + getVariablesUrlParams: () => ({}), + getTimeRangeForUrl: () => ({ from: 'now-7d', to: 'now' }), + }); + + const datasourceUid = '1234'; + const range = rangeUtil.relativeToTimeRange({ from: 600, to: 0 }); + const f0 = new MutableDataFrame({ + name: 'A', + fields: [ + { + name: 'message', + type: FieldType.string, + values: [10, 20], + config: { + links: [ + { + url: '', + title: '', + internal: { + datasourceUid: datasourceUid, + datasourceName: 'testDS', + query: '12345', + range, + }, + }, + ], + }, + display: (v) => ({ numeric: v, text: String(v) }), + }, + ], + }); + + const supplier = getLinksSupplier( + f0, + f0.fields[0], + {}, + // We do not need to interpolate anything for this test + (value, vars, format) => value + ); + + const links = supplier({ valueRowIndex: 0 }); + const rangeStr = JSON.stringify({ + from: range.from.toISOString(), + to: range.to.toISOString(), + }); + const encodeURIParams = `{"range":${rangeStr},"datasource":"${datasourceUid}","queries":["12345"]}`; + expect(links.length).toBe(1); + expect(links[0]).toEqual( + expect.objectContaining({ + title: 'testDS', + href: `/explore?left=${encodeURIComponent(encodeURIParams)}`, + onClick: undefined, + }) + ); + }); + describe('dynamic links', () => { beforeEach(() => { locationUtil.initialize({ diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index 7f0b3a5c289..12f82e2970a 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -451,7 +451,7 @@ export const getLinksSupplier = internalLink: link.internal, scopedVars: variables, field, - range: {} as any, + range: link.internal.range ?? ({} as any), replaceVariables, }); } diff --git a/packages/grafana-data/src/types/dataLink.ts b/packages/grafana-data/src/types/dataLink.ts index 3b9db274d94..d8f4c45cf9a 100644 --- a/packages/grafana-data/src/types/dataLink.ts +++ b/packages/grafana-data/src/types/dataLink.ts @@ -1,6 +1,7 @@ import { ExplorePanelsState } from './explore'; import { InterpolateFunction } from './panel'; import { DataQuery } from './query'; +import { TimeRange } from './time'; /** * Callback info for DataLink click events @@ -61,6 +62,7 @@ export interface InternalDataLink { datasourceName: string; // used as a title if `DataLink.title` is empty panelsState?: ExplorePanelsState; transformations?: DataLinkTransformationConfig[]; + range?: TimeRange; } export type LinkTarget = '_blank' | '_self' | undefined;