Canvas: Add option to disable tooltips for one-click elements (#109937)
This commit is contained in:
@@ -282,6 +282,8 @@ The options are:
|
||||
- **Enabled** - Show a tooltip when the cursor hovers over an element.
|
||||
- **Disabled** - Tooltips are not shown on hover.
|
||||
|
||||
The **Disable for one-click elements** setting allows hiding tooltips on elements that have one-click functionality enabled. This prevents tooltips from interfering with one-click interactions while still allowing tooltips on other elements.
|
||||
|
||||
### Layer options
|
||||
|
||||
The **Layer** options let you add elements to the canvas and control its appearance:
|
||||
|
||||
+1
@@ -114,6 +114,7 @@ export const defaultCanvasElementOptions: Partial<CanvasElementOptions> = {
|
||||
};
|
||||
|
||||
export interface CanvasTooltip {
|
||||
disableForOneClick?: boolean;
|
||||
mode: ui.TooltipDisplayMode;
|
||||
}
|
||||
|
||||
|
||||
@@ -866,7 +866,8 @@ export class ElementState implements LayerElement {
|
||||
handleMouseEnter = (event: React.MouseEvent, isSelected: boolean | undefined) => {
|
||||
const scene = this.getScene();
|
||||
|
||||
const shouldHandleTooltip = !scene?.isEditingEnabled && !scene?.tooltipPayload?.isOpen;
|
||||
const shouldHandleTooltip =
|
||||
!scene?.isEditingEnabled && (!scene?.tooltipPayload?.isOpen || scene?.tooltipPayload?.element === this);
|
||||
if (shouldHandleTooltip) {
|
||||
this.handleTooltip(event);
|
||||
} else if (!isSelected) {
|
||||
@@ -933,7 +934,14 @@ export class ElementState implements LayerElement {
|
||||
|
||||
handleTooltip = (event: React.MouseEvent) => {
|
||||
const scene = this.getScene();
|
||||
if (scene?.tooltipCallback && scene.tooltipMode !== TooltipDisplayMode.None) {
|
||||
if (!scene || !scene.tooltipCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldDisableForOneClick = scene.tooltipDisableForOneClick && this.oneClickMode !== OneClickMode.Off;
|
||||
const shouldShowTooltip = scene.tooltipMode !== TooltipDisplayMode.None && !shouldDisableForOneClick;
|
||||
|
||||
if (shouldShowTooltip) {
|
||||
const rect = this.div?.getBoundingClientRect();
|
||||
scene.tooltipCallback({
|
||||
anchorPoint: { x: rect?.right ?? event.pageX, y: rect?.top ?? event.pageY },
|
||||
|
||||
@@ -5,7 +5,7 @@ import { CSSProperties } from 'react';
|
||||
import { BehaviorSubject, ReplaySubject, Subject, Subscription } from 'rxjs';
|
||||
import Selecto from 'selecto';
|
||||
|
||||
import { AppEvents, PanelData } from '@grafana/data';
|
||||
import { AppEvents, PanelData, OneClickMode } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import {
|
||||
ColorDimensionConfig,
|
||||
@@ -81,6 +81,7 @@ export class Scene {
|
||||
shouldPanZoom?: boolean;
|
||||
zoomToContent?: boolean;
|
||||
tooltipMode?: TooltipDisplayMode;
|
||||
tooltipDisableForOneClick?: boolean;
|
||||
skipNextSelectionBroadcast = false;
|
||||
ignoreDataUpdate = false;
|
||||
panel: CanvasPanel;
|
||||
@@ -152,6 +153,7 @@ export class Scene {
|
||||
load(options: Options, enableEditing: boolean) {
|
||||
const { root, showAdvancedTypes, panZoom, zoomToContent, tooltip } = options;
|
||||
const tooltipMode = tooltip?.mode ?? TooltipDisplayMode.Single;
|
||||
const tooltipDisableForOneClick = tooltip?.disableForOneClick ?? false;
|
||||
|
||||
this.root = new RootElement(
|
||||
root ?? {
|
||||
@@ -167,6 +169,7 @@ export class Scene {
|
||||
this.shouldPanZoom = panZoom;
|
||||
this.zoomToContent = zoomToContent;
|
||||
this.tooltipMode = tooltipMode;
|
||||
this.tooltipDisableForOneClick = tooltipDisableForOneClick;
|
||||
|
||||
setTimeout(() => {
|
||||
if (config.featureToggles.canvasPanelPanZoom) {
|
||||
@@ -376,8 +379,12 @@ export class Scene {
|
||||
this.tooltipPayload?.element?.options.actions && this.tooltipPayload.element.options.actions.length > 0;
|
||||
|
||||
const isTooltipValid = hasDataLinks || hasActions || this.tooltipPayload?.element?.data?.field;
|
||||
const isTooltipEnabled = this.tooltipMode !== TooltipDisplayMode.None;
|
||||
const canShowElementTooltip = !this.isEditingEnabled && isTooltipValid && isTooltipEnabled;
|
||||
const isCanvasTooltipEnabled = this.tooltipMode !== TooltipDisplayMode.None;
|
||||
|
||||
const isTooltipDisabledForOneClick =
|
||||
this.tooltipDisableForOneClick && this.tooltipPayload?.element?.oneClickMode !== OneClickMode.Off;
|
||||
const shouldShowElementTooltip =
|
||||
!this.isEditingEnabled && isTooltipValid && isCanvasTooltipEnabled && !isTooltipDisabledForOneClick;
|
||||
|
||||
const sceneDiv = (
|
||||
<>
|
||||
@@ -392,7 +399,7 @@ export class Scene {
|
||||
/>
|
||||
</Portal>
|
||||
)}
|
||||
{canShowElementTooltip && (
|
||||
{shouldShowElementTooltip && (
|
||||
<Portal>
|
||||
<CanvasTooltip scene={this} />
|
||||
</Portal>
|
||||
|
||||
@@ -237,13 +237,16 @@ export class CanvasPanel extends Component<Props, State> {
|
||||
const panZoomSwitched = this.props.options.panZoom !== nextProps.options.panZoom;
|
||||
const zoomToContentSwitched = this.props.options.zoomToContent !== nextProps.options.zoomToContent;
|
||||
const tooltipModeSwitched = this.props.options.tooltip?.mode !== nextProps.options.tooltip?.mode;
|
||||
const tooltipDisableForOneClickSwitched =
|
||||
this.props.options.tooltip?.disableForOneClick !== nextProps.options.tooltip?.disableForOneClick;
|
||||
if (
|
||||
this.needsReload ||
|
||||
inlineEditingSwitched ||
|
||||
shouldShowAdvancedTypesSwitched ||
|
||||
panZoomSwitched ||
|
||||
zoomToContentSwitched ||
|
||||
tooltipModeSwitched
|
||||
tooltipModeSwitched ||
|
||||
tooltipDisableForOneClickSwitched
|
||||
) {
|
||||
if (inlineEditingSwitched) {
|
||||
// Replace scene div to prevent selecto instance leaks
|
||||
|
||||
@@ -74,6 +74,14 @@ export const addStandardCanvasEditorOptions = (builder: PanelOptionsEditorBuilde
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
builder.addBooleanSwitch({
|
||||
path: 'tooltip.disableForOneClick',
|
||||
name: t('canvas.tooltip-options.label-disable-one-click', 'Disable for one-click elements'),
|
||||
category,
|
||||
defaultValue: false,
|
||||
showIf: (options) => options.tooltip?.mode !== TooltipDisplayMode.None,
|
||||
});
|
||||
};
|
||||
|
||||
export const plugin = new PanelPlugin<Options>(CanvasPanel)
|
||||
|
||||
@@ -91,6 +91,7 @@ composableKinds: PanelCfg: {
|
||||
} @cuetsy(kind="interface")
|
||||
CanvasTooltip: {
|
||||
mode: ui.TooltipDisplayMode
|
||||
disableForOneClick?: bool
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
Options: {
|
||||
|
||||
@@ -112,6 +112,7 @@ export const defaultCanvasElementOptions: Partial<CanvasElementOptions> = {
|
||||
};
|
||||
|
||||
export interface CanvasTooltip {
|
||||
disableForOneClick?: boolean;
|
||||
mode: ui.TooltipDisplayMode;
|
||||
}
|
||||
|
||||
|
||||
@@ -4019,6 +4019,7 @@
|
||||
}
|
||||
},
|
||||
"tooltip-options": {
|
||||
"label-disable-one-click": "Disable for one-click elements",
|
||||
"name-tooltip-mode": "Tooltip mode",
|
||||
"tooltip-mode-options": {
|
||||
"label-disabled": "Disabled",
|
||||
|
||||
Reference in New Issue
Block a user