mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			142 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| define([
 | |
|   'angular',
 | |
|   'lodash',
 | |
|   'config',
 | |
| ],
 | |
| function(angular, _, config) {
 | |
|   'use strict';
 | |
| 
 | |
|   if (!config.unsaved_changes_warning) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   var module = angular.module('grafana.services');
 | |
| 
 | |
|   module.service('unsavedChangesSrv', function($rootScope, $modal, $q, $location, $timeout) {
 | |
| 
 | |
|     var self = this;
 | |
|     var modalScope = $rootScope.$new();
 | |
| 
 | |
|     $rootScope.$on("dashboard-loaded", function(event, newDashboard) {
 | |
|       // wait for different services to patch the dashboard (missing properties)
 | |
|       $timeout(function() {
 | |
|         self.original = angular.copy(newDashboard);
 | |
|         self.current = newDashboard;
 | |
|       }, 1200);
 | |
|     });
 | |
| 
 | |
|     $rootScope.$on("dashboard-saved", function(event, savedDashboard) {
 | |
|       self.original = angular.copy(savedDashboard);
 | |
|       self.current = savedDashboard;
 | |
|       self.orignalPath = $location.path();
 | |
|     });
 | |
| 
 | |
|     $rootScope.$on("$routeChangeSuccess", function() {
 | |
|       self.original = null;
 | |
|       self.originalPath = $location.path();
 | |
|     });
 | |
| 
 | |
|     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.originalPath === $location.path()) {
 | |
|           return;
 | |
|         }
 | |
| 
 | |
|         if (self.has_unsaved_changes()) {
 | |
|           event.preventDefault();
 | |
|           self.next = next;
 | |
| 
 | |
|           $timeout(self.open_modal);
 | |
|         }
 | |
|       });
 | |
|     };
 | |
| 
 | |
|     this.open_modal = function() {
 | |
|       var confirmModal = $modal({
 | |
|         template: './app/partials/unsaved-changes.html',
 | |
|         modalClass: 'confirm-modal',
 | |
|         persist: true,
 | |
|         show: false,
 | |
|         scope: modalScope,
 | |
|         keyboard: false
 | |
|       });
 | |
| 
 | |
|       $q.when(confirmModal).then(function(modalEl) {
 | |
|         modalEl.modal('show');
 | |
|       });
 | |
|     };
 | |
| 
 | |
|     this.has_unsaved_changes = function() {
 | |
|       if (!self.original) {
 | |
|         return false;
 | |
|       }
 | |
| 
 | |
|       var current = angular.copy(self.current);
 | |
|       var original = self.original;
 | |
| 
 | |
|       // ignore timespan changes
 | |
|       current.time = original.time = {};
 | |
|       current.refresh = original.refresh;
 | |
|       // ignore version
 | |
|       current.version = original.version;
 | |
| 
 | |
|       // ignore template variable values
 | |
|       _.each(current.templating.list, function(value, index) {
 | |
|         value.current = null;
 | |
|         value.options = null;
 | |
| 
 | |
|         if (original.templating.list.length > index) {
 | |
|           original.templating.list[index].current = null;
 | |
|           original.templating.list[index].options = null;
 | |
|         }
 | |
|       });
 | |
| 
 | |
|       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() {
 | |
|       self.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();
 | |
|   });
 | |
| });
 |