unsavedChangesSrv.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. define([
  2. 'angular',
  3. 'lodash',
  4. 'config',
  5. ],
  6. function(angular, _, config) {
  7. 'use strict';
  8. if (!config.unsaved_changes_warning) {
  9. return;
  10. }
  11. var module = angular.module('grafana.services');
  12. module.service('unsavedChangesSrv', function($rootScope, $modal, $q, $location, $timeout) {
  13. var self = this;
  14. var modalScope = $rootScope.$new();
  15. $rootScope.$on("dashboard-loaded", function(event, newDashboard) {
  16. // wait for different services to patch the dashboard (missing properties)
  17. $timeout(function() {
  18. self.original = angular.copy(newDashboard);
  19. self.current = newDashboard;
  20. }, 1200);
  21. });
  22. $rootScope.$on("dashboard-saved", function(event, savedDashboard) {
  23. self.original = angular.copy(savedDashboard);
  24. self.current = savedDashboard;
  25. self.orignalPath = $location.path();
  26. });
  27. $rootScope.$on("$routeChangeSuccess", function() {
  28. self.original = null;
  29. self.originalPath = $location.path();
  30. });
  31. window.onbeforeunload = function() {
  32. if (self.has_unsaved_changes()) {
  33. return "There are unsaved changes to this dashboard";
  34. }
  35. };
  36. this.init = function() {
  37. $rootScope.$on("$locationChangeStart", function(event, next) {
  38. if (self.originalPath === $location.path()) {
  39. console.log("skipping");
  40. return;
  41. }
  42. if (self.has_unsaved_changes()) {
  43. event.preventDefault();
  44. self.next = next;
  45. $timeout(self.open_modal);
  46. }
  47. });
  48. };
  49. this.open_modal = function() {
  50. var confirmModal = $modal({
  51. template: './app/partials/unsaved-changes.html',
  52. persist: true,
  53. show: false,
  54. scope: modalScope,
  55. keyboard: false
  56. });
  57. $q.when(confirmModal).then(function(modalEl) {
  58. modalEl.modal('show');
  59. });
  60. };
  61. this.has_unsaved_changes = function() {
  62. if (!self.original) {
  63. return false;
  64. }
  65. var current = angular.copy(self.current);
  66. var original = self.original;
  67. // ignore timespan changes
  68. current.time = original.time = {};
  69. current.refresh = original.refresh;
  70. var currentTimepicker = _.findWhere(current.nav, { type: 'timepicker' });
  71. var originalTimepicker = _.findWhere(original.nav, { type: 'timepicker' });
  72. if (currentTimepicker && originalTimepicker) {
  73. currentTimepicker.now = originalTimepicker.now;
  74. }
  75. var currentJson = angular.toJson(current);
  76. var originalJson = angular.toJson(original);
  77. if (currentJson !== originalJson) {
  78. return true;
  79. }
  80. return false;
  81. };
  82. this.goto_next = function() {
  83. var baseLen = $location.absUrl().length - $location.url().length;
  84. var nextUrl = self.next.substring(baseLen);
  85. $location.url(nextUrl);
  86. };
  87. modalScope.ignore = function() {
  88. self.original = null;
  89. self.goto_next();
  90. };
  91. modalScope.save = function() {
  92. var unregister = $rootScope.$on('dashboard-saved', function() {
  93. self.goto_next();
  94. });
  95. $timeout(unregister, 2000);
  96. $rootScope.$emit('save-dashboard');
  97. };
  98. }).run(function(unsavedChangesSrv) {
  99. unsavedChangesSrv.init();
  100. });
  101. });