mirror of
https://github.com/grafana/grafana.git
synced 2024-11-22 08:56:43 -06:00
Shortcuts: Fixes panel shortcuts so they always work (#32385)
* Shortcuts: Fixes panel shortcuts so they always work * Updated snapshot
This commit is contained in:
parent
4becb79f1e
commit
feaaa32ffd
@ -12,7 +12,7 @@ e2e.scenario({
|
||||
e2e.flows.openDashboard({ uid: 'O6f11TZWk' });
|
||||
|
||||
e2e()
|
||||
.get(`#panel-6 [aria-label^="${selectors.components.Panels.Visualization.BarGauge.value}"]`)
|
||||
.get(`[data-panelid=6] [aria-label^="${selectors.components.Panels.Visualization.BarGauge.value}"]`)
|
||||
.should('have.css', 'color', 'rgb(242, 73, 92)')
|
||||
.contains('100');
|
||||
},
|
||||
|
@ -21,6 +21,7 @@ import { contextSrv } from '../core';
|
||||
import { getDatasourceSrv } from '../../features/plugins/datasource_srv';
|
||||
import { getTimeSrv } from '../../features/dashboard/services/TimeSrv';
|
||||
import { toggleTheme } from './toggleTheme';
|
||||
import { withFocusedPanel } from './withFocusedPanelId';
|
||||
|
||||
export class KeybindingSrv {
|
||||
modalOpen = false;
|
||||
@ -174,6 +175,10 @@ export class KeybindingSrv {
|
||||
Mousetrap.unbind(keyArg, keyType);
|
||||
}
|
||||
|
||||
bindWithPanelId(keyArg: string, fn: (panelId: number) => void) {
|
||||
this.bind(keyArg, withFocusedPanel(fn));
|
||||
}
|
||||
|
||||
setupDashboardBindings(dashboard: DashboardModel) {
|
||||
this.bind('mod+o', () => {
|
||||
dashboard.graphTooltip = (dashboard.graphTooltip + 1) % 3;
|
||||
@ -209,105 +214,82 @@ export class KeybindingSrv {
|
||||
});
|
||||
|
||||
// edit panel
|
||||
this.bind('e', () => {
|
||||
if (!dashboard.meta.focusPanelId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dashboard.canEditPanelById(dashboard.meta.focusPanelId)) {
|
||||
locationService.partial({
|
||||
editPanel: dashboard.meta.focusPanelId,
|
||||
});
|
||||
this.bindWithPanelId('e', (panelId) => {
|
||||
if (dashboard.canEditPanelById(panelId)) {
|
||||
const isEditing = locationService.getSearchObject().editPanel !== undefined;
|
||||
locationService.partial({ editPanel: isEditing ? null : panelId });
|
||||
}
|
||||
});
|
||||
|
||||
// view panel
|
||||
this.bind('v', () => {
|
||||
if (dashboard.meta.focusPanelId) {
|
||||
locationService.partial({
|
||||
viewPanel: dashboard.meta.focusPanelId,
|
||||
});
|
||||
}
|
||||
this.bindWithPanelId('v', (panelId) => {
|
||||
const isViewing = locationService.getSearchObject().viewPanel !== undefined;
|
||||
locationService.partial({ viewPanel: isViewing ? null : panelId });
|
||||
});
|
||||
|
||||
this.bind('i', () => {
|
||||
if (dashboard.meta.focusPanelId) {
|
||||
locationService.partial({
|
||||
inspect: dashboard.meta.focusPanelId,
|
||||
});
|
||||
}
|
||||
this.bindWithPanelId('i', (panelId) => {
|
||||
locationService.partial({ inspect: panelId });
|
||||
});
|
||||
|
||||
// jump to explore if permissions allow
|
||||
if (contextSrv.hasAccessToExplore()) {
|
||||
this.bind('x', async () => {
|
||||
if (dashboard.meta.focusPanelId) {
|
||||
const panel = dashboard.getPanelById(dashboard.meta.focusPanelId)!;
|
||||
const datasource = await getDatasourceSrv().get(panel.datasource);
|
||||
const url = await getExploreUrl({
|
||||
panel,
|
||||
panelTargets: panel.targets,
|
||||
panelDatasource: datasource,
|
||||
datasourceSrv: getDatasourceSrv(),
|
||||
timeSrv: getTimeSrv(),
|
||||
});
|
||||
this.bindWithPanelId('x', async (panelId) => {
|
||||
const panel = dashboard.getPanelById(panelId)!;
|
||||
const datasource = await getDatasourceSrv().get(panel.datasource);
|
||||
const url = await getExploreUrl({
|
||||
panel,
|
||||
panelTargets: panel.targets,
|
||||
panelDatasource: datasource,
|
||||
datasourceSrv: getDatasourceSrv(),
|
||||
timeSrv: getTimeSrv(),
|
||||
});
|
||||
|
||||
if (url) {
|
||||
const urlWithoutBase = locationUtil.stripBaseFromUrl(url);
|
||||
if (urlWithoutBase) {
|
||||
locationService.push(urlWithoutBase);
|
||||
}
|
||||
if (url) {
|
||||
const urlWithoutBase = locationUtil.stripBaseFromUrl(url);
|
||||
if (urlWithoutBase) {
|
||||
locationService.push(urlWithoutBase);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// delete panel
|
||||
this.bind('p r', () => {
|
||||
const panelId = dashboard.meta.focusPanelId;
|
||||
|
||||
if (panelId && dashboard.canEditPanelById(panelId) && !(dashboard.panelInView || dashboard.panelInEdit)) {
|
||||
this.bindWithPanelId('p r', (panelId) => {
|
||||
if (dashboard.canEditPanelById(panelId) && !(dashboard.panelInView || dashboard.panelInEdit)) {
|
||||
appEvents.publish(new RemovePanelEvent(panelId));
|
||||
dashboard.meta.focusPanelId = 0;
|
||||
}
|
||||
});
|
||||
|
||||
// duplicate panel
|
||||
this.bind('p d', () => {
|
||||
const panelId = dashboard.meta.focusPanelId;
|
||||
|
||||
if (panelId && dashboard.canEditPanelById(panelId)) {
|
||||
this.bindWithPanelId('p d', (panelId) => {
|
||||
if (dashboard.canEditPanelById(panelId)) {
|
||||
const panelIndex = dashboard.getPanelInfoById(panelId)!.index;
|
||||
dashboard.duplicatePanel(dashboard.panels[panelIndex]);
|
||||
}
|
||||
});
|
||||
|
||||
// share panel
|
||||
this.bind('p s', () => {
|
||||
if (dashboard.meta.focusPanelId) {
|
||||
const panelInfo = dashboard.getPanelInfoById(dashboard.meta.focusPanelId);
|
||||
this.bindWithPanelId('p s', (panelId) => {
|
||||
const panelInfo = dashboard.getPanelInfoById(panelId);
|
||||
|
||||
appEvents.publish(
|
||||
new ShowModalReactEvent({
|
||||
component: ShareModal,
|
||||
props: {
|
||||
dashboard: dashboard,
|
||||
panel: panelInfo?.panel,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
appEvents.publish(
|
||||
new ShowModalReactEvent({
|
||||
component: ShareModal,
|
||||
props: {
|
||||
dashboard: dashboard,
|
||||
panel: panelInfo?.panel,
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// toggle panel legend
|
||||
this.bind('p l', () => {
|
||||
if (dashboard.meta.focusPanelId) {
|
||||
const panelInfo = dashboard.getPanelInfoById(dashboard.meta.focusPanelId)!;
|
||||
this.bindWithPanelId('p l', (panelId) => {
|
||||
const panelInfo = dashboard.getPanelInfoById(panelId)!;
|
||||
|
||||
if (panelInfo.panel.legend) {
|
||||
panelInfo.panel.legend.show = !panelInfo.panel.legend.show;
|
||||
panelInfo.panel.render();
|
||||
}
|
||||
if (panelInfo.panel.legend) {
|
||||
panelInfo.panel.legend.show = !panelInfo.panel.legend.show;
|
||||
panelInfo.panel.render();
|
||||
}
|
||||
});
|
||||
|
||||
|
12
public/app/core/services/withFocusedPanelId.ts
Normal file
12
public/app/core/services/withFocusedPanelId.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export function withFocusedPanel(fn: (panelId: number) => void) {
|
||||
return () => {
|
||||
const elements = document.querySelectorAll(':hover');
|
||||
|
||||
for (let i = elements.length - 1; i > 0; i--) {
|
||||
const element = (elements[i] as unknown) as HTMLElement;
|
||||
if (element.dataset?.panelid) {
|
||||
fn(parseInt(element.dataset?.panelid, 10));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -238,7 +238,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
}
|
||||
return (
|
||||
<div className={styles.centeringContainer} style={{ width, height }}>
|
||||
<div style={calculatePanelSize(uiState.mode, width, height, panel)}>
|
||||
<div style={calculatePanelSize(uiState.mode, width, height, panel)} data-panelid={panel.editSourceId}>
|
||||
<DashboardPanel
|
||||
dashboard={dashboard}
|
||||
panel={panel}
|
||||
|
@ -228,7 +228,7 @@ export class DashboardGrid extends PureComponent<Props> {
|
||||
panel.isInView = this.isInView(panel);
|
||||
|
||||
panelElements.push(
|
||||
<div key={id} className={panelClasses} id={'panel-' + id} ref={(elem) => elem && (this.panelRef[id] = elem)}>
|
||||
<div key={id} className={panelClasses} data-panelid={id} ref={(elem) => elem && (this.panelRef[id] = elem)}>
|
||||
{this.renderPanel(panel)}
|
||||
</div>
|
||||
);
|
||||
|
@ -66,14 +66,6 @@ export class DashboardPanelUnconnected extends PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
onMouseEnter = () => {
|
||||
this.props.dashboard.setPanelFocus(this.props.panel.id);
|
||||
};
|
||||
|
||||
onMouseLeave = () => {
|
||||
this.props.dashboard.setPanelFocus(0);
|
||||
};
|
||||
|
||||
renderPanel(plugin: PanelPlugin) {
|
||||
const { dashboard, panel, isViewing, isInView, isEditing } = this.props;
|
||||
|
||||
@ -135,11 +127,7 @@ export class DashboardPanelUnconnected extends PureComponent<Props, State> {
|
||||
'panel-wrapper--view': isViewing,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={panelWrapperClass} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
||||
{this.renderPanel(plugin)}
|
||||
</div>
|
||||
);
|
||||
return <div className={panelWrapperClass}>{this.renderPanel(plugin)}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
id="panel-1"
|
||||
data-panelid="1"
|
||||
key="1"
|
||||
>
|
||||
<Connect(DashboardPanelUnconnected)
|
||||
@ -269,7 +269,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
id="panel-2"
|
||||
data-panelid="2"
|
||||
key="2"
|
||||
>
|
||||
<Connect(DashboardPanelUnconnected)
|
||||
@ -493,7 +493,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
id="panel-3"
|
||||
data-panelid="3"
|
||||
key="3"
|
||||
>
|
||||
<Connect(DashboardPanelUnconnected)
|
||||
@ -717,7 +717,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
id="panel-4"
|
||||
data-panelid="4"
|
||||
key="4"
|
||||
>
|
||||
<Connect(DashboardPanelUnconnected)
|
||||
|
@ -726,10 +726,6 @@ export class DashboardModel {
|
||||
}
|
||||
}
|
||||
|
||||
setPanelFocus(id: number) {
|
||||
this.meta.focusPanelId = id;
|
||||
}
|
||||
|
||||
updateSubmenuVisibility() {
|
||||
this.meta.submenuEnabled = (() => {
|
||||
if (this.links.length > 0) {
|
||||
|
@ -23,7 +23,6 @@ export interface DashboardMeta {
|
||||
submenuEnabled?: boolean;
|
||||
provisioned?: boolean;
|
||||
provisionedExternalId?: string;
|
||||
focusPanelId?: number;
|
||||
isStarred?: boolean;
|
||||
showSettings?: boolean;
|
||||
expires?: string;
|
||||
|
Loading…
Reference in New Issue
Block a user