mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Fix url encoding, expand template vars, fix TS hacks
* moved datasource related functions to panel sub-class * expand panel template vars for url * added keybindings for x -> Explore * url encoding for explore state
This commit is contained in:
parent
05b0bfafe4
commit
8a53ec610b
@ -10,6 +10,7 @@ import Graph from './Graph';
|
||||
import Table from './Table';
|
||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { buildQueryOptions, ensureQueries, generateQueryKey, hasQuery } from './utils/query';
|
||||
import { decodePathComponent } from 'app/core/utils/location_util';
|
||||
|
||||
function makeTimeSeriesList(dataList, options) {
|
||||
return dataList.map((seriesData, index) => {
|
||||
@ -43,7 +44,7 @@ function parseInitialQueries(initial) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(initial);
|
||||
const parsed = JSON.parse(decodePathComponent(initial));
|
||||
return parsed.queries.map(q => q.query);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -3,6 +3,7 @@ import _ from 'lodash';
|
||||
|
||||
import coreModule from 'app/core/core_module';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { encodePathComponent } from 'app/core/utils/location_util';
|
||||
|
||||
import Mousetrap from 'mousetrap';
|
||||
import 'mousetrap-global-bind';
|
||||
@ -13,7 +14,7 @@ export class KeybindingSrv {
|
||||
timepickerOpen = false;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope, private $location) {
|
||||
constructor(private $rootScope, private $location, private datasourceSrv) {
|
||||
// clear out all shortcuts on route change
|
||||
$rootScope.$on('$routeChangeSuccess', () => {
|
||||
Mousetrap.reset();
|
||||
@ -176,6 +177,17 @@ export class KeybindingSrv {
|
||||
}
|
||||
});
|
||||
|
||||
this.bind('x', async () => {
|
||||
if (dashboard.meta.focusPanelId) {
|
||||
const panel = dashboard.getPanelById(dashboard.meta.focusPanelId);
|
||||
const datasource = await this.datasourceSrv.get(panel.datasource);
|
||||
if (datasource && datasource.supportsExplore) {
|
||||
const exploreState = encodePathComponent(JSON.stringify(datasource.getExploreState(panel)));
|
||||
this.$location.url(`/explore/${exploreState}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// delete panel
|
||||
this.bind('p r', () => {
|
||||
if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
|
||||
|
@ -1,6 +1,11 @@
|
||||
import config from 'app/core/config';
|
||||
|
||||
const _stripBaseFromUrl = url => {
|
||||
// Slash encoding for angular location provider, see https://github.com/angular/angular.js/issues/10479
|
||||
const SLASH = '<SLASH>';
|
||||
export const decodePathComponent = (pc: string) => decodeURIComponent(pc).replace(new RegExp(SLASH, 'g'), '/');
|
||||
export const encodePathComponent = (pc: string) => encodeURIComponent(pc.replace(/\//g, SLASH));
|
||||
|
||||
export const stripBaseFromUrl = url => {
|
||||
const appSubUrl = config.appSubUrl;
|
||||
const stripExtraChars = appSubUrl.endsWith('/') ? 1 : 0;
|
||||
const urlWithoutBase =
|
||||
@ -9,6 +14,4 @@ const _stripBaseFromUrl = url => {
|
||||
return urlWithoutBase;
|
||||
};
|
||||
|
||||
export default {
|
||||
stripBaseFromUrl: _stripBaseFromUrl,
|
||||
};
|
||||
export default { stripBaseFromUrl };
|
||||
|
@ -6,6 +6,7 @@ import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
||||
|
||||
import * as rangeUtil from 'app/core/utils/rangeutil';
|
||||
import * as dateMath from 'app/core/utils/datemath';
|
||||
import { encodePathComponent } from 'app/core/utils/location_util';
|
||||
|
||||
import { metricsTabDirective } from './metrics_tab';
|
||||
|
||||
@ -309,6 +310,24 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
getAdditionalMenuItems() {
|
||||
const items = [];
|
||||
if (this.datasource.supportsExplore) {
|
||||
items.push({
|
||||
text: 'Explore',
|
||||
click: 'ctrl.explore();',
|
||||
icon: 'fa fa-fw fa-rocket',
|
||||
shortcut: 'x',
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
explore() {
|
||||
const exploreState = encodePathComponent(JSON.stringify(this.datasource.getExploreState(this.panel)));
|
||||
this.$location.url(`/explore/${exploreState}`);
|
||||
}
|
||||
|
||||
addQuery(target) {
|
||||
target.refId = this.dashboard.getNextQueryLetter(this.panel);
|
||||
|
||||
|
@ -99,12 +99,6 @@ export class PanelCtrl {
|
||||
this.changeView(false, false);
|
||||
}
|
||||
|
||||
explore() {
|
||||
// TS hack :<
|
||||
const initialState = JSON.stringify(this['datasource'].getExploreState(this.panel));
|
||||
this.$location.url(`/explore/${initialState}`);
|
||||
}
|
||||
|
||||
initEditMode() {
|
||||
this.editorTabs = [];
|
||||
this.addEditorTab('General', 'public/app/partials/panelgeneral.html');
|
||||
@ -162,16 +156,6 @@ export class PanelCtrl {
|
||||
});
|
||||
}
|
||||
|
||||
// TS hack :<
|
||||
if ('datasource' in this && this['datasource'].supportsExplore) {
|
||||
menu.push({
|
||||
text: 'Explore',
|
||||
click: 'ctrl.explore();',
|
||||
icon: 'fa fa-fw fa-rocket',
|
||||
shortcut: 'x',
|
||||
});
|
||||
}
|
||||
|
||||
menu.push({
|
||||
text: 'Share',
|
||||
click: 'ctrl.sharePanel();',
|
||||
@ -179,6 +163,9 @@ export class PanelCtrl {
|
||||
shortcut: 'p s',
|
||||
});
|
||||
|
||||
// Additional items from sub-class
|
||||
menu.push(...this.getAdditionalMenuItems());
|
||||
|
||||
let extendedMenu = this.getExtendedMenu();
|
||||
menu.push({
|
||||
text: 'More ...',
|
||||
@ -227,6 +214,11 @@ export class PanelCtrl {
|
||||
return menu;
|
||||
}
|
||||
|
||||
// Override in sub-class to add items before extended menu
|
||||
getAdditionalMenuItems() {
|
||||
return [];
|
||||
}
|
||||
|
||||
otherPanelInFullscreenMode() {
|
||||
return this.dashboard.meta.fullscreen && !this.fullscreen;
|
||||
}
|
||||
|
@ -326,11 +326,18 @@ export class PrometheusDatasource {
|
||||
}
|
||||
|
||||
getExploreState(panel) {
|
||||
if (!panel.targets) {
|
||||
return {};
|
||||
let state = {};
|
||||
if (panel.targets) {
|
||||
const queries = panel.targets.map(t => ({
|
||||
query: this.templateSrv.replace(t.expr, {}, this.interpolateQueryExpr),
|
||||
format: t.format,
|
||||
}));
|
||||
state = {
|
||||
...state,
|
||||
queries,
|
||||
};
|
||||
}
|
||||
const queries = panel.targets.map(t => ({ query: t.expr, format: t.format }));
|
||||
return { queries };
|
||||
return state;
|
||||
}
|
||||
|
||||
getPrometheusTime(date, roundUp) {
|
||||
|
Loading…
Reference in New Issue
Block a user