[#138] alert-unsaved-changes directive

This commit is contained in:
Amir Nissim 2014-03-23 15:20:14 +02:00
parent e996b4fa22
commit 5ffd2615e7
4 changed files with 51 additions and 45 deletions

View File

@ -1,51 +1,25 @@
(function() { (function() {
'use strict'; 'use strict';
function QueryEditCtrl($controller, $scope, $window, $route, $location, growl, Query, Visualization) { function QueryEditCtrl($controller, $scope, $route, $location, growl, Query, Visualization) {
var pristineHash = "";
var leavingPageText = "You will lose your changes if you leave";
var isNewQuery = !$route.current.locals.query.id; var isNewQuery = !$route.current.locals.query.id;
// controller inheritance // controller inheritance
$controller('QueryViewCtrl', {$scope: $scope}); $controller('QueryViewCtrl', {$scope: $scope});
$scope.sourceMode = true; $scope.sourceMode = true;
$scope.isDirty = undefined; $scope.isDirty = false;
$scope.canEdit = currentUser.canEdit($scope.query); $scope.canEdit = currentUser.canEdit($scope.query);
$scope.newVisualization = undefined; $scope.newVisualization = undefined;
$window.onbeforeunload = function() {
if ($scope.canEdit && $scope.isDirty) {
return leavingPageText;
}
}
$scope.$on('$locationChangeStart', function(event, next, current) {
if (next.split("#")[0] == current.split("#")[0]) {
return;
}
if (!$scope.canEdit) {
return;
}
if ($scope.isDirty && !confirm(leavingPageText + "\n\nAre you sure you want to leave this page?")) {
event.preventDefault();
} else {
Mousetrap.unbind("meta+s");
}
});
$scope.saveQuery = function(duplicate, oldId) { $scope.saveQuery = function(duplicate, oldId) {
if (!oldId) { if (!oldId) {
oldId = $scope.query.id; oldId = $scope.query.id;
} }
delete $scope.query.latest_query_data; delete $scope.query.latest_query_data;
$scope.query.$save(function(q) { $scope.query.$save(function(savedQuery) {
pristineHash = q.getHash();
$scope.isDirty = false; $scope.isDirty = false;
if (duplicate) { if (duplicate) {
@ -54,15 +28,14 @@
growl.addSuccessMessage("Query saved"); growl.addSuccessMessage("Query saved");
} }
if (oldId != q.id) { if (oldId != savedQuery.id) {
$location.url($location.url().replace(oldId, q.id)).replace(); $location.url($location.url().replace(oldId, savedQuery.id)).replace();
} }
}, function(httpResponse) { }, function(httpResponse) {
growl.addErrorMessage("Query could not be saved"); growl.addErrorMessage("Query could not be saved");
}); });
}; };
$scope.deleteVisualization = function($e, vis) { $scope.deleteVisualization = function($e, vis) {
$e.preventDefault(); $e.preventDefault();
if (confirm('Are you sure you want to delete ' + vis.name + ' ?')) { if (confirm('Are you sure you want to delete ' + vis.name + ' ?')) {
@ -78,16 +51,11 @@
} }
}; };
$scope.$watch('query.query', function(current, prev) {
$scope.$watch(function() { $scope.isDirty = (current !== prev);
return $scope.query.getHash();
}, function(newHash) {
$scope.isDirty = (newHash !== pristineHash);
}); });
if (isNewQuery) { if (isNewQuery) {
// $scope.lockButton(false);
// save new query when creating a visualization // save new query when creating a visualization
var unbind = $scope.$watch('selectedTab == "add"', function(newPanel) { var unbind = $scope.$watch('selectedTab == "add"', function(newPanel) {
if (newPanel && $route.current.params.queryId == undefined) { if (newPanel && $route.current.params.queryId == undefined) {
@ -100,7 +68,7 @@
}; };
angular.module('redash.controllers').controller('QueryEditCtrl', [ angular.module('redash.controllers').controller('QueryEditCtrl', [
'$controller', '$scope', '$window', '$route', '$location', 'growl', 'Query', '$controller', '$scope', '$route', '$location', 'growl', 'Query',
'Visualization', QueryEditCtrl 'Visualization', QueryEditCtrl
]); ]);
})(); })();

View File

@ -3,11 +3,47 @@
var directives = angular.module('redash.directives', []); var directives = angular.module('redash.directives', []);
directives.directive('alertUnsavedChanges', ['$window', function($window) {
return {
restrict: 'E',
replace: true,
scope: {
'isDirty': '='
},
link: function($scope) {
var
unloadMessage = "You will lose your changes if you leave",
confirmMessage = unloadMessage + "\n\nAre you sure you want to leave this page?",
// store original handler (if any)
_onbeforeunload = $window.onbeforeunload;
$window.onbeforeunload = function() {
return $scope.isDirty ? unloadMessage : null;
}
$scope.$on('$locationChangeStart', function(event, next, current) {
if (next.split("#")[0] == current.split("#")[0]) {
return;
}
if ($scope.isDirty && !confirm(confirmMessage)) {
event.preventDefault();
}
});
$scope.$on('$destroy', function() {
$window.onbeforeunload = _onbeforeunload;
});
}
}
}]);
directives.directive('keyboardShortcut', function() { directives.directive('keyboardShortcut', function() {
return { return {
restrict: 'E', restrict: 'E',
replace: true, replace: true,
template: '<span>foo</span>',
scope: { scope: {
key: '@', key: '@',
action: '=' action: '='
@ -17,6 +53,10 @@
e.preventDefault(); e.preventDefault();
$scope.action(); $scope.action();
}); });
$scope.$on('$destroy', function() {
Mousetrap.unbind($scope.key);
});
} }
} }
}); });

View File

@ -321,10 +321,6 @@
return queryResult; return queryResult;
}; };
Query.prototype.getHash = function() {
return this.query;
};
return Query; return Query;
}; };

View File

@ -1,5 +1,7 @@
<div class="container"> <div class="container">
<alert-unsaved-changes ng-if="canEdit" is-dirty="isDirty"></alert-unsaved-changes>
<keyboard-shortcut ng-if="canEdit" key="meta+s" action="saveQuery"></keyboard-shortcut> <keyboard-shortcut ng-if="canEdit" key="meta+s" action="saveQuery"></keyboard-shortcut>
<div class="row"> <div class="row">