+
diff --git a/src/app/partials/unsaved-changes.html b/src/app/partials/unsaved-changes.html
index 87220e41e8d..b025575e7e7 100644
--- a/src/app/partials/unsaved-changes.html
+++ b/src/app/partials/unsaved-changes.html
@@ -4,7 +4,10 @@
Unsaved changes
-
+
+ {{changes}}
+
+
Cancel
Save
Ignore
@@ -13,4 +16,4 @@
\ No newline at end of file
+
diff --git a/src/app/services/dashboard/dashboardModel.js b/src/app/services/dashboard/dashboardModel.js
index d069a4b43b2..ecb5af07494 100644
--- a/src/app/services/dashboard/dashboardModel.js
+++ b/src/app/services/dashboard/dashboardModel.js
@@ -2,7 +2,8 @@ define([
'angular',
'jquery',
'kbn',
- 'underscore'
+ 'underscore',
+ '../timer',
],
function (angular, $, kbn, _) {
'use strict';
@@ -17,7 +18,7 @@ function (angular, $, kbn, _) {
data = {};
}
- this.title = data.title;
+ this.title = data.title || 'No Title';
this.tags = data.tags || [];
this.style = data.style || "dark";
this.timezone = data.timezone || 'browser';
@@ -25,7 +26,8 @@ function (angular, $, kbn, _) {
this.rows = data.rows || [];
this.pulldowns = data.pulldowns || [];
this.nav = data.nav || [];
- this.services = data.services || {};
+ this.time = data.time || { from: 'now-6h', to: 'now' };
+ this.templating = data.templating || { list: [] };
if (this.nav.length === 0) {
this.nav.push({ type: 'timepicker' });
@@ -39,13 +41,7 @@ function (angular, $, kbn, _) {
this.pulldowns.push({ type: 'annotations', enable: false });
}
- _.each(this.rows, function(row) {
- _.each(row.panels, function(panel) {
- if (panel.type === 'graphite') {
- panel.type = 'graph';
- }
- });
- });
+ this.updateSchema(data);
}
var p = DashboardModel.prototype;
@@ -76,6 +72,64 @@ function (angular, $, kbn, _) {
}
};
+ p.updateSchema = function(old) {
+ var i, j, row, panel;
+ var isChanged = false;
+
+ if (this.version === 2) {
+ return;
+ }
+
+ if (old.services) {
+ if (old.services.filter) {
+ this.time = old.services.filter.time;
+ this.templating.list = old.services.filter.list;
+ }
+ delete this.services;
+ }
+
+ 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.type === 'graphite') {
+ panel.type = 'graph';
+ isChanged = true;
+ }
+
+ if (panel.type === 'graph') {
+ if (_.isBoolean(panel.legend)) {
+ panel.legend = { show: panel.legend };
+ }
+
+ if (panel.grid) {
+ if (panel.grid.min) {
+ panel.grid.leftMin = panel.grid.min;
+ delete panel.grid.min;
+ }
+
+ if (panel.grid.max) {
+ panel.grid.leftMax = panel.grid.max;
+ delete panel.grid.max;
+ }
+ }
+
+ if (panel.y_format) {
+ panel.y_formats[0] = panel.y_format;
+ delete panel.y_format;
+ }
+
+ if (panel.y2_format) {
+ panel.y_formats[1] = panel.y2_format;
+ delete panel.y2_format;
+ }
+ }
+ }
+ }
+
+ this.version = 2;
+ };
+
return {
create: function(dashboard) {
return new DashboardModel(dashboard);
diff --git a/src/app/services/filterSrv.js b/src/app/services/filterSrv.js
index 223f6190e68..cbd0af62364 100644
--- a/src/app/services/filterSrv.js
+++ b/src/app/services/filterSrv.js
@@ -9,12 +9,6 @@ define([
var module = angular.module('grafana.services');
module.factory('filterSrv', function($rootScope, $timeout, $routeParams) {
- // defaults
- var _d = {
- templateParameters: [],
- time: {}
- };
-
var result = {
updateTemplateData: function(initial) {
@@ -86,26 +80,14 @@ define([
removeTemplateParameter: function(templateParameter) {
this.templateParameters = _.without(this.templateParameters, templateParameter);
- this.dashboard.services.filter.list = this.templateParameters;
+ this.dashboard.templating.list = this.templateParameters;
},
init: function(dashboard) {
- _.defaults(this, _d);
this.dashboard = dashboard;
this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
-
- if (!this.dashboard.services.filter) {
- this.dashboard.services.filter = {
- list: [],
- time: {
- from: '1h',
- to: 'now'
- }
- };
- }
-
- this.time = dashboard.services.filter.time;
- this.templateParameters = dashboard.services.filter.list || [];
+ this.time = dashboard.time;
+ this.templateParameters = dashboard.templating.list;
this.updateTemplateData(true);
}
};
diff --git a/src/app/services/graphite/gfunc.js b/src/app/services/graphite/gfunc.js
index 63c28bc1dfc..07ca4e4f58c 100644
--- a/src/app/services/graphite/gfunc.js
+++ b/src/app/services/graphite/gfunc.js
@@ -216,6 +216,7 @@ function (_) {
addFuncDef({
name: 'randomWalk',
+ fake: true,
category: categories.Special,
params: [{ name: "name", type: "string", }],
defaultParams: ['randomWalk']
diff --git a/src/app/services/unsavedChangesSrv.js b/src/app/services/unsavedChangesSrv.js
index 1c05ae86377..aacbabfd326 100644
--- a/src/app/services/unsavedChangesSrv.js
+++ b/src/app/services/unsavedChangesSrv.js
@@ -74,7 +74,7 @@ function(angular, _, config) {
var original = self.original;
// ignore timespan changes
- current.services.filter.time = original.services.filter.time = {};
+ current.time = original.time = {};
current.refresh = original.refresh;
diff --git a/src/test/mocks/dashboard-mock.js b/src/test/mocks/dashboard-mock.js
index 2ee9c659337..7ec0e5e9997 100644
--- a/src/test/mocks/dashboard-mock.js
+++ b/src/test/mocks/dashboard-mock.js
@@ -18,11 +18,9 @@ define([],
rows: [],
pulldowns: [ { type: 'templating' }, { type: 'annotations' } ],
nav: [ { type: 'timepicker' } ],
- services: {
- filter: {
- time: {},
- list: []
- }
+ time: {},
+ templating: {
+ list: []
},
refresh: true
};
diff --git a/src/test/specs/dashboardModel-specs.js b/src/test/specs/dashboardModel-specs.js
new file mode 100644
index 00000000000..5b92caafe46
--- /dev/null
+++ b/src/test/specs/dashboardModel-specs.js
@@ -0,0 +1,82 @@
+define([
+ 'services/dashboard/dashboardModel'
+], function() {
+ 'use strict';
+
+ describe('when creating new dashboard with defaults only', function() {
+ var model;
+
+ beforeEach(module('grafana.services'));
+
+ beforeEach(inject(function(dashboard) {
+ model = dashboard.create({});
+ }));
+
+ it('should have title', function() {
+ expect(model.title).to.be('No Title');
+ });
+
+ it('should have default properties', function() {
+ expect(model.rows.length).to.be(0);
+ expect(model.nav.length).to.be(1);
+ expect(model.pulldowns.length).to.be(2);
+ });
+
+ });
+
+ describe('when creating dashboard with old schema', function() {
+ var model;
+ var graph;
+
+ beforeEach(module('grafana.services'));
+
+ beforeEach(inject(function(dashboard) {
+ model = dashboard.create({
+ services: { filter: { time: { from: 'now-1d', to: 'now'}, list: [1] }},
+ rows: [
+ {
+ panels: [
+ {
+ type: 'graphite',
+ legend: true,
+ grid: { min: 1, max: 10 }
+ }
+ ]
+ }
+ ]
+ });
+
+ graph = model.rows[0].panels[0];
+
+ }));
+
+ it('should have title', function() {
+ expect(model.title).to.be('No Title');
+ });
+
+ it('should move time and filtering list', function() {
+ expect(model.time.from).to.be('now-1d');
+ expect(model.templating.list[0]).to.be(1);
+ });
+
+ it('graphite panel should change name too graph', function() {
+ expect(graph.type).to.be('graph');
+ });
+
+ it('update legend setting', function() {
+ expect(graph.legend.show).to.be(true);
+ });
+
+ it('update grid options', function() {
+ expect(graph.grid.leftMin).to.be(1);
+ expect(graph.grid.leftMax).to.be(10);
+ });
+
+ it('dashboard schema version should be set to latest', function() {
+ expect(model.version).to.be(2);
+ });
+
+ });
+
+
+});
diff --git a/src/test/test-main.js b/src/test/test-main.js
index 1d3ac1b57c5..79eb4db1165 100644
--- a/src/test/test-main.js
+++ b/src/test/test-main.js
@@ -124,6 +124,7 @@ require([
'specs/gfunc-specs',
'specs/filterSrv-specs',
'specs/kbn-format-specs',
+ 'specs/dashboardModel-specs',
'specs/influxSeries-specs'
], function () {
window.__karma__.start();