Unsaved changes: Do not show for snapshots, scripted and file based dashboards, Fixes #1707

This commit is contained in:
Torkel Ödegaard
2015-04-06 11:22:35 +02:00
parent ea800dd838
commit 538ec7c0a0
11 changed files with 244 additions and 206 deletions

View File

@@ -38,7 +38,7 @@ function (angular, $, config) {
$rootScope.performance.panelsInitialized = 0;
$rootScope.performance.panelsRendered = 0;
var dashboard = dashboardSrv.create(data.model);
var dashboard = dashboardSrv.create(data.model, data.meta);
// init services
timeSrv.init(dashboard);
@@ -47,11 +47,12 @@ function (angular, $, config) {
// the rest of the dashboard can load
templateValuesSrv.init(dashboard).then(function() {
$scope.dashboard = dashboard;
$scope.dashboardMeta = dashboard.meta;
$scope.dashboardViewState = dashboardViewStateSrv.create($scope);
$scope.initDashboardMeta(data.meta, $scope.dashboard);
dashboardKeybindings.shortcuts($scope);
$scope.updateTopNavPartial();
$scope.updateSubmenuVisibility();
$scope.setWindowTitleAndTheme();
@@ -59,28 +60,10 @@ function (angular, $, config) {
});
};
$scope.initDashboardMeta = function(meta) {
meta.canShare = true;
meta.canSave = true;
meta.canEdit = true;
meta.canStar = true;
if (contextSrv.hasRole('Viewer')) {
meta.canSave = false;
}
if (meta.isHome) {
meta.canShare = false;
meta.canStar = false;
meta.canSave = false;
meta.canEdit = false;
}
if (meta.isSnapshot) {
$scope.updateTopNavPartial = function() {
if ($scope.dashboard.meta.isSnapshot) {
$scope.topNavPartial = 'app/features/dashboard/partials/snapshotTopNav.html';
}
$scope.dashboardMeta = meta;
};
$scope.updateSubmenuVisibility = function() {

View File

@@ -52,7 +52,7 @@ function (angular, _) {
};
$scope.saveDashboard = function(options) {
var clone = angular.copy($scope.dashboard);
var clone = $scope.dashboard.getSaveModelClone();
backendSrv.saveDashboard(clone, options).then(function(data) {
$scope.dashboard.version = data.version;
@@ -118,7 +118,7 @@ function (angular, _) {
$scope.saveDashboardAs = function() {
var newScope = $rootScope.$new();
newScope.clone = angular.copy($scope.dashboard);
newScope.clone = $scope.dashboard.getSaveModelClone();
$scope.appEvent('show-modal', {
src: './app/features/dashboard/partials/saveDashboardAs.html',
@@ -127,7 +127,8 @@ function (angular, _) {
};
$scope.exportDashboard = function() {
var blob = new Blob([angular.toJson($scope.dashboard, true)], { type: "application/json;charset=utf-8" });
var clone = $scope.dashboard.getSaveModelClone();
var blob = new Blob([angular.toJson(clone, true)], { type: "application/json;charset=utf-8" });
window.saveAs(blob, $scope.dashboard.title + '-' + new Date().getTime());
};
@@ -144,7 +145,8 @@ function (angular, _) {
};
$scope.editJson = function() {
$scope.appEvent('show-json-editor', { object: $scope.dashboard });
var clone = $scope.dashboard.getSaveModelClone();
$scope.appEvent('show-json-editor', { object: clone });
};
$scope.stopPlaylist = function() {

View File

@@ -10,10 +10,9 @@ function (angular, $, kbn, _, moment) {
var module = angular.module('grafana.services');
module.factory('dashboardSrv', function() {
function DashboardModel (data) {
module.factory('dashboardSrv', function(contextSrv) {
function DashboardModel (data, meta) {
if (!data) {
data = {};
}
@@ -46,10 +45,43 @@ function (angular, $, kbn, _, moment) {
}
this._updateSchema(data);
this._initMeta(meta);
}
var p = DashboardModel.prototype;
p._initMeta = function(meta) {
meta = meta || {};
meta.canShare = true;
meta.canSave = true;
meta.canEdit = true;
meta.canStar = true;
if (contextSrv.hasRole('Viewer')) {
meta.canSave = false;
}
if (meta.isSnapshot) {
meta.canSave = false;
}
if (meta.isHome) {
meta.canShare = false;
meta.canStar = false;
meta.canSave = false;
meta.canEdit = false;
}
this.meta = meta;
};
// cleans meta data and other non peristent state
p.getSaveModelClone = function() {
var copy = angular.copy(this);
delete copy.meta;
return copy;
};
p._ensureListExist = function (data) {
if (!data) { data = {}; }
if (!data.list) { data.list = []; }
@@ -276,8 +308,8 @@ function (angular, $, kbn, _, moment) {
};
return {
create: function(dashboard) {
return new DashboardModel(dashboard);
create: function(dashboard, meta) {
return new DashboardModel(dashboard, meta);
}
};

View File

@@ -48,7 +48,7 @@ function (angular, _) {
};
$scope.saveSnapshot = function(external) {
var dash = angular.copy($scope.dashboard);
var dash = $scope.dashboard.getSaveModelClone();
$scope.scrubDashboard(dash);
var cmdData = {

View File

@@ -12,7 +12,7 @@ function(angular, _, config) {
var module = angular.module('grafana.services');
module.service('unsavedChangesSrv', function($rootScope, $modal, $q, $location, $timeout, contextSrv) {
module.service('unsavedChangesSrv', function($rootScope, $modal, $q, $location, $timeout) {
var self = this;
var modalScope = $rootScope.$new();
@@ -36,8 +36,15 @@ function(angular, _, config) {
self.originalPath = $location.path();
});
this.ignoreChanges = function() {
if (!self.current) { return true; }
var meta = self.current.meta;
return !meta.canSave || meta.fromScript || meta.fromFile;
};
window.onbeforeunload = function() {
if (contextSrv.hasRole('Viewer')) { return true; }
if (self.ignoreChanges()) { return; }
if (self.has_unsaved_changes()) {
return "There are unsaved changes to this dashboard";
}
@@ -47,7 +54,7 @@ function(angular, _, config) {
$rootScope.$on("$locationChangeStart", function(event, next) {
// check if we should look for changes
if (self.originalPath === $location.path()) { return true; }
if (contextSrv.hasRole('Viewer')) { return true; }
if (self.ignoreChanges()) { return true; }
if (self.has_unsaved_changes()) {
event.preventDefault();

View File

@@ -40,8 +40,8 @@ function (angular, $) {
});
};
$scope.initPanelScope = function(dashboard) {
$scope.dashboard = dashboardSrv.create(dashboard.model);
$scope.initPanelScope = function(dashData) {
$scope.dashboard = dashboardSrv.create(dashData.model, dashData.meta);
$scope.row = {
height: ($(window).height() - 10) + 'px',