mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Open new window when exploring panel metrics (#18802)
This commit is contained in:
@@ -248,25 +248,18 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAdditionalMenuItems() {
|
async getAdditionalMenuItems() {
|
||||||
const items = [];
|
const items = [];
|
||||||
if (this.contextSrv.hasAccessToExplore() && this.datasource) {
|
if (this.contextSrv.hasAccessToExplore() && this.datasource) {
|
||||||
items.push({
|
items.push({
|
||||||
text: 'Explore',
|
text: 'Explore',
|
||||||
click: 'ctrl.explore();',
|
|
||||||
icon: 'gicon gicon-explore',
|
icon: 'gicon gicon-explore',
|
||||||
shortcut: 'x',
|
shortcut: 'x',
|
||||||
|
href: await getExploreUrl(this.panel.targets, this.datasource, this.datasourceSrv, this.timeSrv),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
async explore() {
|
|
||||||
const url = await getExploreUrl(this.panel.targets, this.datasource, this.datasourceSrv, this.timeSrv);
|
|
||||||
if (url) {
|
|
||||||
this.$timeout(() => this.$location.url(url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { MetricsPanelCtrl };
|
export { MetricsPanelCtrl };
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ export class PanelCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getMenu() {
|
async getMenu() {
|
||||||
const menu = [];
|
const menu = [];
|
||||||
menu.push({
|
menu.push({
|
||||||
text: 'View',
|
text: 'View',
|
||||||
@@ -147,7 +147,7 @@ export class PanelCtrl {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Additional items from sub-class
|
// Additional items from sub-class
|
||||||
menu.push(...this.getAdditionalMenuItems());
|
menu.push(...(await this.getAdditionalMenuItems()));
|
||||||
|
|
||||||
const extendedMenu = this.getExtendedMenu();
|
const extendedMenu = this.getExtendedMenu();
|
||||||
menu.push({
|
menu.push({
|
||||||
@@ -198,7 +198,7 @@ export class PanelCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override in sub-class to add items before extended menu
|
// Override in sub-class to add items before extended menu
|
||||||
getAdditionalMenuItems(): any[] {
|
async getAdditionalMenuItems(): Promise<any[]> {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ function renderMenuItem(item: AngularPanelMenuItem, ctrl: any) {
|
|||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMenuTemplate(ctrl: any) {
|
async function createMenuTemplate(ctrl: any) {
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|
||||||
for (const item of ctrl.getMenu()) {
|
for (const item of await ctrl.getMenu()) {
|
||||||
html += renderMenuItem(item, ctrl);
|
html += renderMenuItem(item, ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ function panelHeader($compile: any) {
|
|||||||
let menuScope: any;
|
let menuScope: any;
|
||||||
let isDragged: boolean;
|
let isDragged: boolean;
|
||||||
|
|
||||||
elem.click((evt: any) => {
|
elem.click(async (evt: any) => {
|
||||||
const targetClass = evt.target.className;
|
const targetClass = evt.target.className;
|
||||||
|
|
||||||
// remove existing scope
|
// remove existing scope
|
||||||
@@ -84,7 +84,7 @@ function panelHeader($compile: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
menuScope = scope.$new();
|
menuScope = scope.$new();
|
||||||
const menuHtml = createMenuTemplate(scope.ctrl);
|
const menuHtml = await createMenuTemplate(scope.ctrl);
|
||||||
menuElem.html(menuHtml);
|
menuElem.html(menuHtml);
|
||||||
$compile(menuElem)(menuScope);
|
$compile(menuElem)(menuScope);
|
||||||
|
|
||||||
|
|||||||
@@ -21,28 +21,28 @@ import { MetricsPanelCtrl } from '../metrics_panel_ctrl';
|
|||||||
describe('MetricsPanelCtrl', () => {
|
describe('MetricsPanelCtrl', () => {
|
||||||
describe('when getting additional menu items', () => {
|
describe('when getting additional menu items', () => {
|
||||||
describe('and has no datasource set but user has access to explore', () => {
|
describe('and has no datasource set but user has access to explore', () => {
|
||||||
it('should not return any items', () => {
|
it('should not return any items', async () => {
|
||||||
const ctrl = setupController({ hasAccessToExplore: true });
|
const ctrl = setupController({ hasAccessToExplore: true });
|
||||||
|
|
||||||
expect(ctrl.getAdditionalMenuItems().length).toBe(0);
|
expect((await ctrl.getAdditionalMenuItems()).length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and has datasource set that supports explore and user does not have access to explore', () => {
|
describe('and has datasource set that supports explore and user does not have access to explore', () => {
|
||||||
it('should not return any items', () => {
|
it('should not return any items', async () => {
|
||||||
const ctrl = setupController({ hasAccessToExplore: false });
|
const ctrl = setupController({ hasAccessToExplore: false });
|
||||||
ctrl.datasource = { meta: { explore: true } } as any;
|
ctrl.datasource = { meta: { explore: true } } as any;
|
||||||
|
|
||||||
expect(ctrl.getAdditionalMenuItems().length).toBe(0);
|
expect((await ctrl.getAdditionalMenuItems()).length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and has datasource set that supports explore and user has access to explore', () => {
|
describe('and has datasource set that supports explore and user has access to explore', () => {
|
||||||
it('should return one item', () => {
|
it('should return one item', async () => {
|
||||||
const ctrl = setupController({ hasAccessToExplore: true });
|
const ctrl = setupController({ hasAccessToExplore: true });
|
||||||
ctrl.datasource = { meta: { explore: true } } as any;
|
ctrl.datasource = { meta: { explore: true } } as any;
|
||||||
|
|
||||||
expect(ctrl.getAdditionalMenuItems().length).toBe(1);
|
expect((await ctrl.getAdditionalMenuItems()).length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -58,6 +58,9 @@ function setupController({ hasAccessToExplore } = { hasAccessToExplore: false })
|
|||||||
case 'contextSrv': {
|
case 'contextSrv': {
|
||||||
return { hasAccessToExplore: () => hasAccessToExplore };
|
return { hasAccessToExplore: () => hasAccessToExplore };
|
||||||
}
|
}
|
||||||
|
case 'timeSrv': {
|
||||||
|
return { timeRangeForUrl: () => {} };
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return jest.fn();
|
return jest.fn();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user