mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'panel_id_permalink'
This commit is contained in:
commit
2b865e3505
@ -11,7 +11,9 @@ function (angular, $, config, _) {
|
|||||||
var module = angular.module('grafana.controllers');
|
var module = angular.module('grafana.controllers');
|
||||||
|
|
||||||
module.controller('DashCtrl', function(
|
module.controller('DashCtrl', function(
|
||||||
$scope, $rootScope, dashboardKeybindings, filterSrv, dashboardSrv, panelMoveSrv, timer) {
|
$scope, $rootScope, dashboardKeybindings,
|
||||||
|
filterSrv, dashboardSrv, dashboardViewStateSrv,
|
||||||
|
panelMoveSrv, timer) {
|
||||||
|
|
||||||
$scope.editor = { index: 0 };
|
$scope.editor = { index: 0 };
|
||||||
$scope.panelNames = config.panels;
|
$scope.panelNames = config.panels;
|
||||||
@ -24,9 +26,9 @@ function (angular, $, config, _) {
|
|||||||
$scope.setupDashboard = function(event, dashboardData) {
|
$scope.setupDashboard = function(event, dashboardData) {
|
||||||
timer.cancel_all();
|
timer.cancel_all();
|
||||||
|
|
||||||
$rootScope.fullscreen = false;
|
|
||||||
|
|
||||||
$scope.dashboard = dashboardSrv.create(dashboardData);
|
$scope.dashboard = dashboardSrv.create(dashboardData);
|
||||||
|
$scope.dashboardViewState = dashboardViewStateSrv.create($scope);
|
||||||
|
|
||||||
$scope.grafana.style = $scope.dashboard.style;
|
$scope.grafana.style = $scope.dashboard.style;
|
||||||
|
|
||||||
$scope.filter = filterSrv;
|
$scope.filter = filterSrv;
|
||||||
|
@ -14,6 +14,7 @@ function (angular, _, moment, config) {
|
|||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.db = datasourceSrv.getGrafanaDB();
|
$scope.db = datasourceSrv.getGrafanaDB();
|
||||||
|
|
||||||
$scope.onAppEvent('save-dashboard', function() {
|
$scope.onAppEvent('save-dashboard', function() {
|
||||||
$scope.saveDashboard();
|
$scope.saveDashboard();
|
||||||
});
|
});
|
||||||
@ -23,10 +24,6 @@ function (angular, _, moment, config) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.exitFullscreen = function() {
|
|
||||||
$scope.emitAppEvent('panel-fullscreen-exit');
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.set_default = function() {
|
$scope.set_default = function() {
|
||||||
window.localStorage.grafanaDashboardDefault = $location.path();
|
window.localStorage.grafanaDashboardDefault = $location.path();
|
||||||
alertSrv.set('Home Set','This page has been set as your default dashboard','success',5000);
|
alertSrv.set('Home Set','This page has been set as your default dashboard','success',5000);
|
||||||
@ -78,6 +75,7 @@ function (angular, _, moment, config) {
|
|||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
alertSrv.set('Dashboard Saved', 'Dashboard has been saved as "' + result.title + '"','success', 5000);
|
alertSrv.set('Dashboard Saved', 'Dashboard has been saved as "' + result.title + '"','success', 5000);
|
||||||
|
|
||||||
|
$location.search({});
|
||||||
$location.path(result.url);
|
$location.path(result.url);
|
||||||
|
|
||||||
$rootScope.$emit('dashboard-saved', $scope.dashboard);
|
$rootScope.$emit('dashboard-saved', $scope.dashboard);
|
||||||
|
@ -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, _) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$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, _) {
|
|||||||
$scope.row.height = fixRowHeight($scope.row.height);
|
$scope.row.height = fixRowHeight($scope.row.height);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @scratch /panels/2
|
|
||||||
* --
|
|
||||||
*/
|
|
||||||
|
|
||||||
$scope.init();
|
$scope.init();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -41,6 +41,7 @@ function (angular, _, config, $) {
|
|||||||
|
|
||||||
var selectedDash = $scope.results.dashboards[$scope.selectedIndex];
|
var selectedDash = $scope.results.dashboards[$scope.selectedIndex];
|
||||||
if (selectedDash) {
|
if (selectedDash) {
|
||||||
|
$location.search({});
|
||||||
$location.path("/dashboard/db/" + selectedDash.id);
|
$location.path("/dashboard/db/" + selectedDash.id);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$('body').click(); // hack to force dropdown to close;
|
$('body').click(); // hack to force dropdown to close;
|
||||||
|
@ -21,7 +21,6 @@ function (angular, $, kbn, moment, _) {
|
|||||||
var legendSideLastValue = null;
|
var legendSideLastValue = null;
|
||||||
|
|
||||||
scope.$on('refresh',function() {
|
scope.$on('refresh',function() {
|
||||||
if (scope.otherPanelInFullscreenMode()) { return; }
|
|
||||||
scope.get_data();
|
scope.get_data();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -39,6 +38,10 @@ function (angular, $, kbn, moment, _) {
|
|||||||
// Receive render events
|
// Receive render events
|
||||||
scope.$on('render',function(event, renderData) {
|
scope.$on('render',function(event, renderData) {
|
||||||
data = renderData || data;
|
data = renderData || data;
|
||||||
|
if (!data) {
|
||||||
|
scope.get_data();
|
||||||
|
return;
|
||||||
|
}
|
||||||
annotations = data.annotations || annotations;
|
annotations = data.annotations || annotations;
|
||||||
render_panel();
|
render_panel();
|
||||||
});
|
});
|
||||||
|
@ -188,13 +188,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
|
|||||||
_.defaults($scope.panel.grid, _d.grid);
|
_.defaults($scope.panel.grid, _d.grid);
|
||||||
_.defaults($scope.panel.legend, _d.legend);
|
_.defaults($scope.panel.legend, _d.legend);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.hiddenSeries = {};
|
||||||
panelSrv.init($scope);
|
|
||||||
$scope.hiddenSeries = {};
|
|
||||||
if (!$scope.skipDataOnInit) {
|
|
||||||
$scope.get_data();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.updateTimeRange = function () {
|
$scope.updateTimeRange = function () {
|
||||||
$scope.range = $scope.filter.timeRange();
|
$scope.range = $scope.filter.timeRange();
|
||||||
@ -210,10 +204,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.get_data = function() {
|
$scope.get_data = function() {
|
||||||
delete $scope.panel.error;
|
|
||||||
|
|
||||||
$scope.panelMeta.loading = true;
|
|
||||||
|
|
||||||
$scope.updateTimeRange();
|
$scope.updateTimeRange();
|
||||||
|
|
||||||
var metricsQuery = {
|
var metricsQuery = {
|
||||||
@ -297,10 +287,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
|
|||||||
return series;
|
return series;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.otherPanelInFullscreenMode = function() {
|
|
||||||
return $rootScope.fullscreen && !$scope.fullscreen;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.render = function(data) {
|
$scope.render = function(data) {
|
||||||
$scope.$emit('render', data);
|
$scope.$emit('render', data);
|
||||||
};
|
};
|
||||||
@ -371,7 +357,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
|
|||||||
$scope.render();
|
$scope.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.init();
|
panelSrv.init($scope);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<li ng-show="fullscreen">
|
<li ng-show="dashboardViewState.fullscreen">
|
||||||
<a ng-click="exitFullscreen()">
|
<a ng-click="exitFullscreen()">
|
||||||
Back to dashboard
|
Back to dashboard
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div ng-controller="DashCtrl" body-class>
|
<div ng-controller="DashCtrl" body-class ng-class="{'dashboard-fullscreen': dashboardViewState.fullscreen}">
|
||||||
|
|
||||||
<div class="navbar navbar-static-top">
|
<div class="navbar navbar-static-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
@ -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 @@
|
|||||||
<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 @@
|
|||||||
<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>
|
||||||
|
@ -11,6 +11,7 @@ function (angular) {
|
|||||||
.when('/dashboard/db/:id', {
|
.when('/dashboard/db/:id', {
|
||||||
templateUrl: 'app/partials/dashboard.html',
|
templateUrl: 'app/partials/dashboard.html',
|
||||||
controller : 'DashFromDBProvider',
|
controller : 'DashFromDBProvider',
|
||||||
|
reloadOnSearch: false,
|
||||||
})
|
})
|
||||||
.when('/dashboard/elasticsearch/:id', {
|
.when('/dashboard/elasticsearch/:id', {
|
||||||
templateUrl: 'app/partials/dashboard.html',
|
templateUrl: 'app/partials/dashboard.html',
|
||||||
|
@ -11,5 +11,6 @@ define([
|
|||||||
'./unsavedChangesSrv',
|
'./unsavedChangesSrv',
|
||||||
'./dashboard/dashboardKeyBindings',
|
'./dashboard/dashboardKeyBindings',
|
||||||
'./dashboard/dashboardSrv',
|
'./dashboard/dashboardSrv',
|
||||||
|
'./dashboard/dashboardViewStateSrv',
|
||||||
],
|
],
|
||||||
function () {});
|
function () {});
|
||||||
|
@ -12,20 +12,6 @@ function(angular, $) {
|
|||||||
|
|
||||||
this.shortcuts = function(scope) {
|
this.shortcuts = function(scope) {
|
||||||
|
|
||||||
scope.onAppEvent('panel-fullscreen-enter', function() {
|
|
||||||
$rootScope.fullscreen = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scope.onAppEvent('panel-fullscreen-exit', function() {
|
|
||||||
$rootScope.fullscreen = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
scope.onAppEvent('dashboard-saved', function() {
|
|
||||||
if ($rootScope.fullscreen) {
|
|
||||||
scope.emitAppEvent('panel-fullscreen-exit');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scope.$on('$destroy', function() {
|
scope.$on('$destroy', function() {
|
||||||
keyboardManager.unbind('ctrl+f');
|
keyboardManager.unbind('ctrl+f');
|
||||||
keyboardManager.unbind('ctrl+h');
|
keyboardManager.unbind('ctrl+h');
|
||||||
@ -67,7 +53,7 @@ function(angular, $) {
|
|||||||
modalData.$scope.dismiss();
|
modalData.$scope.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.emitAppEvent('panel-fullscreen-exit');
|
scope.exitFullscreen();
|
||||||
}, { inputDisabled: true });
|
}, { inputDisabled: true });
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -10,7 +10,7 @@ function (angular, $, kbn, _) {
|
|||||||
|
|
||||||
var module = angular.module('grafana.services');
|
var module = angular.module('grafana.services');
|
||||||
|
|
||||||
module.service('dashboardSrv', function(timer, $rootScope, $timeout) {
|
module.factory('dashboardSrv', function(timer, $rootScope, $timeout) {
|
||||||
|
|
||||||
function DashboardModel (data) {
|
function DashboardModel (data) {
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ function (angular, $, kbn, _) {
|
|||||||
this.time = data.time || { from: 'now-6h', to: 'now' };
|
this.time = data.time || { from: 'now-6h', to: 'now' };
|
||||||
this.templating = data.templating || { list: [] };
|
this.templating = data.templating || { list: [] };
|
||||||
this.refresh = data.refresh;
|
this.refresh = data.refresh;
|
||||||
|
this.version = data.version || 0;
|
||||||
|
this.$state = data.$state;
|
||||||
|
|
||||||
if (this.nav.length === 0) {
|
if (this.nav.length === 0) {
|
||||||
this.nav.push({ type: 'timepicker' });
|
this.nav.push({ type: 'timepicker' });
|
||||||
@ -47,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');
|
||||||
};
|
};
|
||||||
@ -75,12 +136,32 @@ function (angular, $, kbn, _) {
|
|||||||
|
|
||||||
p.updateSchema = function(old) {
|
p.updateSchema = function(old) {
|
||||||
var i, j, row, panel;
|
var i, j, row, panel;
|
||||||
var isChanged = false;
|
var oldVersion = this.version;
|
||||||
|
this.version = 3;
|
||||||
|
|
||||||
if (this.version === 2) {
|
if (oldVersion === 3) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version 3 schema changes
|
||||||
|
// ensure panel ids
|
||||||
|
var maxId = this.getNextPanelId();
|
||||||
|
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) {
|
||||||
|
panel.id = maxId;
|
||||||
|
maxId += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldVersion === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version 2 schema changes
|
||||||
if (old.services) {
|
if (old.services) {
|
||||||
if (old.services.filter) {
|
if (old.services.filter) {
|
||||||
this.time = old.services.filter.time;
|
this.time = old.services.filter.time;
|
||||||
@ -95,7 +176,6 @@ function (angular, $, kbn, _) {
|
|||||||
panel = row.panels[j];
|
panel = row.panels[j];
|
||||||
if (panel.type === 'graphite') {
|
if (panel.type === 'graphite') {
|
||||||
panel.type = 'graph';
|
panel.type = 'graph';
|
||||||
isChanged = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panel.type === 'graph') {
|
if (panel.type === 'graph') {
|
||||||
@ -128,7 +208,7 @@ function (angular, $, kbn, _) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.version = 2;
|
this.version = 3;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
157
src/app/services/dashboard/dashboardViewStateSrv.js
Normal file
157
src/app/services/dashboard/dashboardViewStateSrv.js
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
define([
|
||||||
|
'angular',
|
||||||
|
'lodash',
|
||||||
|
'jquery',
|
||||||
|
],
|
||||||
|
function (angular, _, $) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var module = angular.module('grafana.services');
|
||||||
|
|
||||||
|
module.factory('dashboardViewStateSrv', function($location, $timeout) {
|
||||||
|
|
||||||
|
// represents the transient view state
|
||||||
|
// like fullscreen panel & edit
|
||||||
|
function DashboardViewState($scope) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$scope.exitFullscreen = function() {
|
||||||
|
self.update({ fullscreen: false });
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.onAppEvent('dashboard-saved', function() {
|
||||||
|
self.update({ fullscreen: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.onAppEvent('$routeUpdate', function() {
|
||||||
|
var urlState = self.getQueryStringState();
|
||||||
|
console.log("route updated!");
|
||||||
|
if (self.needsSync(urlState)) {
|
||||||
|
self.update(urlState, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.panelScopes = [];
|
||||||
|
this.$scope = $scope;
|
||||||
|
|
||||||
|
this.update(this.getQueryStringState(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
DashboardViewState.prototype.needsSync = function(urlState) {
|
||||||
|
if (urlState.fullscreen !== this.fullscreen) { return true; }
|
||||||
|
if (urlState.edit !== this.edit) { return true; }
|
||||||
|
if (urlState.panelId !== this.panelId) { return true; }
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.getQueryStringState = function() {
|
||||||
|
var queryParams = $location.search();
|
||||||
|
return {
|
||||||
|
panelId: parseInt(queryParams.panelId) || null,
|
||||||
|
fullscreen: queryParams.fullscreen ? true : false,
|
||||||
|
edit: queryParams.edit ? true : false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.update = function(state, skipUrlSync) {
|
||||||
|
_.extend(this, state);
|
||||||
|
|
||||||
|
if (!this.fullscreen) {
|
||||||
|
this.panelId = null;
|
||||||
|
this.edit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skipUrlSync) {
|
||||||
|
$location.search({
|
||||||
|
fullscreen: this.fullscreen ? true : null,
|
||||||
|
panelId: this.panelId,
|
||||||
|
edit: this.edit ? true : null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.syncState();
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.syncState = function() {
|
||||||
|
if (this.panelScopes.length === 0) { return; }
|
||||||
|
|
||||||
|
if (this.fullscreen) {
|
||||||
|
if (this.fullscreenPanel) {
|
||||||
|
this.leaveFullscreen(false);
|
||||||
|
}
|
||||||
|
var panelScope = this.getPanelScope(this.panelId);
|
||||||
|
this.enterFullscreen(panelScope);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.fullscreenPanel) {
|
||||||
|
this.leaveFullscreen(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.getPanelScope = function(id) {
|
||||||
|
return _.find(this.panelScopes, function(panelScope) {
|
||||||
|
return panelScope.panel.id === id;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.leaveFullscreen = function(render) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.fullscreenPanel.editMode = false;
|
||||||
|
self.fullscreenPanel.fullscreen = false;
|
||||||
|
delete self.fullscreenPanel.height;
|
||||||
|
|
||||||
|
if (!render) { return false;}
|
||||||
|
|
||||||
|
$timeout(function() {
|
||||||
|
if (self.oldTimeRange !== self.fullscreenPanel.range) {
|
||||||
|
self.$scope.dashboard.emit_refresh();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.fullscreenPanel.$emit('render');
|
||||||
|
}
|
||||||
|
delete self.fullscreenPanel;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.enterFullscreen = function(panelScope) {
|
||||||
|
var docHeight = $(window).height();
|
||||||
|
var editHeight = Math.floor(docHeight * 0.3);
|
||||||
|
var fullscreenHeight = Math.floor(docHeight * 0.7);
|
||||||
|
this.oldTimeRange = panelScope.range;
|
||||||
|
|
||||||
|
panelScope.height = this.edit ? editHeight : fullscreenHeight;
|
||||||
|
panelScope.editMode = this.edit;
|
||||||
|
this.fullscreenPanel = panelScope;
|
||||||
|
|
||||||
|
$(window).scrollTop(0);
|
||||||
|
|
||||||
|
panelScope.fullscreen = true;
|
||||||
|
|
||||||
|
$timeout(function() {
|
||||||
|
panelScope.$emit('render');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
DashboardViewState.prototype.registerPanel = function(panelScope) {
|
||||||
|
var self = this;
|
||||||
|
self.panelScopes.push(panelScope);
|
||||||
|
|
||||||
|
if (self.panelId === panelScope.panel.id) {
|
||||||
|
self.enterFullscreen(panelScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
panelScope.$on('$destroy', function() {
|
||||||
|
self.panelScopes = _.without(self.panelScopes, panelScope);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
create: function($scope) {
|
||||||
|
return new DashboardViewState($scope);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
@ -1,9 +1,8 @@
|
|||||||
define([
|
define([
|
||||||
'angular',
|
'angular',
|
||||||
'lodash',
|
'lodash',
|
||||||
'jquery',
|
|
||||||
],
|
],
|
||||||
function (angular, _, $) {
|
function (angular, _) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
var module = angular.module('grafana.services');
|
||||||
@ -22,12 +21,12 @@ function (angular, _, $) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Edit',
|
text: 'Edit',
|
||||||
click: "toggleFullscreenEdit()",
|
click: "toggleFullscreen(true)",
|
||||||
condition: $scope.panelMeta.fullscreenEdit
|
condition: $scope.panelMeta.fullscreenEdit
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "Fullscreen",
|
text: "Fullscreen",
|
||||||
click: 'toggleFullscreen()',
|
click: 'toggleFullscreen(false)',
|
||||||
condition: $scope.panelMeta.fullscreenView
|
condition: $scope.panelMeta.fullscreenView
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -71,46 +70,6 @@ function (angular, _, $) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.enterFullscreenMode = function(options) {
|
|
||||||
var docHeight = $(window).height();
|
|
||||||
var editHeight = Math.floor(docHeight * 0.3);
|
|
||||||
var fullscreenHeight = Math.floor(docHeight * 0.7);
|
|
||||||
var oldTimeRange = $scope.range;
|
|
||||||
|
|
||||||
$scope.height = options.edit ? editHeight : fullscreenHeight;
|
|
||||||
$scope.editMode = options.edit;
|
|
||||||
|
|
||||||
if (!$scope.fullscreen) {
|
|
||||||
var closeEditMode = $rootScope.$on('panel-fullscreen-exit', function() {
|
|
||||||
$scope.editMode = false;
|
|
||||||
$scope.fullscreen = false;
|
|
||||||
delete $scope.height;
|
|
||||||
|
|
||||||
closeEditMode();
|
|
||||||
|
|
||||||
$timeout(function() {
|
|
||||||
if (oldTimeRange !== $scope.range) {
|
|
||||||
$scope.dashboard.emit_refresh();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$scope.$emit('render');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).scrollTop(0);
|
|
||||||
|
|
||||||
$scope.fullscreen = true;
|
|
||||||
|
|
||||||
$rootScope.$emit('panel-fullscreen-enter');
|
|
||||||
|
|
||||||
$timeout(function() {
|
|
||||||
$scope.$emit('render');
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.addDataQuery = function() {
|
$scope.addDataQuery = function() {
|
||||||
$scope.panel.targets.push({target: ''});
|
$scope.panel.targets.push({target: ''});
|
||||||
};
|
};
|
||||||
@ -135,22 +94,12 @@ function (angular, _, $) {
|
|||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleFullscreenEdit = function() {
|
$scope.toggleFullscreen = function(edit) {
|
||||||
if ($scope.editMode) {
|
$scope.dashboardViewState.update({ fullscreen: true, edit: edit, panelId: $scope.panel.id });
|
||||||
$rootScope.$emit('panel-fullscreen-exit');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.enterFullscreenMode({edit: true});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleFullscreen = function() {
|
$scope.otherPanelInFullscreenMode = function() {
|
||||||
if ($scope.fullscreen && !$scope.editMode) {
|
return $scope.dashboardViewState.fullscreen && !$scope.fullscreen;
|
||||||
$rootScope.$emit('panel-fullscreen-exit');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.enterFullscreenMode({ edit: false });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Post init phase
|
// Post init phase
|
||||||
@ -162,6 +111,24 @@ function (angular, _, $) {
|
|||||||
|
|
||||||
$scope.datasources = datasourceSrv.getMetricSources();
|
$scope.datasources = datasourceSrv.getMetricSources();
|
||||||
$scope.setDatasource($scope.panel.datasource);
|
$scope.setDatasource($scope.panel.datasource);
|
||||||
|
|
||||||
|
$scope.dashboardViewState.registerPanel($scope);
|
||||||
|
|
||||||
|
if ($scope.get_data) {
|
||||||
|
var panel_get_data = $scope.get_data;
|
||||||
|
$scope.get_data = function() {
|
||||||
|
if ($scope.otherPanelInFullscreenMode()) { return; }
|
||||||
|
|
||||||
|
delete $scope.panel.error;
|
||||||
|
$scope.panelMeta.loading = true;
|
||||||
|
|
||||||
|
panel_get_data();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!$scope.skipDataOnInit) {
|
||||||
|
$scope.get_data();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ function (angular, _, kbn) {
|
|||||||
timerInstance = setInterval(function() {
|
timerInstance = setInterval(function() {
|
||||||
$rootScope.$apply(function() {
|
$rootScope.$apply(function() {
|
||||||
angular.element(window).unbind('resize');
|
angular.element(window).unbind('resize');
|
||||||
|
$location.search({});
|
||||||
$location.path(dashboards[index % dashboards.length].url);
|
$location.path(dashboards[index % dashboards.length].url);
|
||||||
index++;
|
index++;
|
||||||
});
|
});
|
||||||
|
@ -28,10 +28,12 @@ function(angular, _, config) {
|
|||||||
$rootScope.$on("dashboard-saved", function(event, savedDashboard) {
|
$rootScope.$on("dashboard-saved", function(event, savedDashboard) {
|
||||||
self.original = angular.copy(savedDashboard);
|
self.original = angular.copy(savedDashboard);
|
||||||
self.current = savedDashboard;
|
self.current = savedDashboard;
|
||||||
|
self.orignalPath = $location.path();
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$on("$routeChangeSuccess", function() {
|
$rootScope.$on("$routeChangeSuccess", function() {
|
||||||
self.original = null;
|
self.original = null;
|
||||||
|
self.originalPath = $location.path();
|
||||||
});
|
});
|
||||||
|
|
||||||
window.onbeforeunload = function() {
|
window.onbeforeunload = function() {
|
||||||
@ -42,6 +44,11 @@ function(angular, _, config) {
|
|||||||
|
|
||||||
this.init = function() {
|
this.init = function() {
|
||||||
$rootScope.$on("$locationChangeStart", function(event, next) {
|
$rootScope.$on("$locationChangeStart", function(event, next) {
|
||||||
|
if (self.originalPath === $location.path()) {
|
||||||
|
console.log("skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (self.has_unsaved_changes()) {
|
if (self.has_unsaved_changes()) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
self.next = next;
|
self.next = next;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<strong>{{alert.title}}</strong> <span ng-bind-html='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
|
<strong>{{alert.title}}</strong> <span ng-bind-html='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-view ng-class="{'dashboard-fullscreen': fullscreen}"></div>
|
<div ng-view ></div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -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([
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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] }},
|
||||||
@ -54,6 +112,10 @@ define([
|
|||||||
expect(model.title).to.be('No Title');
|
expect(model.title).to.be('No Title');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have panel id', function() {
|
||||||
|
expect(graph.id).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should move time and filtering list', function() {
|
it('should move time and filtering list', function() {
|
||||||
expect(model.time.from).to.be('now-1d');
|
expect(model.time.from).to.be('now-1d');
|
||||||
expect(model.templating.list[0]).to.be(1);
|
expect(model.templating.list[0]).to.be(1);
|
||||||
@ -73,10 +135,9 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('dashboard schema version should be set to latest', function() {
|
it('dashboard schema version should be set to latest', function() {
|
||||||
expect(model.version).to.be(2);
|
expect(model.version).to.be(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
37
src/test/specs/dashboardViewStateSrv-specs.js
Normal file
37
src/test/specs/dashboardViewStateSrv-specs.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
define([
|
||||||
|
'services/dashboard/dashboardViewStateSrv'
|
||||||
|
], function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe('when updating view state', function() {
|
||||||
|
var viewState, location;
|
||||||
|
|
||||||
|
beforeEach(module('grafana.services'));
|
||||||
|
|
||||||
|
beforeEach(inject(function(dashboardViewStateSrv, $location, $rootScope) {
|
||||||
|
$rootScope.onAppEvent = function(){};
|
||||||
|
viewState = dashboardViewStateSrv.create($rootScope);
|
||||||
|
location = $location;
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('to fullscreen true and edit true', function() {
|
||||||
|
it('should update querystring and view state', function() {
|
||||||
|
var updateState = { fullscreen: true, edit: true, panelId: 1 };
|
||||||
|
viewState.update(updateState);
|
||||||
|
expect(location.search()).to.eql(updateState);
|
||||||
|
expect(viewState.fullscreen).to.be(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('to fullscreen false', function() {
|
||||||
|
it('should remove params from query string', function() {
|
||||||
|
viewState.update({fullscreen: true, panelId: 1, edit: true});
|
||||||
|
viewState.update({fullscreen: false});
|
||||||
|
expect(location.search()).to.eql({});
|
||||||
|
expect(viewState.fullscreen).to.be(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -26,6 +26,8 @@ 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();
|
||||||
|
|
||||||
$rootScope.colors = [];
|
$rootScope.colors = [];
|
||||||
for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); }
|
for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); }
|
||||||
@ -54,6 +56,11 @@ define([
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DashboardViewStateStub() {
|
||||||
|
this.registerPanel = function() {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function FilterSrvStub() {
|
function FilterSrvStub() {
|
||||||
this.time = { from:'now-1h', to: 'now'};
|
this.time = { from:'now-1h', to: 'now'};
|
||||||
this.timeRange = function(parse) {
|
this.timeRange = function(parse) {
|
||||||
|
@ -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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -124,6 +124,7 @@ require([
|
|||||||
'specs/filterSrv-specs',
|
'specs/filterSrv-specs',
|
||||||
'specs/kbn-format-specs',
|
'specs/kbn-format-specs',
|
||||||
'specs/dashboardSrv-specs',
|
'specs/dashboardSrv-specs',
|
||||||
|
'specs/dashboardViewStateSrv-specs',
|
||||||
'specs/influxSeries-specs'
|
'specs/influxSeries-specs'
|
||||||
], function () {
|
], function () {
|
||||||
window.__karma__.start();
|
window.__karma__.start();
|
||||||
|
Loading…
Reference in New Issue
Block a user