Commit b3c073ab by Torkel Ödegaard

feat(panels): more panel refactoring, using events instead of overriding base class methods

parent 6a42b95d
...@@ -14,7 +14,7 @@ export class Emitter { ...@@ -14,7 +14,7 @@ export class Emitter {
this.subjects = {}; this.subjects = {};
} }
emit(name, data) { emit(name, data?) {
var fnName = createName(name); var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Subject()); this.subjects[fnName] || (this.subjects[fnName] = new Subject());
this.subjects[fnName].next(data); this.subjects[fnName].next(data);
......
...@@ -139,7 +139,7 @@ function (angular, _, $) { ...@@ -139,7 +139,7 @@ function (angular, _, $) {
self.$scope.broadcastRefresh(); self.$scope.broadcastRefresh();
} }
else { else {
self.fullscreenPanel.$broadcast('render'); ctrl.render();
} }
delete self.fullscreenPanel; delete self.fullscreenPanel;
}); });
...@@ -159,7 +159,7 @@ function (angular, _, $) { ...@@ -159,7 +159,7 @@ function (angular, _, $) {
this.$scope.appEvent('panel-fullscreen-enter', {panelId: ctrl.panel.id}); this.$scope.appEvent('panel-fullscreen-enter', {panelId: ctrl.panel.id});
$timeout(function() { $timeout(function() {
panelScope.$broadcast('render'); ctrl.render();
}); });
}; };
......
...@@ -44,16 +44,18 @@ class MetricsPanelCtrl extends PanelCtrl { ...@@ -44,16 +44,18 @@ class MetricsPanelCtrl extends PanelCtrl {
if (!this.panel.targets) { if (!this.panel.targets) {
this.panel.targets = [{}]; this.panel.targets = [{}];
} }
this.events.on('refresh', this.onMetricsPanelRefresh.bind(this));
this.events.on('init-edit-mode', this.onInitMetricsPanelEditMode.bind(this));
} }
initEditMode() { private onInitMetricsPanelEditMode() {
super.initEditMode();
this.addEditorTab('Metrics', 'public/app/partials/metrics.html'); this.addEditorTab('Metrics', 'public/app/partials/metrics.html');
this.addEditorTab('Time range', 'public/app/features/panel/partials/panelTime.html'); this.addEditorTab('Time range', 'public/app/features/panel/partials/panelTime.html');
this.datasources = this.datasourceSrv.getMetricSources(); this.datasources = this.datasourceSrv.getMetricSources();
} }
refresh() { private onMetricsPanelRefresh() {
// ignore fetching data if another panel is in fullscreen // ignore fetching data if another panel is in fullscreen
if (this.otherPanelInFullscreenMode()) { return; } if (this.otherPanelInFullscreenMode()) { return; }
......
...@@ -18,7 +18,6 @@ export class PanelCtrl { ...@@ -18,7 +18,6 @@ export class PanelCtrl {
editorTabIndex: number; editorTabIndex: number;
pluginName: string; pluginName: string;
pluginId: string; pluginId: string;
icon: string;
editorTabs: any; editorTabs: any;
$scope: any; $scope: any;
$injector: any; $injector: any;
...@@ -60,7 +59,7 @@ export class PanelCtrl { ...@@ -60,7 +59,7 @@ export class PanelCtrl {
} }
refresh() { refresh() {
this.render(); this.events.emit('refresh', null);
} }
publishAppEvent(evtName, evt) { publishAppEvent(evtName, evt) {
...@@ -89,6 +88,7 @@ export class PanelCtrl { ...@@ -89,6 +88,7 @@ export class PanelCtrl {
this.editorTabs = []; this.editorTabs = [];
this.addEditorTab('General', 'public/app/partials/panelgeneral.html'); this.addEditorTab('General', 'public/app/partials/panelgeneral.html');
this.editModeInitiated = true; this.editModeInitiated = true;
this.events.emit('init-edit-mode', null);
} }
addEditorTab(title, directiveFn, index?) { addEditorTab(title, directiveFn, index?) {
...@@ -118,7 +118,9 @@ export class PanelCtrl { ...@@ -118,7 +118,9 @@ export class PanelCtrl {
} }
getExtendedMenu() { getExtendedMenu() {
return [{text: 'Panel JSON', click: 'ctrl.editPanelJson(); dismiss();'}]; var actions = [{text: 'Panel JSON', click: 'ctrl.editPanelJson(); dismiss();'}];
this.events.emit('init-panel-actions', actions);
return actions;
} }
otherPanelInFullscreenMode() { otherPanelInFullscreenMode() {
...@@ -126,7 +128,6 @@ export class PanelCtrl { ...@@ -126,7 +128,6 @@ export class PanelCtrl {
} }
calculatePanelHeight() { calculatePanelHeight() {
if (this.fullscreen) { if (this.fullscreen) {
var docHeight = $(window).height(); var docHeight = $(window).height();
var editHeight = Math.floor(docHeight * 0.3); var editHeight = Math.floor(docHeight * 0.3);
...@@ -142,8 +143,13 @@ export class PanelCtrl { ...@@ -142,8 +143,13 @@ export class PanelCtrl {
this.height = this.containerHeight - (PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT)); this.height = this.containerHeight - (PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT));
} }
render(arg1?, arg2?) { render(payload?) {
this.$scope.$broadcast('render', arg1, arg2); // ignore if other panel is in fullscreen mode
if (this.otherPanelInFullscreenMode()) {
return;
}
this.events.emit('render', payload);
} }
toggleEditorHelp(index) { toggleEditorHelp(index) {
......
...@@ -28,18 +28,18 @@ class DashListCtrl extends PanelCtrl { ...@@ -28,18 +28,18 @@ class DashListCtrl extends PanelCtrl {
this.panel.tags = [$scope.panel.tag]; this.panel.tags = [$scope.panel.tag];
delete this.panel.tag; delete this.panel.tag;
} }
this.events.on('refresh', this.onRefresh.bind(this));
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
} }
initEditMode() { onInitEditMode() {
super.initEditMode(); this.editorTabIndex = 1;
this.modes = ['starred', 'search', 'recently viewed']; this.modes = ['starred', 'search', 'recently viewed'];
this.icon = "fa fa-star"; this.addEditorTab('Options', 'public/app/plugins/panel/dashlist/editor.html');
this.addEditorTab('Options', () => {
return {templateUrl: 'public/app/plugins/panel/dashlist/editor.html'};
});
} }
refresh() { onRefresh() {
var params: any = {limit: this.panel.limit}; var params: any = {limit: this.panel.limit};
if (this.panel.mode === 'recently viewed') { if (this.panel.mode === 'recently viewed') {
......
...@@ -54,7 +54,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) { ...@@ -54,7 +54,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
}, scope); }, scope);
// Receive render events // Receive render events
scope.$on('render',function(event, renderData) { ctrl.events.on('render', function(renderData) {
data = renderData || data; data = renderData || data;
if (!data) { if (!data) {
ctrl.refresh(); ctrl.refresh();
...@@ -97,10 +97,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) { ...@@ -97,10 +97,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
return true; return true;
} }
if (ctrl.otherPanelInFullscreenMode()) {
return true;
}
if (!setElementHeight()) { return true; } if (!setElementHeight()) { return true; }
if(_.isString(data)) { if(_.isString(data)) {
......
...@@ -22,7 +22,7 @@ function (angular, _, $) { ...@@ -22,7 +22,7 @@ function (angular, _, $) {
var seriesList; var seriesList;
var i; var i;
scope.$on('render', function() { ctrl.events.on('render', function() {
data = ctrl.seriesList; data = ctrl.seriesList;
if (data) { if (data) {
render(); render();
......
...@@ -110,12 +110,11 @@ class GraphCtrl extends MetricsPanelCtrl { ...@@ -110,12 +110,11 @@ class GraphCtrl extends MetricsPanelCtrl {
this.events.on('data-received', this.onDataReceived.bind(this)); this.events.on('data-received', this.onDataReceived.bind(this));
this.events.on('data-error', this.onDataError.bind(this)); this.events.on('data-error', this.onDataError.bind(this));
this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this)); this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this));
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
this.events.on('init-panel-actions', this.onInitPanelActions.bind(this));
} }
initEditMode() { onInitEditMode() {
super.initEditMode();
this.icon = "fa fa-bar-chart";
this.addEditorTab('Axes & Grid', 'public/app/plugins/panel/graph/axisEditor.html', 2); this.addEditorTab('Axes & Grid', 'public/app/plugins/panel/graph/axisEditor.html', 2);
this.addEditorTab('Display Styles', 'public/app/plugins/panel/graph/styleEditor.html', 3); this.addEditorTab('Display Styles', 'public/app/plugins/panel/graph/styleEditor.html', 3);
...@@ -129,12 +128,10 @@ class GraphCtrl extends MetricsPanelCtrl { ...@@ -129,12 +128,10 @@ class GraphCtrl extends MetricsPanelCtrl {
this.unitFormats = kbn.getUnitFormats(); this.unitFormats = kbn.getUnitFormats();
} }
getExtendedMenu() { onInitPanelActions(actions) {
var menu = super.getExtendedMenu(); actions.push({text: 'Export CSV (series as rows)', click: 'ctrl.exportCsv()'});
menu.push({text: 'Export CSV (series as rows)', click: 'ctrl.exportCsv()'}); actions.push({text: 'Export CSV (series as columns)', click: 'ctrl.exportCsvColumns()'});
menu.push({text: 'Export CSV (series as columns)', click: 'ctrl.exportCsvColumns()'}); actions.push({text: 'Toggle legend', click: 'ctrl.toggleLegend()'});
menu.push({text: 'Toggle legend', click: 'ctrl.toggleLegend()'});
return menu;
} }
setUnitFormat(axis, subItem) { setUnitFormat(axis, subItem) {
......
...@@ -8,6 +8,7 @@ import $ from 'jquery'; ...@@ -8,6 +8,7 @@ import $ from 'jquery';
import helpers from 'test/specs/helpers'; import helpers from 'test/specs/helpers';
import TimeSeries from 'app/core/time_series2'; import TimeSeries from 'app/core/time_series2';
import moment from 'moment'; import moment from 'moment';
import {Emitter} from 'app/core/core';
describe('grafanaGraph', function() { describe('grafanaGraph', function() {
...@@ -24,13 +25,10 @@ describe('grafanaGraph', function() { ...@@ -24,13 +25,10 @@ describe('grafanaGraph', function() {
})); }));
beforeEach(angularMocks.inject(function($rootScope, $compile) { beforeEach(angularMocks.inject(function($rootScope, $compile) {
var ctrl: any = {}; var ctrl: any = {
var scope = $rootScope.$new(); events: new Emitter(),
scope.ctrl = ctrl; height: 200,
var element = angular.element("<div style='width:" + elementWidth + "px' grafana-graph><div>"); panel: {
ctrl.height = '200px';
ctrl.panel = {
legend: {}, legend: {},
grid: { }, grid: { },
y_formats: [], y_formats: [],
...@@ -38,17 +36,22 @@ describe('grafanaGraph', function() { ...@@ -38,17 +36,22 @@ describe('grafanaGraph', function() {
tooltip: { tooltip: {
shared: true shared: true
} }
}; },
renderingCompleted: sinon.spy(),
$rootScope.onAppEvent = sinon.spy(); hiddenSeries: {},
ctrl.otherPanelInFullscreenMode = sinon.spy(); dashboard: {timezone: 'browser'},
ctrl.renderingCompleted = sinon.spy(); range: {
ctrl.hiddenSeries = {};
ctrl.dashboard = { timezone: 'browser' };
ctrl.range = {
from: moment([2015, 1, 1, 10]), from: moment([2015, 1, 1, 10]),
to: moment([2015, 1, 1, 22]), to: moment([2015, 1, 1, 22]),
},
}; };
var scope = $rootScope.$new();
scope.ctrl = ctrl;
$rootScope.onAppEvent = sinon.spy();
ctx.data = []; ctx.data = [];
ctx.data.push(new TimeSeries({ ctx.data.push(new TimeSeries({
datapoints: [[1,1],[2,2]], datapoints: [[1,1],[2,2]],
...@@ -61,11 +64,12 @@ describe('grafanaGraph', function() { ...@@ -61,11 +64,12 @@ describe('grafanaGraph', function() {
setupFunc(ctrl, ctx.data); setupFunc(ctrl, ctx.data);
var element = angular.element("<div style='width:" + elementWidth + "px' grafana-graph><div>");
$compile(element)(scope); $compile(element)(scope);
scope.$digest(); scope.$digest();
$.plot = ctx.plotSpy = sinon.spy();
scope.$emit('render', ctx.data); $.plot = ctx.plotSpy = sinon.spy();
ctrl.events.emit('render', ctx.data);
ctx.plotData = ctx.plotSpy.getCall(0).args[1]; ctx.plotData = ctx.plotSpy.getCall(0).args[1];
ctx.plotOptions = ctx.plotSpy.getCall(0).args[2]; ctx.plotOptions = ctx.plotSpy.getCall(0).args[2];
})); }));
......
...@@ -235,14 +235,7 @@ class SingleStatCtrl extends MetricsPanelCtrl { ...@@ -235,14 +235,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
var templateSrv = this.templateSrv; var templateSrv = this.templateSrv;
var data, linkInfo; var data, linkInfo;
var $panelContainer = elem.find('.panel-container'); var $panelContainer = elem.find('.panel-container');
// change elem to singlestat panel
elem = elem.find('.singlestat-panel'); elem = elem.find('.singlestat-panel');
hookupDrilldownLinkTooltip();
scope.$on('render', function() {
render();
ctrl.renderingCompleted();
});
function setElementHeight() { function setElementHeight() {
elem.css('height', ctrl.height + 'px'); elem.css('height', ctrl.height + 'px');
...@@ -417,6 +410,13 @@ class SingleStatCtrl extends MetricsPanelCtrl { ...@@ -417,6 +410,13 @@ class SingleStatCtrl extends MetricsPanelCtrl {
drilldownTooltip.place_tt(e.pageX+20, e.pageY-15); drilldownTooltip.place_tt(e.pageX+20, e.pageY-15);
}); });
} }
hookupDrilldownLinkTooltip();
this.events.on('render', function() {
render();
ctrl.renderingCompleted();
});
} }
} }
......
...@@ -61,17 +61,16 @@ class TablePanelCtrl extends MetricsPanelCtrl { ...@@ -61,17 +61,16 @@ class TablePanelCtrl extends MetricsPanelCtrl {
this.events.on('data-received', this.onDataReceived.bind(this)); this.events.on('data-received', this.onDataReceived.bind(this));
this.events.on('data-error', this.onDataError.bind(this)); this.events.on('data-error', this.onDataError.bind(this));
this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this)); this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this));
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
this.events.on('init-panel-actions', this.onInitPanelActions.bind(this));
} }
initEditMode() { onInitEditMode() {
super.initEditMode();
this.addEditorTab('Options', tablePanelEditor, 2); this.addEditorTab('Options', tablePanelEditor, 2);
} }
getExtendedMenu() { onInitPanelActions(actions) {
var menu = super.getExtendedMenu(); actions.push({text: 'Export CSV', click: 'ctrl.exportCsv()'});
menu.push({text: 'Export CSV', click: 'ctrl.exportCsv()'});
return menu;
} }
issueQueries(datasource) { issueQueries(datasource) {
...@@ -211,7 +210,7 @@ class TablePanelCtrl extends MetricsPanelCtrl { ...@@ -211,7 +210,7 @@ class TablePanelCtrl extends MetricsPanelCtrl {
elem.off('click', '.table-panel-page-link'); elem.off('click', '.table-panel-page-link');
}); });
scope.$on('render', function(event, renderData) { ctrl.events.on('render', function(renderData) {
data = renderData || data; data = renderData || data;
if (data) { if (data) {
renderPanel(); renderPanel();
......
...@@ -20,18 +20,18 @@ export class TextPanelCtrl extends PanelCtrl { ...@@ -20,18 +20,18 @@ export class TextPanelCtrl extends PanelCtrl {
super($scope, $injector); super($scope, $injector);
_.defaults(this.panel, panelDefaults); _.defaults(this.panel, panelDefaults);
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
this.events.on('refresh', this.onRender.bind(this));
this.events.on('render', this.onRender.bind(this));
} }
initEditMode() { onInitEditMode() {
super.initEditMode();
this.icon = 'fa fa-text-width';
this.addEditorTab('Options', 'public/app/plugins/panel/text/editor.html'); this.addEditorTab('Options', 'public/app/plugins/panel/text/editor.html');
this.editorTabIndex = 1; this.editorTabIndex = 1;
} }
render() { onRender() {
super.render();
if (this.panel.mode === 'markdown') { if (this.panel.mode === 'markdown') {
this.renderMarkdown(this.panel.content); this.renderMarkdown(this.panel.content);
} else if (this.panel.mode === 'html') { } else if (this.panel.mode === 'html') {
......
import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'
import {Emitter} from 'app/core/core';
describe("Emitter", () => {
describe('given 2 subscribers', () => {
it('should notfiy subscribers', () => {
var events = new Emitter();
var sub1Called = false;
var sub2Called = false;
events.on('test', () => {
sub1Called = true;
});
events.on('test', () => {
sub2Called = true;
});
events.emit('test', null);
expect(sub1Called).to.be(true);
expect(sub2Called).to.be(true);
});
});
});
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