From f2fa4eb197a1bac38c4223c1f2d7f69652d584a5 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Tue, 18 Oct 2022 13:00:29 +0100 Subject: [PATCH] TimeseriesPanel: Fix variables in data links (#56729) (#57163) * TimeseriesPanel: Fix variables in data links * Refactor variable fix for all Timeseries panels * cr mods (cherry picked from commit 76d6e3c07547639dac073c8ea05f7dbf9346518d) Co-authored-by: Victor Marin <36818606+mdvictor@users.noreply.github.com> --- packages/grafana-data/src/index.ts | 1 + .../grafana-data/src/vector/SortedVector.ts | 4 ++ .../panel/candlestick/CandlestickPanel.tsx | 12 +++++- .../panel/timeseries/TimeSeriesPanel.tsx | 12 +++++- .../timeseries/plugins/ContextMenuPlugin.tsx | 42 ++++++++++++------- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/packages/grafana-data/src/index.ts b/packages/grafana-data/src/index.ts index 1172e5b134f..c9d92f7bff1 100644 --- a/packages/grafana-data/src/index.ts +++ b/packages/grafana-data/src/index.ts @@ -26,3 +26,4 @@ export { PanelPlugin, type SetFieldConfigOptionsArgs, type StandardOptionConfig export { createFieldConfigRegistry } from './panel/registryFactories'; export { type QueryRunner, type QueryRunnerOptions } from './types/queryRunner'; export { type GroupingToMatrixTransformerOptions } from './transformations/transformers/groupingToMatrix'; +export { getLinksSupplier } from './field/fieldOverrides'; diff --git a/packages/grafana-data/src/vector/SortedVector.ts b/packages/grafana-data/src/vector/SortedVector.ts index 0d66dff6ded..b6837bbe14f 100644 --- a/packages/grafana-data/src/vector/SortedVector.ts +++ b/packages/grafana-data/src/vector/SortedVector.ts @@ -16,6 +16,10 @@ export class SortedVector implements Vector { return this.source.get(this.order[index]); } + getOrderIndex(index: number): number { + return this.order[index]; + } + toArray(): T[] { return vectorToArray(this); } diff --git a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx index a3bb863de56..67f5d264c89 100644 --- a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx +++ b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx @@ -4,7 +4,7 @@ import React, { useMemo } from 'react'; import uPlot from 'uplot'; -import { Field, getDisplayProcessor, PanelProps } from '@grafana/data'; +import { Field, getDisplayProcessor, PanelProps, getLinksSupplier } from '@grafana/data'; import { PanelDataErrorView } from '@grafana/runtime'; import { TooltipDisplayMode } from '@grafana/schema'; import { usePanelContext, TimeSeries, TooltipPlugin, ZoomPlugin, UPlotConfigBuilder, useTheme2 } from '@grafana/ui'; @@ -243,6 +243,16 @@ export const CandlestickPanel: React.FC = ({ options={options} > {(config, alignedDataFrame) => { + alignedDataFrame.fields.forEach((field) => { + field.getLinks = getLinksSupplier( + alignedDataFrame, + field, + field.state!.scopedVars!, + replaceVariables, + timeZone + ); + }); + return ( <> diff --git a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx index a622e32b4a3..9b422fb5ad8 100644 --- a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx +++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; -import { Field, PanelProps } from '@grafana/data'; +import { Field, PanelProps, getLinksSupplier } from '@grafana/data'; import { PanelDataErrorView } from '@grafana/runtime'; import { TooltipDisplayMode } from '@grafana/schema'; import { usePanelContext, TimeSeries, TooltipPlugin, ZoomPlugin, KeyboardPlugin } from '@grafana/ui'; @@ -65,6 +65,16 @@ export const TimeSeriesPanel: React.FC = ({ options={options} > {(config, alignedDataFrame) => { + alignedDataFrame.fields.forEach((field) => { + field.getLinks = getLinksSupplier( + alignedDataFrame, + field, + field.state!.scopedVars!, + replaceVariables, + timeZone + ); + }); + return ( <> diff --git a/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx index 4e19f11ce24..d8976238285 100644 --- a/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx @@ -2,7 +2,15 @@ import { css as cssCore, Global } from '@emotion/react'; import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useClickAway } from 'react-use'; -import { CartesianCoords2D, DataFrame, getFieldDisplayName, InterpolateFunction, TimeZone } from '@grafana/data'; +import { + CartesianCoords2D, + DataFrame, + getFieldDisplayName, + InterpolateFunction, + SortedVector, + TimeZone, + ValueLinkConfig, +} from '@grafana/data'; import { ContextMenu, GraphContextMenuHeader, @@ -249,23 +257,27 @@ export const ContextMenuView: React.FC = ({ const hasLinks = field.config.links && field.config.links.length > 0; + const valueLinkConfig: ValueLinkConfig = {}; + + if (field.values instanceof SortedVector) { + valueLinkConfig.valueRowIndex = field.values.getOrderIndex(dataIdx); + } else { + valueLinkConfig.valueRowIndex = dataIdx; + } + if (hasLinks) { if (field.getLinks) { items.push({ - items: field - .getLinks({ - valueRowIndex: dataIdx, - }) - .map((link) => { - return { - label: link.title, - ariaLabel: link.title, - url: link.href, - target: link.target, - icon: link.target === '_self' ? 'link' : 'external-link-alt', - onClick: link.onClick, - }; - }), + items: field.getLinks(valueLinkConfig).map((link) => { + return { + label: link.title, + ariaLabel: link.title, + url: link.href, + target: link.target, + icon: link.target === '_self' ? 'link' : 'external-link-alt', + onClick: link.onClick, + }; + }), }); } }