mirror of
https://github.com/nasa/openmct.git
synced 2025-01-31 08:25:31 +00:00
[Edit] Add mct-before-unload directive
Add directive for exposing expressions which should be evaluated for the browser's onbeforeunload event, to prevent user-initiated navigation from causing a loss of unsaved changes. WTD-1035.
This commit is contained in:
parent
d86e27504f
commit
783d2f332b
@ -23,6 +23,13 @@
|
||||
"depends": [ "$scope" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctBeforeUnload",
|
||||
"implementation": "directives/MCTBeforeUnload.js",
|
||||
"depends": [ "$window" ]
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"key": "edit",
|
||||
|
@ -1,8 +1,9 @@
|
||||
<div content="jquery-wrapper"
|
||||
class="abs holder-all edit-mode"
|
||||
ng-controller="EditController">
|
||||
ng-controller="EditController as editMode"
|
||||
mct-before-unload="editMode.getUnloadWarning()">
|
||||
|
||||
<mct-representation key="'edit-object'" mct-object="navigatedObject">
|
||||
<mct-representation key="'edit-object'" mct-object="editMode.navigatedObject()">
|
||||
</mct-representation>
|
||||
|
||||
<mct-include key="'bottombar'"></mct-include>
|
||||
|
@ -88,6 +88,13 @@ define(
|
||||
*/
|
||||
cancel: function () {
|
||||
return resolvePromise(undefined);
|
||||
},
|
||||
/**
|
||||
* Check if there are any unsaved changes.
|
||||
* @returns {boolean} true if there are unsaved changes
|
||||
*/
|
||||
dirty: function () {
|
||||
return cache.dirty();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -15,10 +15,12 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function EditController($scope, navigationService) {
|
||||
var navigatedObject;
|
||||
|
||||
function setNavigation(domainObject) {
|
||||
// Wrap the domain object such that all mutation is
|
||||
// confined to edit mode (until Save)
|
||||
$scope.navigatedObject =
|
||||
navigatedObject =
|
||||
domainObject && new EditableDomainObject(domainObject);
|
||||
}
|
||||
|
||||
@ -27,6 +29,21 @@ define(
|
||||
$scope.$on("$destroy", function () {
|
||||
navigationService.removeListener(setNavigation);
|
||||
});
|
||||
|
||||
return {
|
||||
navigatedObject: function () {
|
||||
return navigatedObject;
|
||||
},
|
||||
getUnloadWarning: function () {
|
||||
var editorCapability = navigatedObject &&
|
||||
navigatedObject.getCapability("editor"),
|
||||
hasChanges = editorCapability && editorCapability.dirty();
|
||||
|
||||
return hasChanges ?
|
||||
"Unsaved changes will be lost if you leave this page." :
|
||||
undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return EditController;
|
||||
|
68
platform/commonUI/edit/src/directives/MCTBeforeUnload.js
Normal file
68
platform/commonUI/edit/src/directives/MCTBeforeUnload.js
Normal file
@ -0,0 +1,68 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Defines the `mct-before-unload` directive. The expression bound
|
||||
* to this attribute will be evaluated during page navigation events
|
||||
* and, if it returns a truthy value, will be used to populate a
|
||||
* prompt to the user to confirm this navigation.
|
||||
* @constructor
|
||||
* @param $window the window
|
||||
*/
|
||||
function MCTBeforeUnload($window) {
|
||||
var unloads = [],
|
||||
oldBeforeUnload = $window.onbeforeunload;
|
||||
|
||||
// Run all unload functions, returning the first returns truthily.
|
||||
function checkUnloads() {
|
||||
var result;
|
||||
unloads.forEach(function (unload) {
|
||||
result = result || unload();
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// Link function for an mct-before-unload directive usage
|
||||
function link(scope, element, attrs) {
|
||||
// Invoke the
|
||||
function unload() {
|
||||
return scope.$eval(attrs.mctBeforeUnload);
|
||||
}
|
||||
|
||||
// Stop using this unload expression
|
||||
function removeUnload() {
|
||||
unloads = unloads.filter(function (callback) {
|
||||
return callback !== unload;
|
||||
});
|
||||
if (unloads.length === 0) {
|
||||
$window.onbeforeunload = oldBeforeUnload;
|
||||
}
|
||||
}
|
||||
|
||||
// Include this instance of the directive's unload function
|
||||
unloads.push(unload);
|
||||
|
||||
// If this is the first active instance of this directive,
|
||||
// register as the window's beforeunload handler
|
||||
$window.onbeforeunload = checkUnloads;
|
||||
|
||||
// Remove it when the scope is destroyed
|
||||
scope.$on("$destroy", removeUnload);
|
||||
}
|
||||
|
||||
return {
|
||||
// Applicable as an attribute
|
||||
restrict: "A",
|
||||
// Link with the provided function
|
||||
link: link
|
||||
};
|
||||
}
|
||||
|
||||
return MCTBeforeUnload;
|
||||
|
||||
}
|
||||
);
|
@ -91,6 +91,13 @@ define(
|
||||
// Invoke its save behavior
|
||||
object.getCapability('editor').save();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Check if any objects have been marked dirty in this cache.
|
||||
* @returns {boolean} true if objects are dirty
|
||||
*/
|
||||
dirty: function () {
|
||||
return Object.keys(dirty).length > 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user