diff --git a/packages/grafana-data/src/field/overrides/processors.ts b/packages/grafana-data/src/field/overrides/processors.ts index 9846c1c3ef3..8c8542fd6ff 100644 --- a/packages/grafana-data/src/field/overrides/processors.ts +++ b/packages/grafana-data/src/field/overrides/processors.ts @@ -1,3 +1,4 @@ +import { Action } from '../../types/action'; import { Field } from '../../types/dataFrame'; import { DataLink } from '../../types/dataLink'; import { FieldOverrideContext } from '../../types/fieldOverrides'; @@ -59,6 +60,15 @@ export const dataLinksOverrideProcessor = ( return value; }; +export const actionsOverrideProcessor = ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: any, + _context: FieldOverrideContext, + _settings?: DataLinksFieldConfigSettings +): Action[] => { + return value; +}; + export interface ValueMappingFieldConfigSettings {} export const valueMappingsOverrideProcessor = ( diff --git a/packages/grafana-data/src/types/dataFrame.ts b/packages/grafana-data/src/types/dataFrame.ts index 291f88b2333..4a0f8adbe58 100644 --- a/packages/grafana-data/src/types/dataFrame.ts +++ b/packages/grafana-data/src/types/dataFrame.ts @@ -1,6 +1,7 @@ import { HideSeriesConfig } from '@grafana/schema'; import { ScopedVars } from './ScopedVars'; +import { Action } from './action'; import { QueryResultBase, Labels, NullValueMode } from './data'; import { DataLink, LinkModel } from './dataLink'; import { DecimalCount, DisplayProcessor, DisplayValue, DisplayValueAlignmentFactors } from './displayValue'; @@ -98,6 +99,8 @@ export interface FieldConfig { // The behavior when clicking on a result links?: DataLink[]; + actions?: Action[]; + // Alternative to empty string noValue?: string; diff --git a/pkg/registry/apis/iam/common/common_test.go b/pkg/registry/apis/iam/common/common_test.go index 0f1d359842f..c07c2cb63f9 100644 --- a/pkg/registry/apis/iam/common/common_test.go +++ b/pkg/registry/apis/iam/common/common_test.go @@ -31,7 +31,7 @@ func TestList(t *testing.T) { res, err := List(ctx, "items", nil, Pagination{Limit: 2}, func(ctx context.Context, ns claims.NamespaceInfo, p Pagination) (*ListResponse[item], error) { return &ListResponse[item]{ - Items: []item{item{"1"}, item{"2"}}, + Items: []item{{"1"}, {"2"}}, }, nil }) assert.NoError(t, err) @@ -47,7 +47,7 @@ func TestList(t *testing.T) { }) res, err := List(ctx, "items", a, Pagination{Limit: 2}, func(ctx context.Context, ns claims.NamespaceInfo, p Pagination) (*ListResponse[item], error) { return &ListResponse[item]{ - Items: []item{item{"1"}, item{"2"}}, + Items: []item{{"1"}, {"2"}}, }, nil }) assert.NoError(t, err) @@ -70,13 +70,13 @@ func TestList(t *testing.T) { res, err := List(ctx, "items", a, Pagination{Limit: 2}, func(ctx context.Context, ns claims.NamespaceInfo, p Pagination) (*ListResponse[item], error) { if called { return &ListResponse[item]{ - Items: []item{item{"3"}}, + Items: []item{{"3"}}, }, nil } called = true return &ListResponse[item]{ - Items: []item{item{"1"}, item{"2"}}, + Items: []item{{"1"}, {"2"}}, Continue: 3, }, nil }) diff --git a/public/app/core/components/OptionsUI/actions.tsx b/public/app/core/components/OptionsUI/actions.tsx new file mode 100644 index 00000000000..0d5c182380a --- /dev/null +++ b/public/app/core/components/OptionsUI/actions.tsx @@ -0,0 +1,15 @@ +import { Action, DataLinksFieldConfigSettings, StandardEditorProps, VariableSuggestionsScope } from '@grafana/data'; +import { ActionsInlineEditor } from 'app/features/actions/ActionsInlineEditor'; + +type Props = StandardEditorProps; + +export const ActionsValueEditor = ({ value, onChange, context }: Props) => { + return ( + (context.getSuggestions ? context.getSuggestions(VariableSuggestionsScope.Values) : [])} + /> + ); +}; diff --git a/public/app/core/components/OptionsUI/registry.tsx b/public/app/core/components/OptionsUI/registry.tsx index 481395d1744..cf4e0450c18 100644 --- a/public/app/core/components/OptionsUI/registry.tsx +++ b/public/app/core/components/OptionsUI/registry.tsx @@ -26,7 +26,10 @@ import { displayNameOverrideProcessor, FieldNamePickerConfigSettings, booleanOverrideProcessor, + Action, } from '@grafana/data'; +import { actionsOverrideProcessor } from '@grafana/data/src/field/overrides/processors'; +import { config } from '@grafana/runtime'; import { FieldConfig } from '@grafana/schema'; import { RadioButtonGroup, TimeZonePicker, Switch } from '@grafana/ui'; import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker'; @@ -34,6 +37,7 @@ import { ThresholdsValueEditor } from 'app/features/dimensions/editors/Threshold import { ValueMappingsEditor } from 'app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor'; import { DashboardPicker, DashboardPickerOptions } from './DashboardPicker'; +import { ActionsValueEditor } from './actions'; import { ColorValueEditor, ColorValueEditorSettings } from './color'; import { FieldColorEditor } from './fieldColor'; import { DataLinksValueEditor } from './links'; @@ -143,6 +147,13 @@ export const getAllOptionEditors = () => { editor: DataLinksValueEditor, }; + const actions: StandardEditorsRegistryItem = { + id: 'actions', + name: 'Actions', + description: 'Allows defining actions', + editor: ActionsValueEditor, + }; + const statsPicker: StandardEditorsRegistryItem = { id: 'stats-picker', name: 'Stats Picker', @@ -194,6 +205,7 @@ export const getAllOptionEditors = () => { select, unit, links, + actions, statsPicker, strings, timeZone, @@ -336,6 +348,8 @@ export const getAllStandardFieldConfigs = () => { category, }; + const dataLinksCategory = config.featureToggles.vizActions ? 'Data links and actions' : 'Data links'; + const links: FieldConfigPropertyItem = { id: 'links', path: 'links', @@ -347,10 +361,26 @@ export const getAllStandardFieldConfigs = () => { placeholder: '-', }, shouldApply: () => true, - category: ['Data links'], + category: [dataLinksCategory], getItemsCount: (value) => (value ? value.length : 0), }; + const actions: FieldConfigPropertyItem = { + id: 'actions', + path: 'actions', + name: 'Actions', + editor: standardEditorsRegistry.get('actions').editor, + override: standardEditorsRegistry.get('actions').editor, + process: actionsOverrideProcessor, + settings: { + placeholder: '-', + }, + shouldApply: () => true, + category: [dataLinksCategory], + getItemsCount: (value) => (value ? value.length : 0), + showIf: () => config.featureToggles.vizActions, + }; + const color: FieldConfigPropertyItem = { id: 'color', path: 'color', @@ -415,5 +445,19 @@ export const getAllStandardFieldConfigs = () => { category, }; - return [unit, min, max, fieldMinMax, decimals, displayName, color, noValue, links, mappings, thresholds, filterable]; + return [ + unit, + min, + max, + fieldMinMax, + decimals, + displayName, + color, + noValue, + links, + actions, + mappings, + thresholds, + filterable, + ]; }; diff --git a/public/app/features/transformers/suggestionsInput/SuggestionsInput.tsx b/public/app/features/transformers/suggestionsInput/SuggestionsInput.tsx index 0a02cf6b3d9..09c9066e9cb 100644 --- a/public/app/features/transformers/suggestionsInput/SuggestionsInput.tsx +++ b/public/app/features/transformers/suggestionsInput/SuggestionsInput.tsx @@ -221,6 +221,7 @@ export const SuggestionsInput = ({ {...inputProps} ref={handleRef as unknown as React.RefObject} autoFocus={autoFocus} + rows={5} /> )} diff --git a/public/app/plugins/panel/barchart/BarChartPanel.tsx b/public/app/plugins/panel/barchart/BarChartPanel.tsx index ec7296fcb73..ce83432e202 100644 --- a/public/app/plugins/panel/barchart/BarChartPanel.tsx +++ b/public/app/plugins/panel/barchart/BarChartPanel.tsx @@ -24,16 +24,7 @@ const charWidth = measureText('M', UPLOT_AXIS_FONT_SIZE).width; const toRads = Math.PI / 180; export const BarChartPanel = (props: PanelProps) => { - const { - data, - options, - fieldConfig, - width, - height, - timeZone, - id, - // replaceVariables - } = props; + const { data, options, fieldConfig, width, height, timeZone, id, replaceVariables } = props; // will need this if joining on time to re-create data links // const { dataLinkPostProcessor } = usePanelContext(); @@ -177,6 +168,7 @@ export const BarChartPanel = (props: PanelProps) => { sortOrder={options.tooltip.sort} isPinned={isPinned} maxHeight={options.tooltip.maxHeight} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx index 319b127b227..acddd0a5727 100644 --- a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx +++ b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx @@ -306,6 +306,7 @@ export const CandlestickPanel = ({ isPinned={isPinned} annotate={enableAnnotationCreation ? annotate : undefined} maxHeight={options.tooltip.maxHeight} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/heatmap/HeatmapPanel.tsx b/public/app/plugins/panel/heatmap/HeatmapPanel.tsx index a3a9896b251..06042a4080e 100644 --- a/public/app/plugins/panel/heatmap/HeatmapPanel.tsx +++ b/public/app/plugins/panel/heatmap/HeatmapPanel.tsx @@ -219,6 +219,7 @@ export const HeatmapPanel = ({ annotate={enableAnnotationCreation ? annotate : undefined} maxHeight={options.tooltip.maxHeight} maxWidth={options.tooltip.maxWidth} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/heatmap/HeatmapTooltip.tsx b/public/app/plugins/panel/heatmap/HeatmapTooltip.tsx index 924c287fd23..010fbdfa09c 100644 --- a/public/app/plugins/panel/heatmap/HeatmapTooltip.tsx +++ b/public/app/plugins/panel/heatmap/HeatmapTooltip.tsx @@ -3,11 +3,13 @@ import * as React from 'react'; import uPlot from 'uplot'; import { + ActionModel, DataFrameType, Field, FieldType, formattedValueToString, getFieldDisplayName, + InterpolateFunction, LinkModel, PanelData, } from '@grafana/data'; @@ -16,14 +18,14 @@ import { TooltipDisplayMode, useTheme2 } from '@grafana/ui'; import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent'; import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter'; import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader'; +import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTooltipWrapper'; import { ColorIndicator, ColorPlacement, VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types'; import { ColorScale } from 'app/core/components/ColorScale/ColorScale'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import { isHeatmapCellsDense, readHeatmapRowsCustomMeta } from 'app/features/transformers/calculateHeatmap/heatmap'; import { DataHoverView } from 'app/features/visualization/data-hover/DataHoverView'; -import { VizTooltipWrapper } from '../../../../../packages/grafana-ui/src/components/VizTooltip/VizTooltipWrapper'; -import { getDataLinks } from '../status-history/utils'; +import { getDataLinks, getFieldActions } from '../status-history/utils'; import { isTooltipScrollable } from '../timeseries/utils'; import { HeatmapData } from './fields'; @@ -43,6 +45,7 @@ interface HeatmapTooltipProps { annotate?: () => void; maxHeight?: number; maxWidth?: number; + replaceVariables: InterpolateFunction; } export const HeatmapTooltip = (props: HeatmapTooltipProps) => { @@ -73,6 +76,7 @@ const HeatmapHoverCell = ({ annotate, maxHeight, maxWidth, + replaceVariables, }: HeatmapTooltipProps) => { const index = dataIdxs[1]!; const data = dataRef.current; @@ -291,6 +295,7 @@ const HeatmapHoverCell = ({ if (isPinned) { let links: Array> = []; + let actions: Array> = []; const linksField = data.series?.fields[yValueIdx + 1]; @@ -301,9 +306,11 @@ const HeatmapHoverCell = ({ if (visible && hasLinks) { links = getDataLinks(linksField, xValueIdx); } + + actions = getFieldActions(data.series!, linksField, replaceVariables); } - footer = ; + footer = ; } let can = useRef(null); diff --git a/public/app/plugins/panel/histogram/HistogramTooltip.tsx b/public/app/plugins/panel/histogram/HistogramTooltip.tsx index 4fee3eb5c11..53bfd3bcfc6 100644 --- a/public/app/plugins/panel/histogram/HistogramTooltip.tsx +++ b/public/app/plugins/panel/histogram/HistogramTooltip.tsx @@ -5,10 +5,10 @@ import { SortOrder, TooltipDisplayMode } from '@grafana/schema/dist/esm/common/c import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent'; import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter'; import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader'; +import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTooltipWrapper'; import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types'; import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils'; -import { VizTooltipWrapper } from '../../../../../packages/grafana-ui/src/components/VizTooltip/VizTooltipWrapper'; import { getDataLinks } from '../status-history/utils'; import { isTooltipScrollable } from '../timeseries/utils'; diff --git a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx index 202de0f1035..df2df2c811c 100644 --- a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx +++ b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx @@ -198,6 +198,7 @@ export const StateTimelinePanel = ({ annotate={enableAnnotationCreation ? annotate : undefined} withDuration={true} maxHeight={options.tooltip.maxHeight} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/state-timeline/StateTimelineTooltip2.tsx b/public/app/plugins/panel/state-timeline/StateTimelineTooltip2.tsx index efb1d4ff1db..b4ff1a07c21 100644 --- a/public/app/plugins/panel/state-timeline/StateTimelineTooltip2.tsx +++ b/public/app/plugins/panel/state-timeline/StateTimelineTooltip2.tsx @@ -6,12 +6,12 @@ import { TooltipDisplayMode } from '@grafana/ui'; import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent'; import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter'; import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader'; +import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTooltipWrapper'; import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types'; import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils'; import { findNextStateIndex, fmtDuration } from 'app/core/components/TimelineChart/utils'; -import { VizTooltipWrapper } from '../../../../../packages/grafana-ui/src/components/VizTooltip/VizTooltipWrapper'; -import { getDataLinks } from '../status-history/utils'; +import { getDataLinks, getFieldActions } from '../status-history/utils'; import { TimeSeriesTooltipProps } from '../timeseries/TimeSeriesTooltip'; import { isTooltipScrollable } from '../timeseries/utils'; @@ -31,6 +31,7 @@ export const StateTimelineTooltip2 = ({ timeRange, withDuration, maxHeight, + replaceVariables, }: StateTimelineTooltip2Props) => { const xField = series.fields[0]; @@ -70,8 +71,9 @@ export const StateTimelineTooltip2 = ({ const field = series.fields[seriesIdx]; const dataIdx = dataIdxs[seriesIdx]!; const links = getDataLinks(field, dataIdx); + const actions = getFieldActions(series, field, replaceVariables!); - footer = ; + footer = ; } const headerItem: VizTooltipItem = { diff --git a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx index 475ad75556f..5f09c96ca52 100644 --- a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx +++ b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx @@ -130,6 +130,7 @@ export const StatusHistoryPanel = ({ annotate={enableAnnotationCreation ? annotate : undefined} withDuration={false} maxHeight={options.tooltip.maxHeight} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/status-history/utils.ts b/public/app/plugins/panel/status-history/utils.ts index f4775386ce1..b5807d0b2cb 100644 --- a/public/app/plugins/panel/status-history/utils.ts +++ b/public/app/plugins/panel/status-history/utils.ts @@ -1,4 +1,7 @@ -import { Field, LinkModel } from '@grafana/data'; +import { ActionModel, Field, InterpolateFunction, LinkModel } from '@grafana/data'; +import { DataFrame } from '@grafana/data/'; +import { config } from '@grafana/runtime'; +import { getActions } from 'app/features/actions/utils'; export const getDataLinks = (field: Field, rowIdx: number) => { const links: Array> = []; @@ -20,3 +23,31 @@ export const getDataLinks = (field: Field, rowIdx: number) => { return links; }; + +export const getFieldActions = (dataFrame: DataFrame, field: Field, replaceVars: InterpolateFunction) => { + if (!config.featureToggles?.vizActions) { + return []; + } + + const actions: Array> = []; + const actionLookup = new Set(); + + const actionsModel = getActions( + dataFrame, + field, + field.state!.scopedVars!, + replaceVars, + field.config.actions ?? [], + {} + ); + + actionsModel.forEach((action) => { + const key = `${action.title}`; + if (!actionLookup.has(key)) { + actions.push(action); + actionLookup.add(key); + } + }); + + return actions; +}; diff --git a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx index 32ec1c7b62a..fb9076f8a01 100644 --- a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx +++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx @@ -131,6 +131,7 @@ export const TimeSeriesPanel = ({ isPinned={isPinned} annotate={enableAnnotationCreation ? annotate : undefined} maxHeight={options.tooltip.maxHeight} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/timeseries/TimeSeriesTooltip.tsx b/public/app/plugins/panel/timeseries/TimeSeriesTooltip.tsx index eb6faf49742..2c30eb643c8 100644 --- a/public/app/plugins/panel/timeseries/TimeSeriesTooltip.tsx +++ b/public/app/plugins/panel/timeseries/TimeSeriesTooltip.tsx @@ -1,16 +1,15 @@ -import { css } from '@emotion/css'; import { ReactNode } from 'react'; -import { DataFrame, Field, FieldType, formattedValueToString } from '@grafana/data'; +import { DataFrame, Field, FieldType, formattedValueToString, InterpolateFunction } from '@grafana/data'; import { SortOrder, TooltipDisplayMode } from '@grafana/schema/dist/esm/common/common.gen'; import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent'; import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter'; import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader'; +import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTooltipWrapper'; import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types'; import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils'; -import { VizTooltipWrapper } from '../../../../../packages/grafana-ui/src/components/VizTooltip/VizTooltipWrapper'; -import { getDataLinks } from '../status-history/utils'; +import { getDataLinks, getFieldActions } from '../status-history/utils'; import { fmt } from '../xychart/utils'; import { isTooltipScrollable } from './utils'; @@ -36,6 +35,8 @@ export interface TimeSeriesTooltipProps { annotate?: () => void; maxHeight?: number; + + replaceVariables?: InterpolateFunction; } export const TimeSeriesTooltip = ({ @@ -48,6 +49,7 @@ export const TimeSeriesTooltip = ({ isPinned, annotate, maxHeight, + replaceVariables, }: TimeSeriesTooltipProps) => { const xField = series.fields[0]; const xVal = formattedValueToString(xField.display!(xField.values[dataIdxs[0]!])); @@ -77,8 +79,9 @@ export const TimeSeriesTooltip = ({ const field = series.fields[seriesIdx]; const dataIdx = dataIdxs[seriesIdx]!; const links = getDataLinks(field, dataIdx); + const actions = getFieldActions(series, field, replaceVariables!); - footer = ; + footer = ; } const headerItem: VizTooltipItem | null = xField.config.custom?.hideFrom?.tooltip @@ -101,10 +104,3 @@ export const TimeSeriesTooltip = ({ ); }; - -export const getStyles = () => ({ - wrapper: css({ - display: 'flex', - flexDirection: 'column', - }), -}); diff --git a/public/app/plugins/panel/trend/TrendPanel.tsx b/public/app/plugins/panel/trend/TrendPanel.tsx index 757789d7e87..0d7d398ab01 100644 --- a/public/app/plugins/panel/trend/TrendPanel.tsx +++ b/public/app/plugins/panel/trend/TrendPanel.tsx @@ -130,6 +130,7 @@ export const TrendPanel = ({ sortOrder={options.tooltip.sort} isPinned={isPinned} maxHeight={options.tooltip.maxHeight} + replaceVariables={replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/xychart/XYChartTooltip.tsx b/public/app/plugins/panel/xychart/XYChartTooltip.tsx index 9ef55c0df9a..b8046935bb3 100644 --- a/public/app/plugins/panel/xychart/XYChartTooltip.tsx +++ b/public/app/plugins/panel/xychart/XYChartTooltip.tsx @@ -5,9 +5,9 @@ import { alpha } from '@grafana/data/src/themes/colorManipulator'; import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent'; import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter'; import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader'; +import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTooltipWrapper'; import { ColorIndicator, VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types'; -import { VizTooltipWrapper } from '../../../../../packages/grafana-ui/src/components/VizTooltip/VizTooltipWrapper'; import { getDataLinks } from '../status-history/utils'; import { Options } from './panelcfg.gen'; diff --git a/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx b/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx index cbc2c80c656..f22fd8248e1 100644 --- a/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx +++ b/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx @@ -122,6 +122,7 @@ export const XYChartPanel2 = (props: Props2) => { dismiss={dismiss} isPinned={isPinned} seriesIdx={seriesIdx!} + replaceVariables={props.replaceVariables} /> ); }} diff --git a/public/app/plugins/panel/xychart/v2/XYChartTooltip.tsx b/public/app/plugins/panel/xychart/v2/XYChartTooltip.tsx index a680b9d2a67..4a6f590c2f9 100644 --- a/public/app/plugins/panel/xychart/v2/XYChartTooltip.tsx +++ b/public/app/plugins/panel/xychart/v2/XYChartTooltip.tsx @@ -1,14 +1,14 @@ import { ReactNode } from 'react'; -import { DataFrame } from '@grafana/data'; +import { DataFrame, InterpolateFunction } from '@grafana/data'; import { alpha } from '@grafana/data/src/themes/colorManipulator'; import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent'; import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter'; import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader'; +import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTooltipWrapper'; import { ColorIndicator, VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types'; -import { VizTooltipWrapper } from '../../../../../../packages/grafana-ui/src/components/VizTooltip/VizTooltipWrapper'; -import { getDataLinks } from '../../status-history/utils'; +import { getDataLinks, getFieldActions } from '../../status-history/utils'; import { XYSeries } from './types2'; import { fmt } from './utils'; @@ -20,6 +20,7 @@ export interface Props { dismiss: () => void; data: DataFrame[]; xySeries: XYSeries[]; + replaceVariables: InterpolateFunction; } function stripSeriesName(fieldName: string, seriesName: string) { @@ -30,7 +31,7 @@ function stripSeriesName(fieldName: string, seriesName: string) { return fieldName; } -export const XYChartTooltip = ({ dataIdxs, seriesIdx, data, xySeries, dismiss, isPinned }: Props) => { +export const XYChartTooltip = ({ dataIdxs, seriesIdx, data, xySeries, dismiss, isPinned, replaceVariables }: Props) => { const rowIndex = dataIdxs.find((idx) => idx !== null)!; const series = xySeries[seriesIdx! - 1]; @@ -94,8 +95,10 @@ export const XYChartTooltip = ({ dataIdxs, seriesIdx, data, xySeries, dismiss, i if (isPinned && seriesIdx != null) { const links = getDataLinks(yField, rowIndex); + const yFieldFrame = data.find((frame) => frame.fields.includes(yField))!; + const actions = getFieldActions(yFieldFrame, yField, replaceVariables); - footer = ; + footer = ; } return (