diff --git a/src/app/controllers/dashLoader.js b/src/app/controllers/dashLoader.js
index 49bc25793d6..17a162b6935 100644
--- a/src/app/controllers/dashLoader.js
+++ b/src/app/controllers/dashLoader.js
@@ -38,7 +38,9 @@ function (angular, _, moment, config) {
};
$scope.saveForSharing = function() {
- $scope.db.saveDashboardTemp($scope.dashboard)
+ var clone = angular.copy($scope.dashboard);
+ clone.temp = true;
+ $scope.db.saveDashboard(clone)
.then(function(result) {
$scope.share = { url: result.url, title: result.title };
@@ -71,7 +73,8 @@ function (angular, _, moment, config) {
$scope.saveDashboard = function() {
if (!this.isAdmin()) { return false; }
- $scope.db.saveDashboard($scope.dashboard, $scope.dashboard.title)
+ var clone = angular.copy($scope.dashboard);
+ $scope.db.saveDashboard(clone)
.then(function(result) {
alertSrv.set('Dashboard Saved', 'Dashboard has been saved as "' + result.title + '"','success', 5000);
diff --git a/src/app/controllers/row.js b/src/app/controllers/row.js
index 279116a92e6..0f020ff345d 100644
--- a/src/app/controllers/row.js
+++ b/src/app/controllers/row.js
@@ -130,28 +130,9 @@ function (angular, app, _) {
}
};
- /** @scratch /panels/0
- * [[panels]]
- * = Panels
- *
- * [partintro]
- * --
- * *grafana* dashboards are made up of blocks called +panels+. Panels are organized into rows
- * and can serve many purposes, though most are designed to provide the results of a query or
- * multiple queries as a visualization. Other panels may show collections of documents or
- * allow you to insert instructions for your users.
- *
- * Panels can be configured easily via the grafana web interface. For more advanced usage, such
- * as templated or scripted dashboards, documentation of panel properties is available in this
- * section. You may find settings here which are not exposed via the web interface.
- *
- * Each panel type has its own properties, hover there are several that are shared.
- *
- */
-
$scope.reset_panel = function(type) {
var
- defaultSpan = 4,
+ defaultSpan = 12,
_as = 12-$scope.rowSpan($scope.row);
$scope.panel = {
@@ -192,4 +173,4 @@ function (angular, app, _) {
});
-});
\ No newline at end of file
+});
diff --git a/src/app/dashboards/default.json b/src/app/dashboards/default.json
index ccc96c1cb73..a31d4985779 100644
--- a/src/app/dashboards/default.json
+++ b/src/app/dashboards/default.json
@@ -134,10 +134,5 @@
"now": true
}
],
- "loader": {
- "save_temp": true,
- "save_temp_ttl_enable": true,
- "save_temp_ttl": "30d"
- },
"refresh": false
}
diff --git a/src/app/dashboards/empty.json b/src/app/dashboards/empty.json
index 041790a41cd..25a375e5821 100644
--- a/src/app/dashboards/empty.json
+++ b/src/app/dashboards/empty.json
@@ -65,10 +65,5 @@
"now": true
}
],
- "loader": {
- "save_temp": true,
- "save_temp_ttl_enable": true,
- "save_temp_ttl": "30d",
- },
"refresh": false
}
diff --git a/src/app/partials/dashLoader.html b/src/app/partials/dashLoader.html
index c22137de64a..5ff4e1598c9 100644
--- a/src/app/partials/dashLoader.html
+++ b/src/app/partials/dashLoader.html
@@ -47,7 +47,7 @@
Export dashboard
-
+
Share temp copy
diff --git a/src/app/partials/dasheditor.html b/src/app/partials/dasheditor.html
index 227ff223d66..1131a31c50b 100644
--- a/src/app/partials/dasheditor.html
+++ b/src/app/partials/dasheditor.html
@@ -2,7 +2,7 @@
Dashboard settings
-
+
@@ -79,18 +79,6 @@
{{pulldown.type}}
-
diff --git a/src/app/routes/dashboard-from-db.js b/src/app/routes/dashboard-from-db.js
index 39e3e2581b0..a2202ef518d 100644
--- a/src/app/routes/dashboard-from-db.js
+++ b/src/app/routes/dashboard-from-db.js
@@ -25,7 +25,9 @@ function (angular) {
module.controller('DashFromDBProvider', function($scope, $rootScope, datasourceSrv, $routeParams, alertSrv) {
var db = datasourceSrv.getGrafanaDB();
- db.getDashboard($routeParams.id)
+ var isTemp = window.location.href.indexOf('dashboard/temp') !== -1;
+
+ db.getDashboard($routeParams.id, isTemp)
.then(function(dashboard) {
$scope.emitAppEvent('setup-dashboard', dashboard);
}).then(null, function(error) {
diff --git a/src/app/services/dashboard/dashboardModel.js b/src/app/services/dashboard/dashboardModel.js
index 58ebe6d6199..d069a4b43b2 100644
--- a/src/app/services/dashboard/dashboardModel.js
+++ b/src/app/services/dashboard/dashboardModel.js
@@ -26,13 +26,6 @@ function (angular, $, kbn, _) {
this.pulldowns = data.pulldowns || [];
this.nav = data.nav || [];
this.services = data.services || {};
- this.loader = data.loader || {};
-
- _.defaults(this.loader, {
- save_temp: true,
- save_temp_ttl_enable: true,
- save_temp_ttl: '30d',
- });
if (this.nav.length === 0) {
this.nav.push({ type: 'timepicker' });
diff --git a/src/app/services/elasticsearch/es-datasource.js b/src/app/services/elasticsearch/es-datasource.js
index 577e143cd14..a7506966abe 100644
--- a/src/app/services/elasticsearch/es-datasource.js
+++ b/src/app/services/elasticsearch/es-datasource.js
@@ -18,12 +18,16 @@ function (angular, _, $, config, kbn, moment) {
this.basicAuth = datasource.basicAuth;
this.url = datasource.url;
this.name = datasource.name;
- this.supportAnnotations = true;
- this.supportMetrics = false;
this.index = datasource.index;
this.grafanaDB = datasource.grafanaDB;
- this.annotationEditorSrc = 'app/partials/elasticsearch/annotation_editor.html';
this.searchMaxResults = config.search.max_results || 20;
+
+ this.saveTemp = _.isUndefined(datasource.save_temp) ? true : datasource.save_temp;
+ this.saveTempTTL = _.isUndefined(datasource.save_temp_ttl) ? '30d' : datasource.save_temp_ttl;
+
+ this.annotationEditorSrc = 'app/partials/elasticsearch/annotation_editor.html';
+ this.supportAnnotations = true;
+ this.supportMetrics = false;
}
ElasticDatasource.prototype._request = function(method, url, index, data) {
@@ -103,11 +107,10 @@ function (angular, _, $, config, kbn, moment) {
});
};
- ElasticDatasource.prototype.getDashboard = function(id) {
+ ElasticDatasource.prototype.getDashboard = function(id, isTemp) {
var url = '/dashboard/' + id;
- // hack to check if it is a temp dashboard
- if (window.location.href.indexOf('dashboard/temp') > 0) {
+ if (isTemp) {
url = '/temp/' + id;
}
@@ -127,44 +130,40 @@ function (angular, _, $, config, kbn, moment) {
});
};
- ElasticDatasource.prototype.saveDashboard = function(dashboard, title) {
- var dashboardClone = angular.copy(dashboard);
- title = dashboardClone.title = title ? title : dashboard.title;
+ ElasticDatasource.prototype.saveDashboard = function(dashboard) {
+ var title = dashboard.title;
+ var temp = dashboard.temp;
+ if (temp) { delete dashboard.temp; }
var data = {
user: 'guest',
group: 'guest',
title: title,
- tags: dashboardClone.tags,
- dashboard: angular.toJson(dashboardClone)
- };
-
- return this._request('PUT', '/dashboard/' + encodeURIComponent(title), this.index, data)
- .then(function() {
- return { title: title, url: '/dashboard/db/' + title };
- }, function(err) {
- throw 'Failed to save to elasticsearch ' + err.data;
- });
- };
-
- ElasticDatasource.prototype.saveDashboardTemp = function(dashboard) {
- var data = {
- user: 'guest',
- group: 'guest',
- title: dashboard.title,
tags: dashboard.tags,
dashboard: angular.toJson(dashboard)
};
- var ttl = dashboard.loader.save_temp_ttl;
+ if (temp) {
+ return this._saveTempDashboard(data);
+ }
+ else {
+ return this._request('PUT', '/dashboard/' + encodeURIComponent(title), this.index, data)
+ .then(function() {
+ return { title: title, url: '/dashboard/db/' + title };
+ }, function(err) {
+ throw 'Failed to save to elasticsearch ' + err.data;
+ });
+ }
+ };
- return this._request('POST', '/temp/?ttl=' + ttl, this.index, data)
+ ElasticDatasource.prototype._saveTempDashboard = function(data) {
+ return this._request('POST', '/temp/?ttl=' + this.saveTempTTL, this.index, data)
.then(function(result) {
var baseUrl = window.location.href.replace(window.location.hash,'');
var url = baseUrl + "#dashboard/temp/" + result.data._id;
- return { title: dashboard.title, url: url };
+ return { title: data.title, url: url };
}, function(err) {
throw "Failed to save to temp dashboard to elasticsearch " + err.data;
diff --git a/src/app/services/influxdb/influxdbDatasource.js b/src/app/services/influxdb/influxdbDatasource.js
index a778ed3fbfd..9a744977967 100644
--- a/src/app/services/influxdb/influxdbDatasource.js
+++ b/src/app/services/influxdb/influxdbDatasource.js
@@ -22,6 +22,9 @@ function (angular, _, kbn, InfluxSeries) {
interpolate : /\[\[([\s\S]+?)\]\]/g,
};
+ this.saveTemp = _.isUndefined(datasource.save_temp) ? true : datasource.save_temp;
+ this.saveTempTTL = _.isUndefined(datasource.save_temp_ttl) ? '30d' : datasource.save_temp_ttl;
+
this.grafanaDB = datasource.grafanaDB;
this.supportAnnotations = true;
this.supportMetrics = true;
@@ -231,31 +234,47 @@ function (angular, _, kbn, InfluxSeries) {
return deferred.promise;
};
- InfluxDatasource.prototype.saveDashboard = function(dashboard, title) {
- var dashboardClone = angular.copy(dashboard);
- var tags = dashboardClone.tags.join(',');
- title = dashboardClone.title = title ? title : dashboard.title;
+ InfluxDatasource.prototype.saveDashboard = function(dashboard) {
+ var tags = dashboard.tags.join(',');
+ var title = dashboard.title;
+ var temp = dashboard.temp;
+ if (temp) { delete dashboard.temp; }
var data = [{
name: 'grafana.dashboard_' + btoa(title),
columns: ['time', 'sequence_number', 'title', 'tags', 'dashboard'],
- points: [[1, 1, title, tags, angular.toJson(dashboardClone)]]
+ points: [[1000000000000, 1, title, tags, angular.toJson(dashboard)]]
}];
+ if (temp) {
+ return this._saveDashboardTemp(data, title);
+ }
+ else {
+ return this._influxRequest('POST', '/series', data).then(function() {
+ return { title: title, url: '/dashboard/db/' + title };
+ }, function(err) {
+ throw 'Failed to save dashboard to InfluxDB: ' + err.data;
+ });
+ }
+ };
+
+ InfluxDatasource.prototype._saveDashboardTemp = function(data, title) {
+ data[0].name = 'grafana.dashboard_temp_' + btoa(title);
+ data[0].columns.push('expires');
+ data[0].points[0].push(this._getTempDashboardExpiresDate());
+
return this._influxRequest('POST', '/series', data).then(function() {
- return { title: title, url: '/dashboard/db/' + title };
+ var baseUrl = window.location.href.replace(window.location.hash,'');
+ var url = baseUrl + "#dashboard/temp/" + title;
+ return { title: title, url: url };
}, function(err) {
- throw 'Failed to save dashboard to InfluxDB: ' + err.data;
+ throw 'Failed to save shared dashboard to InfluxDB: ' + err.data;
});
};
- InfluxDatasource.prototype.saveDashboardTemp = function(dashboard, title) {
- var dashboardClone = angular.copy(dashboard);
- var tags = dashboardClone.tags.join(',');
- title = dashboardClone.title = title ? title : dashboard.title;
- var ttl = dashboard.loader.save_temp_ttl;
- var ttlLength = ttl.substring(0, ttl.length-1);
- var ttlTerm = ttl.substring(ttl.length-1, ttl.length).toLowerCase();
+ InfluxDatasource.prototype._getTempDashboardExpiresDate = function() {
+ var ttlLength = this.saveTempTTL.substring(0, this.saveTempTTL.length - 1);
+ var ttlTerm = this.saveTempTTL.substring(this.saveTempTTL.length - 1, this.saveTempTTL.length).toLowerCase();
var expires = Date.now();
switch(ttlTerm) {
case "m":
@@ -270,39 +289,24 @@ function (angular, _, kbn, InfluxSeries) {
default:
throw "Unknown ttl duration format";
}
-
- var data = [{
- name: 'grafana.dashboard_' + btoa(title),
- columns: ['time', 'sequence_number', 'title', 'tags', 'dashboard', 'expires'],
- points: [[1, 1, title, tags, angular.toJson(dashboardClone), expires]]
- }];
-
- return this._influxRequest('POST', '/series', data).then(function() {
- var baseUrl = window.location.href.replace(window.location.hash,'');
- var url = baseUrl + "#dashboard/temp/" + title;
- return { title: title, url: url };
- }, function(err) {
- throw 'Failed to save shared dashboard to InfluxDB: ' + err.data;
- });
+ return expires;
};
- InfluxDatasource.prototype.getDashboard = function(id) {
+
+ InfluxDatasource.prototype.getDashboard = function(id, isTemp) {
var queryString = 'select dashboard from "grafana.dashboard_' + btoa(id) + '"';
- // hack to check if it is a temp dashboard
- if (window.location.href.indexOf('dashboard/temp') > 0) {
- var isTemp = true;
- queryString = 'select dashboard, expires from "grafana.dashboard_' + btoa(id) + '"';
+
+ if (isTemp) {
+ queryString = 'select dashboard from "grafana.dashboard_temp_' + btoa(id) + '"';
}
+
return this._seriesQuery(queryString).then(function(results) {
if (!results || !results.length) {
throw "Dashboard not found";
}
- var expiresCol = _.indexOf(results[0].columns, 'expires');
- var expiresTime = results[0].points[0][expiresCol];
- if (Date.now() > expiresTime && isTemp) {
- throw "Dashboard has expired";
- }
+
var dashCol = _.indexOf(results[0].columns, 'dashboard');
var dashJson = results[0].points[0][dashCol];
+
return angular.fromJson(dashJson);
}, function(err) {
return "Could not load dashboard, " + err.data;
diff --git a/src/test/mocks/dashboard-mock.js b/src/test/mocks/dashboard-mock.js
index 97858ceac23..2ee9c659337 100644
--- a/src/test/mocks/dashboard-mock.js
+++ b/src/test/mocks/dashboard-mock.js
@@ -24,20 +24,6 @@ define([],
list: []
}
},
- loader: {
- save_gist: false,
- save_elasticsearch: true,
- save_local: true,
- save_default: true,
- save_temp: true,
- save_temp_ttl_enable: true,
- save_temp_ttl: '30d',
- load_gist: false,
- load_elasticsearch: true,
- load_elasticsearch_size: 20,
- load_local: false,
- hide: false
- },
refresh: true
};
}