Files
grafana/public/app/features/panel/query_troubleshooter.ts

155 lines
4.2 KiB
TypeScript
Raw Normal View History

2017-05-19 16:00:01 +02:00
///<reference path="../../headers/common.d.ts" />
import _ from 'lodash';
import appEvents from 'app/core/app_events';
import {coreModule, JsonExplorer} from 'app/core/core';
const template = `
2017-05-19 17:35:36 +02:00
<collapse-box title="Query Troubleshooter" is-open="ctrl.isOpen" state-changed="ctrl.stateChanged()"
ng-class="{'collapse-box--error': ctrl.hasError}">
2017-05-19 16:00:01 +02:00
<collapse-box-actions>
<a class="pointer" ng-click="ctrl.toggleExpand()" ng-hide="ctrl.allNodesExpanded">
2017-05-20 18:21:41 +02:00
<i class="fa fa-plus-square-o"></i> Expand All
</a>
<a class="pointer" ng-click="ctrl.toggleExpand()" ng-show="ctrl.allNodesExpanded">
2017-05-20 18:21:41 +02:00
<i class="fa fa-minus-square-o"></i> Collapse All
</a>
<a class="pointer" clipboard-button="ctrl.getClipboardText()"><i class="fa fa-clipboard"></i> Copy to Clipboard</a>
2017-05-19 16:00:01 +02:00
</collapse-box-actions>
<collapse-box-body>
2017-05-20 22:41:34 +02:00
<i class="fa fa-spinner fa-spin" ng-show="ctrl.isLoading"></i>
2017-05-19 16:00:01 +02:00
<div class="query-troubleshooter-json"></div>
</collapse-box-body>
</collapse-box>
`;
export class QueryTroubleshooterCtrl {
2017-05-19 17:35:36 +02:00
isOpen: any;
2017-05-20 22:41:34 +02:00
isLoading: boolean;
2017-05-19 16:00:01 +02:00
showResponse: boolean;
panelCtrl: any;
renderJsonExplorer: (data) => void;
2017-05-19 17:35:36 +02:00
onRequestErrorEventListener: any;
onRequestResponseEventListener: any;
hasError: boolean;
allNodesExpanded: boolean;
jsonExplorer: JsonExplorer;
2017-05-19 16:00:01 +02:00
/** @ngInject **/
constructor($scope, private $timeout) {
2017-05-19 17:35:36 +02:00
this.onRequestErrorEventListener = this.onRequestError.bind(this);
this.onRequestResponseEventListener = this.onRequestResponse.bind(this);
2017-05-19 16:00:01 +02:00
2017-05-20 22:55:36 +02:00
appEvents.on('ds-request-response', this.onRequestResponseEventListener);
2017-05-19 17:35:36 +02:00
appEvents.on('ds-request-error', this.onRequestErrorEventListener);
$scope.$on('$destroy', this.removeEventsListeners.bind(this));
2017-05-19 16:00:01 +02:00
}
2017-05-19 17:35:36 +02:00
removeEventsListeners() {
appEvents.off('ds-request-response', this.onRequestResponseEventListener);
appEvents.off('ds-request-error', this.onRequestErrorEventListener);
2017-05-19 16:00:01 +02:00
}
onRequestError(err) {
2017-05-19 17:35:36 +02:00
this.isOpen = true;
this.hasError = true;
this.onRequestResponse(err);
2017-05-19 16:00:01 +02:00
}
2017-05-19 17:35:36 +02:00
stateChanged() {
if (this.isOpen) {
this.panelCtrl.refresh();
2017-05-20 22:41:34 +02:00
this.isLoading = true;
2017-05-19 16:00:01 +02:00
}
2017-05-19 17:35:36 +02:00
}
getClipboardText() {
if (this.jsonExplorer) {
return JSON.stringify(this.jsonExplorer.json, null, 2);
}
}
2017-05-19 17:35:36 +02:00
onRequestResponse(data) {
2017-05-20 22:55:36 +02:00
// ignore if closed
if (!this.isOpen) {
return;
}
2017-05-20 22:41:34 +02:00
this.isLoading = false;
2017-05-19 17:35:36 +02:00
data = _.cloneDeep(data);
2017-05-19 16:00:01 +02:00
if (data.headers) {
delete data.headers;
}
if (data.config) {
data.request = data.config;
delete data.config;
delete data.request.transformRequest;
delete data.request.transformResponse;
delete data.request.paramSerializer;
delete data.request.jsonpCallbackParam;
delete data.request.headers;
delete data.request.requestId;
delete data.request.inspect;
delete data.request.retry;
delete data.request.timeout;
}
if (data.data) {
data.response = data.data;
2017-05-20 22:41:34 +02:00
if (data.status === 200) {
// if we are in error state, assume we automatically opened
// and auto close it again
if (this.hasError) {
this.hasError = false;
this.isOpen = false;
}
}
2017-05-19 16:00:01 +02:00
delete data.data;
delete data.status;
delete data.statusText;
delete data.$$config;
}
2017-05-19 17:35:36 +02:00
this.$timeout(_.partial(this.renderJsonExplorer, data));
2017-05-19 16:00:01 +02:00
}
toggleExpand(depth) {
if (this.jsonExplorer) {
this.allNodesExpanded = !this.allNodesExpanded;
this.jsonExplorer.openAtDepth(this.allNodesExpanded ? 20 : 1);
}
}
2017-05-19 16:00:01 +02:00
}
export function queryTroubleshooter() {
return {
restrict: 'E',
template: template,
controller: QueryTroubleshooterCtrl,
bindToController: true,
controllerAs: 'ctrl',
scope: {
panelCtrl: "="
},
link: function(scope, elem, attrs, ctrl) {
ctrl.renderJsonExplorer = function(data) {
var jsonElem = elem.find('.query-troubleshooter-json');
2017-05-20 22:55:36 +02:00
ctrl.jsonExplorer = new JsonExplorer(data, 3, {
animateOpen: true,
});
2017-05-19 16:00:01 +02:00
const html = ctrl.jsonExplorer.render(true);
2017-05-19 16:00:01 +02:00
jsonElem.html(html);
};
}
};
}
coreModule.directive('queryTroubleshooter', queryTroubleshooter);