Shortcuts: Fixes panel shortcuts so they always work (#32385)

* Shortcuts: Fixes panel shortcuts so they always work

* Updated snapshot
This commit is contained in:
Torkel Ödegaard 2021-03-29 07:52:57 +02:00 committed by GitHub
parent 4becb79f1e
commit feaaa32ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 68 additions and 91 deletions

View File

@ -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');
},

View File

@ -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();
}
});

View 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));
}
}
};
}

View File

@ -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}

View File

@ -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>
);

View File

@ -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>;
}
}

View File

@ -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)

View File

@ -726,10 +726,6 @@ export class DashboardModel {
}
}
setPanelFocus(id: number) {
this.meta.focusPanelId = id;
}
updateSubmenuVisibility() {
this.meta.submenuEnabled = (() => {
if (this.links.length > 0) {

View File

@ -23,7 +23,6 @@ export interface DashboardMeta {
submenuEnabled?: boolean;
provisioned?: boolean;
provisionedExternalId?: string;
focusPanelId?: number;
isStarred?: boolean;
showSettings?: boolean;
expires?: string;