mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
Merge branch 'unsaved_changes_warning' (Closes #324)
This commit is contained in:
commit
035b5163fb
@ -5,6 +5,8 @@
|
||||
- Increased resolution for graphite datapoints (maxDataPoints), now equal to panel pixel width. (Closes #5)
|
||||
- Improvement to influxdb query editor, can now add where clause and alias (Issue #331, thanks @mavimo)
|
||||
- New config setting for graphite datasource to control if json render request is POST or GET (Issue #345)
|
||||
- Unsaved changes warning feature (Issue #324)
|
||||
|
||||
|
||||
# 1.5.3 (2014-04-17)
|
||||
- Add support for async scripted dashboards (Issue #274)
|
||||
|
@ -25,6 +25,7 @@ function (_, crypto) {
|
||||
grafana_index : 'grafana-dash',
|
||||
elasticsearch_all_disabled : false,
|
||||
timezoneOffset : null,
|
||||
unsaved_changes_warning : true
|
||||
};
|
||||
|
||||
// This initializes a new hash on purpose, to avoid adding parameters to
|
||||
|
@ -30,7 +30,8 @@ function (angular, $, config, _) {
|
||||
var module = angular.module('kibana.controllers');
|
||||
|
||||
module.controller('DashCtrl', function(
|
||||
$scope, $rootScope, $route, ejsResource, dashboard, alertSrv, panelMove, keyboardManager, grafanaVersion) {
|
||||
$scope, $rootScope, ejsResource, dashboard,
|
||||
alertSrv, panelMove, keyboardManager, grafanaVersion) {
|
||||
|
||||
$scope.requiredElasticSearchVersion = ">=0.90.3";
|
||||
|
||||
|
@ -65,23 +65,20 @@ function (angular, _, moment) {
|
||||
};
|
||||
|
||||
$scope.elasticsearch_save = function(type,ttl) {
|
||||
dashboard.elasticsearch_save(
|
||||
type,
|
||||
($scope.elasticsearch.title || dashboard.current.title),
|
||||
($scope.loader.save_temp_ttl_enable ? ttl : false)
|
||||
).then(function(result) {
|
||||
if(_.isUndefined(result._id)) {
|
||||
alertSrv.set('Save failed','Dashboard could not be saved to Elasticsearch','error',5000);
|
||||
return;
|
||||
}
|
||||
dashboard.elasticsearch_save(type, dashboard.current.title, ttl)
|
||||
.then(function(result) {
|
||||
if(_.isUndefined(result._id)) {
|
||||
alertSrv.set('Save failed','Dashboard could not be saved to Elasticsearch','error',5000);
|
||||
return;
|
||||
}
|
||||
|
||||
alertSrv.set('Dashboard Saved', 'This dashboard has been saved to Elasticsearch as "' + result._id + '"','success', 5000);
|
||||
if(type === 'temp') {
|
||||
$scope.share = dashboard.share_link(dashboard.current.title,'temp',result._id);
|
||||
}
|
||||
alertSrv.set('Dashboard Saved', 'Dashboard has been saved to Elasticsearch as "' + result._id + '"','success', 5000);
|
||||
if(type === 'temp') {
|
||||
$scope.share = dashboard.share_link(dashboard.current.title,'temp',result._id);
|
||||
}
|
||||
|
||||
$rootScope.$emit('dashboard-saved');
|
||||
});
|
||||
$rootScope.$emit('dashboard-saved');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.elasticsearch_delete = function(id) {
|
||||
|
16
src/app/partials/unsaved-changes.html
Normal file
16
src/app/partials/unsaved-changes.html
Normal file
@ -0,0 +1,16 @@
|
||||
<div class="modal-header">
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<h3 class="text-center"><i class="icon-warning-sign"></i> Unsaved changes</h3>
|
||||
<div class="row-fluid">
|
||||
<span class="span3"></span>
|
||||
<button type="button" class="btn btn-success span2" ng-click="dismiss()">Cancel</button>
|
||||
<button type="button" class="btn btn-success span2" ng-click="save();dismiss();">Save</button>
|
||||
<button type="button" class="btn btn-warning span2" ng-click="ignore();dismiss();">Ignore</button>
|
||||
<span class="span3"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
@ -8,5 +8,6 @@ define([
|
||||
'./keyboardManager',
|
||||
'./annotationsSrv',
|
||||
'./playlistSrv',
|
||||
'./unsavedChangesSrv',
|
||||
],
|
||||
function () {});
|
@ -63,6 +63,7 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
|
||||
$rootScope.$on('$routeChangeSuccess',function(){
|
||||
// Clear the current dashboard to prevent reloading
|
||||
self.current = {};
|
||||
self.original = null;
|
||||
self.indices = [];
|
||||
route();
|
||||
});
|
||||
@ -157,16 +158,8 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
|
||||
// Set the current dashboard
|
||||
self.current = angular.copy(dashboard);
|
||||
|
||||
// Delay this until we're sure that querySrv and filterSrv are ready
|
||||
$timeout(function() {
|
||||
// Ok, now that we've setup the current dashboard, we can inject our services
|
||||
filterSrv = $injector.get('filterSrv');
|
||||
filterSrv.init();
|
||||
|
||||
},0).then(function() {
|
||||
// Call refresh to calculate the indices and notify the panels that we're ready to roll
|
||||
self.refresh();
|
||||
});
|
||||
filterSrv = $injector.get('filterSrv');
|
||||
filterSrv.init();
|
||||
|
||||
if(dashboard.refresh) {
|
||||
self.set_interval(dashboard.refresh);
|
||||
@ -181,6 +174,10 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
|
||||
|
||||
$rootScope.$emit('dashboard-loaded');
|
||||
|
||||
$timeout(function() {
|
||||
self.original = angular.copy(self.current);
|
||||
}, 500);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -393,6 +390,7 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
|
||||
if(type === 'dashboard') {
|
||||
$location.path('/dashboard/elasticsearch/'+title);
|
||||
}
|
||||
self.original = angular.copy(self.current);
|
||||
return result;
|
||||
},
|
||||
// Failure
|
||||
|
102
src/app/services/unsavedChangesSrv.js
Normal file
102
src/app/services/unsavedChangesSrv.js
Normal file
@ -0,0 +1,102 @@
|
||||
define([
|
||||
'angular',
|
||||
'underscore',
|
||||
'config',
|
||||
],
|
||||
function (angular, _, config) {
|
||||
'use strict';
|
||||
|
||||
if (!config.unsaved_changes_warning) {
|
||||
return;
|
||||
}
|
||||
|
||||
var module = angular.module('kibana.services');
|
||||
|
||||
module.service('unsavedChangesSrv', function($rootScope, $modal, dashboard, $q, $location, $timeout) {
|
||||
var self = this;
|
||||
var modalScope = $rootScope.$new();
|
||||
|
||||
window.onbeforeunload = function () {
|
||||
if (self.has_unsaved_changes()) {
|
||||
return "There are unsaved changes to this dashboard";
|
||||
}
|
||||
};
|
||||
|
||||
this.init = function() {
|
||||
$rootScope.$on("$locationChangeStart", function(event, next) {
|
||||
if (self.has_unsaved_changes()) {
|
||||
event.preventDefault();
|
||||
self.next = next;
|
||||
self.open_modal();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.open_modal = function () {
|
||||
var confirmModal = $modal({
|
||||
template: './app/partials/unsaved-changes.html',
|
||||
persist: true,
|
||||
show: false,
|
||||
scope: modalScope,
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$q.when(confirmModal).then(function(modalEl) {
|
||||
modalEl.modal('show');
|
||||
});
|
||||
};
|
||||
|
||||
this.has_unsaved_changes = function () {
|
||||
if (!dashboard.original) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var current = angular.copy(dashboard.current);
|
||||
var original = dashboard.original;
|
||||
|
||||
// ignore timespan changes
|
||||
current.services.filter.time = original.services.filter.time = {};
|
||||
current.refresh = original.refresh;
|
||||
|
||||
var currentTimepicker = _.findWhere(current.nav, { type: 'timepicker' });
|
||||
var originalTimepicker = _.findWhere(original.nav, { type: 'timepicker' });
|
||||
|
||||
if (currentTimepicker && originalTimepicker) {
|
||||
currentTimepicker.now = originalTimepicker.now;
|
||||
}
|
||||
|
||||
var currentJson = angular.toJson(current);
|
||||
var originalJson = angular.toJson(original);
|
||||
|
||||
if (currentJson !== originalJson) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.goto_next = function () {
|
||||
var baseLen = $location.absUrl().length - $location.url().length;
|
||||
var nextUrl = self.next.substring(baseLen);
|
||||
$location.url(nextUrl);
|
||||
};
|
||||
|
||||
modalScope.ignore = function() {
|
||||
dashboard.original = null;
|
||||
self.goto_next();
|
||||
};
|
||||
|
||||
modalScope.save = function() {
|
||||
var unregister = $rootScope.$on('dashboard-saved', function() {
|
||||
self.goto_next();
|
||||
});
|
||||
|
||||
$timeout(unregister, 2000);
|
||||
|
||||
$rootScope.$emit('save-dashboard');
|
||||
};
|
||||
|
||||
}).run(function(unsavedChangesSrv) {
|
||||
unsavedChangesSrv.init();
|
||||
});
|
||||
});
|
@ -57,8 +57,17 @@ function (Settings) {
|
||||
|
||||
timezoneOffset: null,
|
||||
|
||||
/**
|
||||
* Elasticsearch index for storing dashboards
|
||||
*
|
||||
*/
|
||||
grafana_index: "grafana-dash",
|
||||
|
||||
/**
|
||||
* set to false to disable unsaved changes warning
|
||||
*/
|
||||
unsaved_changes_warning: true,
|
||||
|
||||
panel_names: [
|
||||
'text',
|
||||
'graphite'
|
||||
|
Loading…
Reference in New Issue
Block a user