mirror of
https://github.com/nasa/openmct.git
synced 2025-02-20 17:33:23 +00:00
[UI] Progress indicator for pending operations - Refactoring for code clarity
This commit is contained in:
parent
e1c6c76612
commit
793ed7ebe6
@ -94,41 +94,42 @@ define(
|
||||
CopyAction.prototype.perform = function() {
|
||||
var self = this;
|
||||
|
||||
return AbstractComposeAction.prototype.perform.call(this)
|
||||
.then(
|
||||
function success(){
|
||||
self.notification.dismiss();
|
||||
self.notificationService.info("Copying complete.");
|
||||
},
|
||||
function error(errorDetails){
|
||||
var errorMessage = {
|
||||
title: "Error copying objects.",
|
||||
severity: "error",
|
||||
hint: errorDetails.message,
|
||||
minimized: true, // want the notification to be minimized initially (don't show banner)
|
||||
options: [{
|
||||
label: "OK",
|
||||
callback: function() {
|
||||
self.dialogService.dismiss();
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
self.dialogService.dismiss();
|
||||
if (self.notification) {
|
||||
self.notification.dismiss(); // Clear the progress notification
|
||||
function success(){
|
||||
self.notification.dismiss();
|
||||
self.notificationService.info("Copying complete.");
|
||||
}
|
||||
|
||||
function error(errorDetails){
|
||||
var errorMessage = {
|
||||
title: "Error copying objects.",
|
||||
severity: "error",
|
||||
hint: errorDetails.message,
|
||||
minimized: true, // want the notification to be minimized initially (don't show banner)
|
||||
options: [{
|
||||
label: "OK",
|
||||
callback: function() {
|
||||
self.dialogService.dismiss();
|
||||
}
|
||||
self.$log.error("Error copying objects. ", errorDetails);
|
||||
//Show a minimized notification of error for posterity
|
||||
self.notificationService.notify(errorMessage);
|
||||
//Display a blocking message
|
||||
self.dialogService.showBlockingMessage(errorMessage);
|
||||
|
||||
},
|
||||
function notification(details){
|
||||
self.progress(details.phase, details.totalObjects, details.processed);
|
||||
}
|
||||
);
|
||||
}]
|
||||
};
|
||||
|
||||
self.dialogService.dismiss();
|
||||
if (self.notification) {
|
||||
self.notification.dismiss(); // Clear the progress notification
|
||||
}
|
||||
self.$log.error("Error copying objects. ", errorDetails);
|
||||
//Show a minimized notification of error for posterity
|
||||
self.notificationService.notify(errorMessage);
|
||||
//Display a blocking message
|
||||
self.dialogService.showBlockingMessage(errorMessage);
|
||||
|
||||
}
|
||||
function notification(details){
|
||||
self.progress(details.phase, details.totalObjects, details.processed);
|
||||
}
|
||||
|
||||
return AbstractComposeAction.prototype.perform.call(this)
|
||||
.then(success, error, notification);
|
||||
};
|
||||
return CopyAction;
|
||||
}
|
||||
|
@ -27,6 +27,17 @@ define(
|
||||
function (uuid) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* This class encapsulates the process of copying a domain object
|
||||
* and all of its children.
|
||||
*
|
||||
* @param domainObject The object to copy
|
||||
* @param parent The new location of the cloned object tree
|
||||
* @param persistenceService
|
||||
* @param $q
|
||||
* @param now
|
||||
* @constructor
|
||||
*/
|
||||
function CopyTask (domainObject, parent, persistenceService, $q, now){
|
||||
this.domainObject = domainObject;
|
||||
this.parent = parent;
|
||||
@ -35,6 +46,25 @@ define(
|
||||
this.persistenceService = persistenceService;
|
||||
this.persisted = 0;
|
||||
this.now = now;
|
||||
this.clones = [];
|
||||
}
|
||||
|
||||
function composeChild(child, parent) {
|
||||
//Once copied, associate each cloned
|
||||
// composee with its parent clone
|
||||
child.model.location = parent.id;
|
||||
parent.model.composition = parent.model.composition || [];
|
||||
return parent.model.composition.push(child.id);
|
||||
}
|
||||
|
||||
function cloneObjectModel(objectModel) {
|
||||
var clone = JSON.parse(JSON.stringify(objectModel));
|
||||
|
||||
delete clone.composition;
|
||||
delete clone.persisted;
|
||||
delete clone.modified;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,26 +73,24 @@ define(
|
||||
* result in automatic request batching by the browser.
|
||||
* @private
|
||||
*/
|
||||
CopyTask.prototype.persistObjects = function(objectClones) {
|
||||
CopyTask.prototype.persistObjects = function() {
|
||||
var self = this;
|
||||
|
||||
return this.$q.all(objectClones.map(function(clone){
|
||||
return this.$q.all(this.clones.map(function(clone){
|
||||
clone.model.persisted = self.now();
|
||||
return self.persistenceService.createObject(clone.persistenceSpace, clone.id, clone.model)
|
||||
.then(function(){
|
||||
return self.deferred.notify({phase: "copying", totalObjects: objectClones.length, processed: ++self.persisted});
|
||||
return self.deferred.notify({phase: "copying", totalObjects: self.clones.length, processed: ++self.persisted});
|
||||
});
|
||||
})).then(function(){
|
||||
return objectClones;
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Will add a list of clones to the specified parent's composition
|
||||
* @private
|
||||
*/
|
||||
CopyTask.prototype.addClonesToParent = function(clones) {
|
||||
var parentClone = clones[clones.length-1],
|
||||
CopyTask.prototype.addClonesToParent = function() {
|
||||
var parentClone = this.clones[this.clones.length-1],
|
||||
self = this;
|
||||
|
||||
if (!this.parent.hasCapability('composition')){
|
||||
@ -77,6 +105,61 @@ define(
|
||||
// Ensure the clone of the original domainObject is returned
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an array of objects composed by a parent, clone them, then
|
||||
* add them to the parent.
|
||||
* @private
|
||||
* @returns {*}
|
||||
*/
|
||||
CopyTask.prototype.copyComposees = function(composees, clonedParent, originalParent){
|
||||
var self = this;
|
||||
|
||||
return (composees || []).reduce(function(promise, composee){
|
||||
//If the composee is composed of other
|
||||
// objects, chain a promise..
|
||||
return promise.then(function(){
|
||||
// ...to recursively copy it (and its children)
|
||||
return self.copy(composee, originalParent).then(function(composee){
|
||||
composeChild(composee, clonedParent)
|
||||
});
|
||||
});}, self.$q.when(undefined)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A recursive function that will perform a bottom-up copy of
|
||||
* the object tree with originalObject at the root. Recurses to
|
||||
* the farthest leaf, then works its way back up again,
|
||||
* cloning objects, and composing them with their child clones
|
||||
* as it goes
|
||||
* @private
|
||||
* @param originalObject
|
||||
* @param originalParent
|
||||
* @returns {*}
|
||||
*/
|
||||
CopyTask.prototype.copy = function(originalObject, originalParent) {
|
||||
var self = this;
|
||||
|
||||
//Make a clone of the model of the object to be copied
|
||||
var modelClone = {
|
||||
id: uuid(),
|
||||
model: cloneObjectModel(originalObject.getModel()),
|
||||
persistenceSpace: originalParent.hasCapability('persistence') && originalParent.getCapability('persistence').getSpace()
|
||||
};
|
||||
|
||||
return this.$q.when(originalObject.useCapability('composition')).then(function(composees){
|
||||
self.deferred.notify({phase: "preparing"});
|
||||
//Duplicate the object's children, and their children, and
|
||||
// so on down to the leaf nodes of the tree.
|
||||
return self.copyComposees(composees, modelClone, originalObject).then(function (){
|
||||
//Add the clone to the list of clones that will
|
||||
//be returned by this function
|
||||
self.clones.push(modelClone);
|
||||
return modelClone;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Will build a graph of an object and all of its child objects in
|
||||
* memory
|
||||
@ -90,66 +173,18 @@ define(
|
||||
* references to their own children.
|
||||
*/
|
||||
CopyTask.prototype.buildCopyPlan = function() {
|
||||
var clones = [],
|
||||
$q = this.$q,
|
||||
self = this;
|
||||
var self = this;
|
||||
|
||||
function makeClone(object) {
|
||||
return JSON.parse(JSON.stringify(object));
|
||||
}
|
||||
|
||||
/**
|
||||
* A recursive function that will perform a bottom-up copy of
|
||||
* the object tree with originalObject at the root. Recurses to
|
||||
* the farthest leaf, then works its way back up again,
|
||||
* cloning objects, and composing them with their child clones
|
||||
* as it goes
|
||||
* @param originalObject
|
||||
* @param originalParent
|
||||
* @returns {*}
|
||||
*/
|
||||
function copy(originalObject, originalParent) {
|
||||
//Make a clone of the model of the object to be copied
|
||||
var modelClone = {
|
||||
id: uuid(),
|
||||
model: makeClone(originalObject.getModel()),
|
||||
persistenceSpace: originalParent.hasCapability('persistence') && originalParent.getCapability('persistence').getSpace()
|
||||
};
|
||||
|
||||
delete modelClone.model.composition;
|
||||
delete modelClone.model.persisted;
|
||||
delete modelClone.model.modified;
|
||||
|
||||
return $q.when(originalObject.useCapability('composition')).then(function(composees){
|
||||
self.deferred.notify({phase: "preparing"});
|
||||
return (composees || []).reduce(function(promise, composee){
|
||||
//If the object is composed of other
|
||||
// objects, chain a promise..
|
||||
return promise.then(function(){
|
||||
// ...to recursively copy it (and its children)
|
||||
return copy(composee, originalObject).then(function(composeeClone){
|
||||
//Once copied, associate each cloned
|
||||
// composee with its parent clone
|
||||
composeeClone.model.location = modelClone.id;
|
||||
modelClone.model.composition = modelClone.model.composition || [];
|
||||
return modelClone.model.composition.push(composeeClone.id);
|
||||
});
|
||||
});}, $q.when(undefined)
|
||||
).then(function (){
|
||||
//Add the clone to the list of clones that will
|
||||
//be returned by this function
|
||||
clones.push(modelClone);
|
||||
return modelClone;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return copy(self.domainObject, self.parent).then(function(domainObjectClone){
|
||||
return this.copy(self.domainObject, self.parent).then(function(domainObjectClone){
|
||||
domainObjectClone.model.location = self.parent.getId();
|
||||
return clones;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute the copy task with the objects provided in the constructor.
|
||||
* @returns {promise} Which will resolve with a clone of the object
|
||||
* once complete.
|
||||
*/
|
||||
CopyTask.prototype.perform = function(){
|
||||
var persistObjects = this.persistObjects.bind(this),
|
||||
addClonesToParent = this.addClonesToParent.bind(this);
|
||||
|
@ -342,7 +342,7 @@ define(
|
||||
expect(copyFinished.mostRecentCall.args[0].model.modified).toBeUndefined();
|
||||
expect(copyFinished.mostRecentCall.args[0].model.persisted).toBe(mockNow.now());
|
||||
});
|
||||
|
||||
|
||||
it ("correctly locates cloned objects", function() {
|
||||
expect(mockPersistenceService.createObject.calls[0].args[2].location).toEqual(mockPersistenceService.createObject.calls[1].args[1]);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user