Commit 56269758 by Torkel Ödegaard

refactoring of panel manipulation, moved to dashboard model

parent 436f6bda
...@@ -32,36 +32,13 @@ function (angular, app, _) { ...@@ -32,36 +32,13 @@ function (angular, app, _) {
} }
}; };
$scope.rowSpan = function(row) { // This can be overridden by individual panels
return _.reduce(row.panels, function(p,v) {
return p + v.span;
},0);
};
// This can be overridden by individual panels
$scope.close_edit = function() { $scope.close_edit = function() {
$scope.$broadcast('render'); $scope.$broadcast('render');
}; };
$scope.add_panel = function(panel) { $scope.add_panel = function(panel) {
var rowSpan = $scope.rowSpan($scope.row); $scope.dashboard.add_panel(panel, $scope.row);
var panelCount = $scope.row.panels.length;
var space = (12 - rowSpan) - panel.span;
// try to make room of there is no space left
if (space <= 0) {
if (panelCount === 1) {
$scope.row.panels[0].span = 6;
panel.span = 6;
}
else if (panelCount === 2) {
$scope.row.panels[0].span = 4;
$scope.row.panels[1].span = 4;
panel.span = 4;
}
}
$scope.row.panels.push(panel);
}; };
$scope.delete_row = function() { $scope.delete_row = function() {
...@@ -100,45 +77,17 @@ function (angular, app, _) { ...@@ -100,45 +77,17 @@ function (angular, app, _) {
}; };
$scope.duplicatePanel = function(panel, row) { $scope.duplicatePanel = function(panel, row) {
row = row || $scope.row; $scope.dashboard.duplicatePanel(panel, row || $scope.row);
var currentRowSpan = $scope.rowSpan(row);
if (currentRowSpan <= 9) {
row.panels.push(angular.copy(panel));
}
else {
var rowsList = $scope.dashboard.rows;
var rowIndex = _.indexOf(rowsList, row);
if (rowIndex === rowsList.length - 1) {
var newRow = angular.copy($scope.row);
newRow.panels = [];
$scope.dashboard.rows.push(newRow);
$scope.duplicatePanel(panel, newRow);
}
else {
$scope.duplicatePanel(panel, rowsList[rowIndex+1]);
}
}
}; };
$scope.reset_panel = function(type) { $scope.reset_panel = function(type) {
var var defaultSpan = 12;
defaultSpan = 12, var _as = 12 - $scope.dashboard.rowSpan($scope.row);
_as = 12-$scope.rowSpan($scope.row);
$scope.panel = { $scope.panel = {
error : false, error : false,
/** @scratch /panels/1
* span:: A number, 1-12, that describes the width of the panel.
*/
span : _as < defaultSpan && _as > 0 ? _as : defaultSpan, span : _as < defaultSpan && _as > 0 ? _as : defaultSpan,
/** @scratch /panels/1
* editable:: Enable or disable the edit button the the panel
*/
editable: true, editable: true,
/** @scratch /panels/1
* type:: The type of panel this object contains. Each panel type will require additional
* properties. See the panel types list to the right.
*/
type : type type : type
}; };
...@@ -155,10 +104,6 @@ function (angular, app, _) { ...@@ -155,10 +104,6 @@ function (angular, app, _) {
$scope.row.height = fixRowHeight($scope.row.height); $scope.row.height = fixRowHeight($scope.row.height);
}; };
/** @scratch /panels/2
* --
*/
$scope.init(); $scope.init();
}); });
......
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
</div> </div>
</div> </div>
<div ng-show="rowSpan(row) < 10 && dashboard.$$panelDragging" class="panel" style="margin:5px;width:30%;background:rgba(100,100,100,0.50)" ng-class="{'dragInProgress':dashboard.panelDragging}" ng-style="{height:row.height}" data-drop="true" ng-model="row.panels" data-jqyoui-options jqyoui-droppable="{index:row.panels.length,mutate:false,onDrop:'panelMoveDrop',onOver:'panelMoveOver',onOut:'panelMoveOut'}"> <div ng-show="dashboard.rowSpan(row) < 10 && dashboard.$$panelDragging" class="panel" style="margin:5px;width:30%;background:rgba(100,100,100,0.50)" ng-class="{'dragInProgress':dashboard.panelDragging}" ng-style="{height:row.height}" data-drop="true" ng-model="row.panels" data-jqyoui-options jqyoui-droppable="{index:row.panels.length,mutate:false,onDrop:'panelMoveDrop',onOver:'panelMoveOver',onOut:'panelMoveOut'}">
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<thead> <thead>
<th>Title</th> <th>Title</th>
<th>Type</th> <th>Type</th>
<th>Span <span class="small">({{rowSpan(row)}}/12)</span></th> <th>Span <span class="small">({{dashboard.rowSpan(row)}}/12)</span></th>
<th>Delete</th> <th>Delete</th>
<th>Move</th> <th>Move</th>
<th></th> <th></th>
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<h4>Select Panel Type</h4> <h4>Select Panel Type</h4>
<form class="form-inline"> <form class="form-inline">
<select class="input-medium" ng-model="panel.type" ng-options="panelType for panelType in availablePanels|stringSort"></select> <select class="input-medium" ng-model="panel.type" ng-options="panelType for panelType in availablePanels|stringSort"></select>
<small ng-show="rowSpan(row) > 11"> <small ng-show="dashboard.rowSpan(row) > 11">
Note: This row is full, new panels will wrap to a new line. You should add another row. Note: This row is full, new panels will wrap to a new line. You should add another row.
</small> </small>
</form> </form>
......
...@@ -49,6 +49,65 @@ function (angular, $, kbn, _) { ...@@ -49,6 +49,65 @@ function (angular, $, kbn, _) {
var p = DashboardModel.prototype; var p = DashboardModel.prototype;
p.getNextPanelId = function() {
var i, j, row, panel, max = 0;
for (i = 0; i < this.rows.length; i++) {
row = this.rows[i];
for (j = 0; j < row.panels.length; j++) {
panel = row.panels[j];
if (panel.id > max) { max = panel.id; }
}
}
return max + 1;
};
p.rowSpan = function(row) {
return _.reduce(row.panels, function(p,v) {
return p + v.span;
},0);
};
p.add_panel = function(panel, row) {
var rowSpan = this.rowSpan(row);
var panelCount = row.panels.length;
var space = (12 - rowSpan) - panel.span;
panel.id = this.getNextPanelId();
// try to make room of there is no space left
if (space <= 0) {
if (panelCount === 1) {
row.panels[0].span = 6;
panel.span = 6;
}
else if (panelCount === 2) {
row.panels[0].span = 4;
row.panels[1].span = 4;
panel.span = 4;
}
}
row.panels.push(panel);
};
p.duplicatePanel = function(panel, row) {
var rowIndex = _.indexOf(this.rows, row);
var newPanel = angular.copy(panel);
newPanel.id = this.getNextPanelId();
while(rowIndex < this.rows.length) {
var currentRow = this.rows[rowIndex];
if (this.rowSpan(currentRow) <= 9) {
currentRow.panels.push(newPanel);
return;
}
rowIndex++;
}
var newRow = angular.copy(row);
newRow.panels = [newPanel];
this.rows.push(newRow);
};
p.emit_refresh = function() { p.emit_refresh = function() {
$rootScope.$broadcast('refresh'); $rootScope.$broadcast('refresh');
}; };
...@@ -86,13 +145,15 @@ function (angular, $, kbn, _) { ...@@ -86,13 +145,15 @@ function (angular, $, kbn, _) {
// Version 3 schema changes // Version 3 schema changes
// ensure panel ids // ensure panel ids
var panelId = 1; var maxId = this.getNextPanelId();
for (i = 0; i < this.rows.length; i++) { for (i = 0; i < this.rows.length; i++) {
row = this.rows[i]; row = this.rows[i];
for (j = 0; j < row.panels.length; j++) { for (j = 0; j < row.panels.length; j++) {
panel = row.panels[j]; panel = row.panels[j];
panel.id = panelId; if (!panel.id) {
panelId += 1; panel.id = maxId;
maxId += 1;
}
} }
} }
......
...@@ -7,7 +7,6 @@ define([ ...@@ -7,7 +7,6 @@ define([
var model; var model;
beforeEach(module('grafana.services')); beforeEach(module('grafana.services'));
beforeEach(inject(function(dashboardSrv) { beforeEach(inject(function(dashboardSrv) {
model = dashboardSrv.create({}); model = dashboardSrv.create({});
})); }));
...@@ -24,12 +23,71 @@ define([ ...@@ -24,12 +23,71 @@ define([
}); });
describe('when getting next panel id', function() {
var model;
beforeEach(module('grafana.services'));
beforeEach(inject(function(dashboardSrv) {
model = dashboardSrv.create({
rows: [{ panels: [{ id: 5 }]}]
});
}));
it('should return max id + 1', function() {
expect(model.getNextPanelId()).to.be(6);
});
});
describe('row and panel manipulation', function() {
var dashboard;
beforeEach(module('grafana.services'));
beforeEach(inject(function(dashboardSrv) {
dashboard = dashboardSrv.create({});
}));
it('row span should sum spans', function() {
var spanLeft = dashboard.rowSpan({ panels: [{ span: 2 }, { span: 3 }] });
expect(spanLeft).to.be(5);
});
it('adding default should split span in half', function() {
dashboard.rows = [{ panels: [{ span: 12, id: 7 }] }];
dashboard.add_panel({span: 4}, dashboard.rows[0]);
expect(dashboard.rows[0].panels[0].span).to.be(6);
expect(dashboard.rows[0].panels[1].span).to.be(6);
expect(dashboard.rows[0].panels[1].id).to.be(8);
});
it('duplicate panel should try to add it to same row', function() {
var panel = { span: 4, attr: '123', id: 10 };
dashboard.rows = [{ panels: [panel] }];
dashboard.duplicatePanel(panel, dashboard.rows[0]);
expect(dashboard.rows[0].panels[0].span).to.be(4);
expect(dashboard.rows[0].panels[1].span).to.be(4);
expect(dashboard.rows[0].panels[1].attr).to.be('123');
expect(dashboard.rows[0].panels[1].id).to.be(11);
});
it('duplicate should add row if there is no space left', function() {
var panel = { span: 12, attr: '123' };
dashboard.rows = [{ panels: [panel] }];
dashboard.duplicatePanel(panel, dashboard.rows[0]);
expect(dashboard.rows[0].panels[0].span).to.be(12);
expect(dashboard.rows[0].panels.length).to.be(1);
expect(dashboard.rows[1].panels[0].attr).to.be('123');
});
});
describe('when creating dashboard with old schema', function() { describe('when creating dashboard with old schema', function() {
var model; var model;
var graph; var graph;
beforeEach(module('grafana.services')); beforeEach(module('grafana.services'));
beforeEach(inject(function(dashboardSrv) { beforeEach(inject(function(dashboardSrv) {
model = dashboardSrv.create({ model = dashboardSrv.create({
services: { filter: { time: { from: 'now-1d', to: 'now'}, list: [1] }}, services: { filter: { time: { from: 'now-1d', to: 'now'}, list: [1] }},
......
...@@ -26,6 +26,7 @@ define([ ...@@ -26,6 +26,7 @@ define([
self.scope.panel = {}; self.scope.panel = {};
self.scope.row = { panels:[] }; self.scope.row = { panels:[] };
self.scope.filter = new FilterSrvStub(); self.scope.filter = new FilterSrvStub();
self.scope.dashboard = {};
self.scope.dashboardViewState = new DashboardViewStateStub(); self.scope.dashboardViewState = new DashboardViewStateStub();
$rootScope.colors = []; $rootScope.colors = [];
......
...@@ -12,50 +12,6 @@ define([ ...@@ -12,50 +12,6 @@ define([
beforeEach(ctx.providePhase()); beforeEach(ctx.providePhase());
beforeEach(ctx.createControllerPhase('RowCtrl')); beforeEach(ctx.createControllerPhase('RowCtrl'));
describe('when getting rowSpan', function() {
it('should return sum of panels spans', function() {
var spanLeft = ctx.scope.rowSpan({ panels: [{ span: 2 }, { span: 3 }] });
expect(spanLeft).to.be(5);
});
});
describe('when adding panel to row with 12 span panel', function() {
it('should split span in half and add panel with defaults', function() {
ctx.scope.row = { panels: [{ span: 12 }] };
ctx.scope.add_panel_default('graph');
expect(ctx.scope.row.panels[0].span).to.be(6);
expect(ctx.scope.row.panels[1].span).to.be(6);
expect(ctx.scope.row.panels[1].type).to.be('graph');
});
});
describe('when duplicating panel', function() {
it('should try to add it to same row', function() {
var panel = { span: 4, attr: '123' };
ctx.scope.row = { panels: [panel] };
ctx.scope.duplicatePanel(panel, ctx.scope.row);
expect(ctx.scope.row.panels[0].span).to.be(4);
expect(ctx.scope.row.panels[1].span).to.be(4);
expect(ctx.scope.row.panels[1].attr).to.be('123');
});
});
describe('when duplicating panel', function() {
it('should add row if there is no space left', function() {
var panel = { span: 12, attr: '123' };
ctx.scope.row = { panels: [panel] };
ctx.scope.dashboard = { rows: [ctx.scope.row] };
ctx.scope.duplicatePanel(panel, ctx.scope.row);
expect(ctx.scope.row.panels[0].span).to.be(12);
expect(ctx.scope.row.panels.length).to.be(1);
expect(ctx.scope.dashboard.rows[1].panels[0].attr).to.be('123');
});
});
}); });
}); });
......
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