216 lines
8.7 KiB
JavaScript

/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
['../../../browse/src/creation/CreateWizard'],
function (CreateWizard) {
'use strict';
/**
* The "Save" action; the action triggered by clicking Save from
* Edit Mode. Exits the editing user interface and invokes object
* capabilities to persist the changes that have been made.
* @constructor
* @implements {Action}
* @memberof platform/commonUI/edit
*/
function SaveAction($q, $location, $injector, urlService, navigationService, policyService, dialogService, creationService, context) {
this.domainObject = (context || {}).domainObject;
this.$location = $location;
this.injectObjectService = function(){
this.objectService = $injector.get("objectService");
};
this.urlService = urlService;
this.navigationService = navigationService;
this.policyService = policyService;
this.dialogService = dialogService;
this.creationService = creationService;
this.$q = $q;
}
SaveAction.prototype.getObjectService = function(){
// Lazily acquire object service (avoids cyclical dependency)
if (!this.objectService) {
this.injectObjectService();
}
return this.objectService;
};
/**
* Save changes and conclude editing.
*
* @returns {Promise} a promise that will be fulfilled when
* cancellation has completed
* @memberof platform/commonUI/edit.SaveAction#
*/
SaveAction.prototype.perform = function () {
var domainObject = this.domainObject,
$location = this.$location,
urlService = this.urlService,
self = this;
function resolveWith(object){
return function() {
return object;
};
}
function doWizardSave(parent) {
var context = domainObject.getCapability("context"),
wizard = new CreateWizard(domainObject.useCapability('type'), parent, self.policyService, domainObject.getModel());
function mergeObjects(fromObject, toObject){
Object.keys(fromObject).forEach(function(key) {
toObject[key] = fromObject[key];
});
}
// Create and persist the new object, based on user
// input.
function buildObjectFromInput(formValue) {
var parent = wizard.getLocation(formValue),
formModel = wizard.createModel(formValue);
formModel.location = parent.getId();
//Replace domain object model with model collected
// from user form.
domainObject.useCapability("mutation", function(){
//Replace object model with the model from the form
return formModel;
});
return domainObject;
}
function getAllComposees(domainObject){
return domainObject.useCapability('composition');
}
function addComposeesToObject(object){
return function(composees){
return self.$q.all(composees.map(function (composee) {
return object.getCapability('composition').add(composee);
})).then(resolveWith(object));
};
}
/**
* Add the composees of the 'virtual' object to the
* persisted object
* @param object
* @returns {*}
*/
function composeNewObject(object){
if (self.$q.when(object.hasCapability('composition') && domainObject.hasCapability('composition'))) {
return getAllComposees(domainObject)
.then(addComposeesToObject(object));
}
}
return self.dialogService
.getUserInput(wizard.getFormStructure(), wizard.getInitialFormValue())
.then(buildObjectFromInput);
}
function persistObject(object){
return ((object.hasCapability('editor') && object.getCapability('editor').save(true)) ||
object.getCapability('persistence').persist())
.then(resolveWith(object));
}
function fetchObject(objectId){
return self.getObjectService().getObjects([objectId]).then(function(objects){
return objects[objectId];
});
}
function getParent(object){
return fetchObject(object.getModel().location);
}
function locateObjectInParent(parent){
parent.getCapability('composition').add(domainObject.getId());
return parent;
}
function doNothing() {
// Create cancelled, do nothing
return false;
}
// Invoke any save behavior introduced by the editor capability;
// this is introduced by EditableDomainObject which is
// used to insulate underlying objects from changes made
// during editing.
function doSave() {
//WARNING: HACK
//This is a new 'virtual object' that has not been persisted
// yet.
if (!domainObject.getModel().persisted){
return getParent(domainObject)
.then(doWizardSave)
.then(persistObject)
.then(getParent)//Parent may have changed based
// on user selection
.then(locateObjectInParent)
.then(persistObject)
.then(function(){
return fetchObject(domainObject.getId());
})
.catch(doNothing)
} else {
return domainObject.getCapability("editor").save()
.then(resolveWith(domainObject.getOriginalObject()));
}
}
// Discard the current root view (which will be the editing
// UI, which will have been pushed atop the Browse UI.)
function returnToBrowse(object) {
if (object) {
self.navigationService.setNavigation(object);
}
return object;
}
//return doSave().then(returnToBrowse);
return doSave().then(returnToBrowse);
};
/**
* Check if this action is applicable in a given context.
* This will ensure that a domain object is present in the context,
* and that this domain object is in Edit mode.
* @returns true if applicable
*/
SaveAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject;
return domainObject !== undefined &&
domainObject.hasCapability("editor");
};
return SaveAction;
}
);