|
@@ -1,90 +1,68 @@
|
|
|
define([
|
|
define([
|
|
|
'angular',
|
|
'angular',
|
|
|
'lodash',
|
|
'lodash',
|
|
|
- 'config',
|
|
|
|
|
],
|
|
],
|
|
|
-function(angular, _, config) {
|
|
|
|
|
|
|
+function(angular, _) {
|
|
|
'use strict';
|
|
'use strict';
|
|
|
|
|
|
|
|
- if (!config.unsaved_changes_warning) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
var module = angular.module('grafana.services');
|
|
var module = angular.module('grafana.services');
|
|
|
|
|
|
|
|
- module.service('unsavedChangesSrv', function($rootScope, $modal, $q, $location, $timeout, contextSrv) {
|
|
|
|
|
|
|
+ module.service('unsavedChangesSrv', function($modal, $q, $location, $timeout, contextSrv, $window) {
|
|
|
|
|
|
|
|
- var self = this;
|
|
|
|
|
- var modalScope = $rootScope.$new();
|
|
|
|
|
|
|
+ function Tracker(dashboard, scope) {
|
|
|
|
|
+ var self = this;
|
|
|
|
|
|
|
|
- $rootScope.$on("dashboard-loaded", function(event, newDashboard) {
|
|
|
|
|
- // wait for different services to patch the dashboard (missing properties)
|
|
|
|
|
- $timeout(function() {
|
|
|
|
|
- self.original = newDashboard.getSaveModelClone();
|
|
|
|
|
- self.current = newDashboard;
|
|
|
|
|
- }, 1200);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- $rootScope.$on("dashboard-saved", function(event, savedDashboard) {
|
|
|
|
|
- self.original = savedDashboard.getSaveModelClone();
|
|
|
|
|
- self.current = savedDashboard;
|
|
|
|
|
- self.orignalPath = $location.path();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- $rootScope.$on("$routeChangeSuccess", function() {
|
|
|
|
|
- self.original = null;
|
|
|
|
|
- self.originalPath = $location.path();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- this.ignoreChanges = function() {
|
|
|
|
|
- if (!contextSrv.isEditor) { return true; }
|
|
|
|
|
- if (!self.current || !self.current.meta) { return true; }
|
|
|
|
|
|
|
+ this.original = dashboard.getSaveModelClone();
|
|
|
|
|
+ this.current = dashboard;
|
|
|
|
|
+ this.originalPath = $location.path();
|
|
|
|
|
+ this.scope = scope;
|
|
|
|
|
|
|
|
- var meta = self.current.meta;
|
|
|
|
|
- return !meta.canSave || meta.fromScript || meta.fromFile;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ // register events
|
|
|
|
|
+ scope.onAppEvent('dashboard-saved', function() {
|
|
|
|
|
+ self.original = self.current.getSaveModelClone();
|
|
|
|
|
+ self.originalPath = $location.path();
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- window.onbeforeunload = function() {
|
|
|
|
|
- if (self.ignoreChanges()) { return; }
|
|
|
|
|
- if (self.has_unsaved_changes()) {
|
|
|
|
|
- return "There are unsaved changes to this dashboard";
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ $window.onbeforeunload = function() {
|
|
|
|
|
+ if (self.ignoreChanges()) { return; }
|
|
|
|
|
+ if (self.hasChanges()) {
|
|
|
|
|
+ return "There are unsaved changes to this dashboard";
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- this.init = function() {
|
|
|
|
|
- $rootScope.$on("$locationChangeStart", function(event, next) {
|
|
|
|
|
|
|
+ scope.$on("$locationChangeStart", function(event, next) {
|
|
|
// check if we should look for changes
|
|
// check if we should look for changes
|
|
|
if (self.originalPath === $location.path()) { return true; }
|
|
if (self.originalPath === $location.path()) { return true; }
|
|
|
if (self.ignoreChanges()) { return true; }
|
|
if (self.ignoreChanges()) { return true; }
|
|
|
|
|
|
|
|
- if (self.has_unsaved_changes()) {
|
|
|
|
|
|
|
+ if (self.hasChanges()) {
|
|
|
event.preventDefault();
|
|
event.preventDefault();
|
|
|
self.next = next;
|
|
self.next = next;
|
|
|
|
|
|
|
|
- $timeout(self.open_modal);
|
|
|
|
|
|
|
+ $timeout(function() {
|
|
|
|
|
+ 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
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ var p = Tracker.prototype;
|
|
|
|
|
|
|
|
- $q.when(confirmModal).then(function(modalEl) {
|
|
|
|
|
- modalEl.modal('show');
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ // for some dashboards and users
|
|
|
|
|
+ // changes should be ignored
|
|
|
|
|
+ p.ignoreChanges = function() {
|
|
|
|
|
+ if (!this.original) { return false; }
|
|
|
|
|
+ if (!contextSrv.isEditor) { return true; }
|
|
|
|
|
+ if (!this.current || !this.current.meta) { return true; }
|
|
|
|
|
+
|
|
|
|
|
+ var meta = this.current.meta;
|
|
|
|
|
+ return !meta.canSave || meta.fromScript || meta.fromFile;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- this.cleanDashboardFromRepeatedPanelsAndRows = function(dash) {
|
|
|
|
|
|
|
+ // remove stuff that should not count in diff
|
|
|
|
|
+ p.cleanDashboardFromIgnoredChanges = function(dash) {
|
|
|
dash.rows = _.filter(dash.rows, function(row) {
|
|
dash.rows = _.filter(dash.rows, function(row) {
|
|
|
if (row.repeatRowId) {
|
|
if (row.repeatRowId) {
|
|
|
- console.log('filtering out row');
|
|
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -101,13 +79,9 @@ function(angular, _, config) {
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- this.has_unsaved_changes = function() {
|
|
|
|
|
- if (!self.original) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- var current = self.current.getSaveModelClone();
|
|
|
|
|
- var original = self.original;
|
|
|
|
|
|
|
+ p.hasChanges = function() {
|
|
|
|
|
+ var current = this.current.getSaveModelClone();
|
|
|
|
|
+ var original = this.original;
|
|
|
|
|
|
|
|
// ignore timespan changes
|
|
// ignore timespan changes
|
|
|
current.time = original.time = {};
|
|
current.time = original.time = {};
|
|
@@ -126,8 +100,8 @@ function(angular, _, config) {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- this.cleanDashboardFromRepeatedPanelsAndRows(current);
|
|
|
|
|
- this.cleanDashboardFromRepeatedPanelsAndRows(original);
|
|
|
|
|
|
|
+ this.cleanDashboardFromIgnoredChanges(current);
|
|
|
|
|
+ this.cleanDashboardFromIgnoredChanges(original);
|
|
|
|
|
|
|
|
// ignore some panel and row stuff
|
|
// ignore some panel and row stuff
|
|
|
current.forEachPanel(function(panel, panelIndex, row, rowIndex) {
|
|
current.forEachPanel(function(panel, panelIndex, row, rowIndex) {
|
|
@@ -165,28 +139,43 @@ function(angular, _, config) {
|
|
|
return false;
|
|
return false;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- this.goto_next = function() {
|
|
|
|
|
- var baseLen = $location.absUrl().length - $location.url().length;
|
|
|
|
|
- var nextUrl = self.next.substring(baseLen);
|
|
|
|
|
- $location.url(nextUrl);
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ p.open_modal = function() {
|
|
|
|
|
+ var tracker = this;
|
|
|
|
|
|
|
|
- modalScope.ignore = function() {
|
|
|
|
|
- self.original = null;
|
|
|
|
|
- self.goto_next();
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ var modalScope = this.scope.$new();
|
|
|
|
|
+ modalScope.ignore = function() {
|
|
|
|
|
+ tracker.original = null;
|
|
|
|
|
+ tracker.goto_next();
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ modalScope.save = function() {
|
|
|
|
|
+ tracker.scope.$emit('save-dashboard');
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- modalScope.save = function() {
|
|
|
|
|
- var unregister = $rootScope.$on('dashboard-saved', function() {
|
|
|
|
|
- self.goto_next();
|
|
|
|
|
|
|
+ var confirmModal = $modal({
|
|
|
|
|
+ template: './app/partials/unsaved-changes.html',
|
|
|
|
|
+ modalClass: 'confirm-modal',
|
|
|
|
|
+ persist: false,
|
|
|
|
|
+ show: false,
|
|
|
|
|
+ scope: modalScope,
|
|
|
|
|
+ keyboard: false
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- $timeout(unregister, 2000);
|
|
|
|
|
|
|
+ $q.when(confirmModal).then(function(modalEl) {
|
|
|
|
|
+ modalEl.modal('show');
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- $rootScope.$emit('save-dashboard');
|
|
|
|
|
|
|
+ p.goto_next = function() {
|
|
|
|
|
+ var baseLen = $location.absUrl().length - $location.url().length;
|
|
|
|
|
+ var nextUrl = this.next.substring(baseLen);
|
|
|
|
|
+ $location.url(nextUrl);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- }).run(function(unsavedChangesSrv) {
|
|
|
|
|
- unsavedChangesSrv.init();
|
|
|
|
|
|
|
+ this.Tracker = Tracker;
|
|
|
|
|
+ this.init = function(dashboard, scope) {
|
|
|
|
|
+ // wait for different services to patch the dashboard (missing properties)
|
|
|
|
|
+ $timeout(function() { new Tracker(dashboard, scope); }, 1200);
|
|
|
|
|
+ };
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|