diff --git a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx
index cb17a7792fd..f66b3d554b6 100644
--- a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx
+++ b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx
@@ -321,6 +321,7 @@ export const CandlestickPanel = ({
/>
)}
)}
{
return links;
};
-export const getAllFrameActions = (dataFrame: DataFrame) => {};
-
export const getFieldActions = (
dataFrame: DataFrame,
field: Field,
@@ -31,19 +29,22 @@ export const getFieldActions = (
rowIndex: number
) => {
const actions: Array> = [];
- const actionLookup = new Set();
- const actionsModel = getActions(dataFrame, field, field.state!.scopedVars!, replaceVars, field.config.actions ?? [], {
- valueRowIndex: rowIndex,
- });
+ if (field.state?.scopedVars) {
+ const actionLookup = new Set();
- actionsModel.forEach((action) => {
- const key = `${action.title}`;
- if (!actionLookup.has(key)) {
- actions.push(action);
- actionLookup.add(key);
- }
- });
+ const actionsModel = getActions(dataFrame, field, field.state.scopedVars, replaceVars, field.config.actions ?? [], {
+ valueRowIndex: rowIndex,
+ });
+
+ 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 bc198392c05..e254fdc3e91 100644
--- a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx
+++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx
@@ -191,6 +191,7 @@ export const TimeSeriesPanel = ({
{!isVerticallyOriented && (
<>
void;
canvasRegionRendering?: boolean;
+ replaceVariables: InterpolateFunction;
}
// TODO: batch by color, use Path2D objects
@@ -62,6 +70,7 @@ export const AnnotationsPlugin2 = ({
config,
newRange,
setNewRange,
+ replaceVariables,
canvasRegionRendering = true,
}: AnnotationsPluginProps) => {
const [plot, setPlot] = useState();
@@ -73,6 +82,9 @@ export const AnnotationsPlugin2 = ({
const [_, forceUpdate] = useReducer((x) => x + 1, 0);
+ const { canExecuteActions } = usePanelContext();
+ const userCanExecuteActions = canExecuteActions?.() ?? false;
+
const annos = useMemo(() => {
let annos = annotations.filter(
(frame) => frame.name !== 'exemplar' && frame.length > 0 && frame.fields.some((f) => f.name === 'time')
@@ -258,6 +270,8 @@ export const AnnotationsPlugin2 = ({
key={`${frameIdx}:${i}`}
exitWipEdit={isWip ? exitWipEdit : null}
portalRoot={portalRoot}
+ canExecuteActions={userCanExecuteActions}
+ replaceVariables={replaceVariables}
/>
);
}
diff --git a/public/app/plugins/panel/timeseries/plugins/annotations2/AnnotationMarker2.tsx b/public/app/plugins/panel/timeseries/plugins/annotations2/AnnotationMarker2.tsx
index 07ec7514b83..4b5cf62bdf7 100644
--- a/public/app/plugins/panel/timeseries/plugins/annotations2/AnnotationMarker2.tsx
+++ b/public/app/plugins/panel/timeseries/plugins/annotations2/AnnotationMarker2.tsx
@@ -5,11 +5,11 @@ import { useState } from 'react';
import * as React from 'react';
import { createPortal } from 'react-dom';
-import { DataFrame, GrafanaTheme2, LinkModel } from '@grafana/data';
+import { ActionModel, DataFrame, GrafanaTheme2, InterpolateFunction, LinkModel } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { TimeZone } from '@grafana/schema';
import { floatingUtils, useStyles2 } from '@grafana/ui';
-import { getDataLinks } from 'app/plugins/panel/status-history/utils';
+import { getDataLinks, getFieldActions } from 'app/plugins/panel/status-history/utils';
import { AnnotationEditor2 } from './AnnotationEditor2';
import { AnnotationTooltip2 } from './AnnotationTooltip2';
@@ -23,6 +23,8 @@ interface AnnoBoxProps {
timeZone: TimeZone;
exitWipEdit?: null | (() => void);
portalRoot: HTMLElement;
+ canExecuteActions: boolean;
+ replaceVariables: InterpolateFunction;
}
const STATE_DEFAULT = 0;
@@ -38,6 +40,8 @@ export const AnnotationMarker2 = ({
exitWipEdit,
timeZone,
portalRoot,
+ replaceVariables,
+ canExecuteActions,
}: AnnoBoxProps) => {
const styles = useStyles2(getStyles);
const placement = 'bottom';
@@ -52,10 +56,15 @@ export const AnnotationMarker2 = ({
});
const links: LinkModel[] = [];
+ const actions: ActionModel[] = [];
if (STATE_HOVERED) {
frame.fields.forEach((field) => {
links.push(...getDataLinks(field, annoIdx));
+
+ if (canExecuteActions) {
+ actions.push(...getFieldActions(frame, field, replaceVariables, annoIdx));
+ }
});
}
@@ -67,6 +76,7 @@ export const AnnotationMarker2 = ({
timeZone={timeZone}
onEdit={() => setState(STATE_EDITING)}
links={links}
+ actions={actions}
/>
) : state === STATE_EDITING ? (
void;
links?: LinkModel[];
+ actions?: ActionModel[];
}
const retFalse = () => false;
-export const AnnotationTooltip2 = ({ annoVals, annoIdx, timeZone, onEdit, links = [] }: Props) => {
+export const AnnotationTooltip2 = ({ annoVals, annoIdx, timeZone, onEdit, links = [], actions = [] }: Props) => {
const annoId = annoVals.id?.[annoIdx];
const styles = useStyles2(getStyles);
@@ -110,7 +111,7 @@ export const AnnotationTooltip2 = ({ annoVals, annoIdx, timeZone, onEdit, links
- {links.length > 0 && }
+ {(links.length > 0 || actions.length > 0) && }
);
};