Commit 5210a8f2 by Ryan McKinley Committed by GitHub

Dashboards: add panel inspector (#20052)

parent 4424c2f4
......@@ -13,6 +13,7 @@ export interface BuildInfo {
interface FeatureToggles {
transformations: boolean;
inspect: boolean;
expressions: boolean;
}
export class GrafanaBootConfig {
......@@ -48,6 +49,7 @@ export class GrafanaBootConfig {
pluginsToPreload: string[] = [];
featureToggles: FeatureToggles = {
transformations: false,
inspect: false,
expressions: false,
};
......
......@@ -13,6 +13,7 @@ import 'mousetrap-global-bind';
import { ContextSrv } from './context_srv';
import { ILocationService, ITimeoutService, IRootScopeService } from 'angular';
import { GrafanaRootScope } from 'app/routes/GrafanaCtrl';
import { getLocationSrv } from '@grafana/runtime';
export class KeybindingSrv {
helpModal: boolean;
......@@ -264,6 +265,13 @@ export class KeybindingSrv {
}
});
// inspect panel
this.bind('p i', () => {
if (dashboard.meta.focusPanelId) {
getLocationSrv().update({ partial: true, query: { inspect: dashboard.meta.focusPanelId } });
}
});
// toggle panel legend
this.bind('p l', () => {
if (dashboard.meta.focusPanelId) {
......
// Libraries
import React, { PureComponent } from 'react';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
import { JSONFormatter, Modal } from '@grafana/ui';
import { css } from 'emotion';
import { getLocationSrv } from '@grafana/runtime';
interface Props {
dashboard: DashboardModel;
panel: PanelModel;
}
interface State {}
export class PanelInspector extends PureComponent<Props, State> {
constructor(props: Props) {
super(props);
}
onDismiss = () => {
getLocationSrv().update({
query: { inspect: null },
partial: true,
});
};
render() {
const { panel } = this.props;
if (!panel) {
this.onDismiss(); // Try to close the component
return null;
}
const bodyStyle = css`
max-height: 70vh;
overflow-y: scroll;
`;
// TODO? should we get the result with an observable once?
const data = (panel.getQueryRunner() as any).lastResult;
return (
<Modal
title={
<div className="modal-header-title">
<i className="fa fa-info-circle" />
<span className="p-l-1">{panel.title ? panel.title : 'Panel'}</span>
</div>
}
onDismiss={this.onDismiss}
isOpen={true}
>
<div className={bodyStyle}>
<JSONFormatter json={data} open={2} />
</div>
</Modal>
);
}
}
......@@ -31,6 +31,7 @@ import {
AppNotificationSeverity,
} from 'app/types';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
import { PanelInspector } from '../components/Inspector/PanelInspector';
export interface Props {
urlUid?: string;
urlSlug?: string;
......@@ -38,6 +39,7 @@ export interface Props {
editview?: string;
urlPanelId?: string;
urlFolderId?: string;
inspectPanelId?: string;
$scope: any;
$injector: any;
routeInfo: DashboardRouteInfo;
......@@ -250,7 +252,7 @@ export class DashboardPage extends PureComponent<Props, State> {
}
render() {
const { dashboard, editview, $injector, isInitSlow, initError } = this.props;
const { dashboard, editview, $injector, isInitSlow, initError, inspectPanelId } = this.props;
const { isSettingsOpening, isEditing, isFullscreen, scrollTop, updateScrollTop } = this.state;
if (!dashboard) {
......@@ -270,6 +272,9 @@ export class DashboardPage extends PureComponent<Props, State> {
'dashboard-container--has-submenu': dashboard.meta.submenuEnabled,
});
// Find the panel to inspect
const inspectPanel = inspectPanelId ? dashboard.getPanelById(parseInt(inspectPanelId, 10)) : null;
// Only trigger render when the scroll has moved by 25
const approximateScrollTop = Math.round(scrollTop / 25) * 25;
......@@ -306,6 +311,8 @@ export class DashboardPage extends PureComponent<Props, State> {
</div>
</CustomScrollbar>
</div>
{inspectPanel && <PanelInspector dashboard={dashboard} panel={inspectPanel} />}
</div>
);
}
......@@ -320,6 +327,7 @@ export const mapStateToProps = (state: StoreState) => ({
urlFolderId: state.location.query.folderId,
urlFullscreen: !!state.location.query.fullscreen,
urlEdit: !!state.location.query.edit,
inspectPanelId: state.location.query.inspect,
initPhase: state.dashboard.initPhase,
isInitSlow: state.dashboard.isInitSlow,
initError: state.dashboard.initError,
......
import { updateLocation } from 'app/core/actions';
import { store } from 'app/store/store';
import config from 'app/core/config';
import { removePanel, duplicatePanel, copyPanel, editPanelJson, sharePanel } from 'app/features/dashboard/utils/panel';
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
import { getLocationSrv } from '@grafana/runtime';
import { PanelMenuItem } from '@grafana/data';
export const getPanelMenu = (dashboard: DashboardModel, panel: PanelModel) => {
......@@ -37,6 +39,15 @@ export const getPanelMenu = (dashboard: DashboardModel, panel: PanelModel) => {
sharePanel(dashboard, panel);
};
const onInspectPanel = () => {
getLocationSrv().update({
partial: true,
query: {
inspect: panel.id,
},
});
};
const onDuplicatePanel = () => {
duplicatePanel(dashboard, panel);
};
......@@ -78,6 +89,15 @@ export const getPanelMenu = (dashboard: DashboardModel, panel: PanelModel) => {
shortcut: 'p s',
});
if (config.featureToggles.inspect) {
menu.push({
text: 'Inspect',
iconClassName: 'fa fa-fw fa-info-circle',
onClick: onInspectPanel,
shortcut: 'p i',
});
}
const subMenu: PanelMenuItem[] = [];
if (!panel.fullscreen && dashboard.meta.canEdit) {
......
......@@ -18,6 +18,7 @@ import { auto } from 'angular';
import { TemplateSrv } from '../templating/template_srv';
import { getPanelLinksSupplier } from './panellinks/linkSuppliers';
import { renderMarkdown, AppEvent, PanelEvents, PanelPluginMeta } from '@grafana/data';
import { getLocationSrv } from '@grafana/runtime';
export class PanelCtrl {
panel: any;
......@@ -145,6 +146,15 @@ export class PanelCtrl {
shortcut: 'p s',
});
if (config.featureToggles.inspect) {
menu.push({
text: 'Inspect',
icon: 'fa fa-fw fa-info-circle',
click: 'ctrl.inspectPanel();',
shortcut: 'p i',
});
}
// Additional items from sub-class
menu.push(...(await this.getAdditionalMenuItems()));
......@@ -234,6 +244,15 @@ export class PanelCtrl {
sharePanelUtil(this.dashboard, this.panel);
}
inspectPanel() {
getLocationSrv().update({
query: {
inspect: this.panel.id,
},
partial: true,
});
}
getInfoMode() {
if (this.error) {
return 'error';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment