2023-10-20 15:22:56 +02:00
|
|
|
import { locationService } from '@grafana/runtime';
|
|
|
|
|
import { sceneGraph, VizPanel } from '@grafana/scenes';
|
|
|
|
|
import { OptionsWithLegend } from '@grafana/schema';
|
|
|
|
|
import { KeybindingSet } from 'app/core/services/KeybindingSet';
|
|
|
|
|
|
|
|
|
|
import { ShareModal } from '../sharing/ShareModal';
|
|
|
|
|
import { getDashboardUrl, getInspectUrl, getViewPanelUrl, tryGetExploreUrlForPanel } from '../utils/urlBuilders';
|
|
|
|
|
import { getPanelIdForVizPanel } from '../utils/utils';
|
|
|
|
|
|
|
|
|
|
import { DashboardScene } from './DashboardScene';
|
|
|
|
|
|
|
|
|
|
export function setupKeyboardShortcuts(scene: DashboardScene) {
|
|
|
|
|
const keybindings = new KeybindingSet();
|
|
|
|
|
|
|
|
|
|
// View panel
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'v',
|
|
|
|
|
onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => {
|
|
|
|
|
if (!scene.state.viewPanelKey) {
|
|
|
|
|
locationService.push(getViewPanelUrl(vizPanel));
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Panel edit
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'e',
|
|
|
|
|
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
|
|
|
|
const sceneRoot = vizPanel.getRoot();
|
|
|
|
|
if (sceneRoot instanceof DashboardScene) {
|
|
|
|
|
const panelId = getPanelIdForVizPanel(vizPanel);
|
|
|
|
|
locationService.push(
|
|
|
|
|
getDashboardUrl({
|
|
|
|
|
uid: sceneRoot.state.uid,
|
|
|
|
|
subPath: `/panel-edit/${panelId}`,
|
|
|
|
|
currentQueryParams: location.search,
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Panel share
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'p s',
|
|
|
|
|
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
|
|
|
|
scene.showModal(new ShareModal({ panelRef: vizPanel.getRef(), dashboardRef: scene.getRef() }));
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Panel inspect
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'i',
|
|
|
|
|
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
|
|
|
|
locationService.push(getInspectUrl(vizPanel));
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Got to Explore for panel
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'p x',
|
|
|
|
|
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
|
|
|
|
const url = await tryGetExploreUrlForPanel(vizPanel);
|
|
|
|
|
if (url) {
|
|
|
|
|
locationService.push(url);
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Toggle legend
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'p l',
|
|
|
|
|
onTrigger: withFocusedPanel(scene, toggleVizPanelLegend),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Refresh
|
|
|
|
|
keybindings.addBinding({
|
|
|
|
|
key: 'd r',
|
|
|
|
|
onTrigger: () => sceneGraph.getTimeRange(scene).onRefresh(),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// toggle all panel legends (TODO)
|
|
|
|
|
// delete panel (TODO when we work on editing)
|
|
|
|
|
// toggle all exemplars (TODO)
|
|
|
|
|
// collapse all rows (TODO)
|
|
|
|
|
// expand all rows (TODO)
|
|
|
|
|
|
|
|
|
|
return () => keybindings.removeAll;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function withFocusedPanel(scene: DashboardScene, fn: (vizPanel: VizPanel) => void) {
|
|
|
|
|
return () => {
|
|
|
|
|
const elements = document.querySelectorAll(':hover');
|
|
|
|
|
|
|
|
|
|
for (let i = elements.length - 1; i > 0; i--) {
|
|
|
|
|
const element = elements[i];
|
|
|
|
|
|
|
|
|
|
if (element instanceof HTMLElement && element.dataset?.vizPanelKey) {
|
|
|
|
|
const panelKey = element.dataset?.vizPanelKey;
|
|
|
|
|
const vizPanel = sceneGraph.findObject(scene, (o) => o.state.key === panelKey);
|
|
|
|
|
|
|
|
|
|
if (vizPanel && vizPanel instanceof VizPanel) {
|
|
|
|
|
fn(vizPanel);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function toggleVizPanelLegend(vizPanel: VizPanel) {
|
|
|
|
|
const options = vizPanel.state.options;
|
|
|
|
|
if (hasLegendOptions(options) && typeof options.legend.showLegend === 'boolean') {
|
|
|
|
|
vizPanel.onOptionsChange({
|
|
|
|
|
legend: {
|
|
|
|
|
showLegend: options.legend.showLegend ? false : true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hasLegendOptions(optionsWithLegend: unknown): optionsWithLegend is OptionsWithLegend {
|
2023-11-07 14:20:20 +01:00
|
|
|
return optionsWithLegend != null && typeof optionsWithLegend === 'object' && 'legend' in optionsWithLegend;
|
2023-10-20 15:22:56 +02:00
|
|
|
}
|