mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 02:29:24 +00:00
Compare commits
6 Commits
refresh-op
...
open824
Author | SHA1 | Date | |
---|---|---|---|
23dbbf965c | |||
a72f193e97 | |||
18e0aadfc1 | |||
64b3580cf6 | |||
08684fa14a | |||
56a5a30f56 |
@ -25,11 +25,8 @@
|
||||
* Module defining CreateAction. Created by vwoeltje on 11/10/14.
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'./CreateWizard',
|
||||
'../../../edit/src/objects/EditableDomainObject'
|
||||
],
|
||||
function (CreateWizard, EditableDomainObject) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
@ -88,22 +85,19 @@ define(
|
||||
CreateAction.prototype.perform = function () {
|
||||
var newModel = this.type.getInitialModel(),
|
||||
parentObject = this.navigationService.getNavigation(),
|
||||
newObject,
|
||||
editableObject;
|
||||
newObject;
|
||||
|
||||
newModel.type = this.type.getKey();
|
||||
newObject = parentObject.useCapability('instantiation', newModel);
|
||||
editableObject = new EditableDomainObject(newObject, this.$q);
|
||||
editableObject.setOriginalObject(parentObject);
|
||||
editableObject.getCapability('status').set('editing', true);
|
||||
editableObject.useCapability('mutation', function(model){
|
||||
newObject.useCapability('mutation', function(model){
|
||||
model.location = parentObject.getId();
|
||||
});
|
||||
|
||||
if (countEditableViews(editableObject) > 0 && editableObject.hasCapability('composition')) {
|
||||
this.navigationService.setNavigation(editableObject);
|
||||
if (countEditableViews(newObject) > 0 && newObject.hasCapability('composition')) {
|
||||
this.navigationService.setNavigation(newObject);
|
||||
newObject.getCapability("action").perform("edit");
|
||||
} else {
|
||||
return editableObject.getCapability('action').perform('save');
|
||||
return newObject.getCapability('action').perform('save');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -40,6 +40,10 @@ define([
|
||||
"./src/policies/EditContextualActionPolicy",
|
||||
"./src/representers/EditRepresenter",
|
||||
"./src/representers/EditToolbarRepresenter",
|
||||
"./src/capabilities/EditorCapability",
|
||||
"./src/capabilities/TransactionDecorator",
|
||||
"./src/services/TransactionService",
|
||||
"./src/services/DirtyModelCache",
|
||||
"text!./res/templates/library.html",
|
||||
"text!./res/templates/edit-object.html",
|
||||
"text!./res/templates/edit-action-buttons.html",
|
||||
@ -65,6 +69,10 @@ define([
|
||||
EditContextualActionPolicy,
|
||||
EditRepresenter,
|
||||
EditToolbarRepresenter,
|
||||
EditorCapability,
|
||||
TransactionDecorator,
|
||||
TransactionService,
|
||||
DirtyModelCache,
|
||||
libraryTemplate,
|
||||
editObjectTemplate,
|
||||
editActionButtonsTemplate,
|
||||
@ -182,10 +190,7 @@ define([
|
||||
"implementation": CancelAction,
|
||||
"name": "Cancel",
|
||||
"description": "Discard changes made to these objects.",
|
||||
"depends": [
|
||||
"$injector",
|
||||
"navigationService"
|
||||
]
|
||||
"depends": []
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
@ -252,6 +257,35 @@ define([
|
||||
"template": topbarEditTemplate
|
||||
}
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"type": "decorator",
|
||||
"provides": "capabilityService",
|
||||
"implementation": TransactionDecorator,
|
||||
"depends": [
|
||||
"$q",
|
||||
"transactionService",
|
||||
"dirtyModelCache"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "provider",
|
||||
"provides": "transactionService",
|
||||
"implementation": TransactionService,
|
||||
"depends": [
|
||||
"$q",
|
||||
"dirtyModelCache"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "provider",
|
||||
"provides": "dirtyModelCache",
|
||||
"implementation": DirtyModelCache,
|
||||
"depends": [
|
||||
"topic"
|
||||
]
|
||||
}
|
||||
],
|
||||
"representers": [
|
||||
{
|
||||
"implementation": EditRepresenter,
|
||||
@ -263,7 +297,19 @@ define([
|
||||
{
|
||||
"implementation": EditToolbarRepresenter
|
||||
}
|
||||
]
|
||||
],
|
||||
"capabilities": [
|
||||
{
|
||||
"key": "editor",
|
||||
"name": "Editor Capability",
|
||||
"description": "Provides transactional editing capabilities",
|
||||
"implementation": EditorCapability,
|
||||
"depends": [
|
||||
"transactionService",
|
||||
"dirtyModelCache"
|
||||
]
|
||||
}
|
||||
],
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -33,10 +33,8 @@ define(
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {Action}
|
||||
*/
|
||||
function CancelAction($injector, navigationService, context) {
|
||||
function CancelAction(context) {
|
||||
this.domainObject = context.domainObject;
|
||||
this.navigationService = navigationService;
|
||||
this.objectService = $injector.get('objectService');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,30 +44,16 @@ define(
|
||||
* cancellation has completed
|
||||
*/
|
||||
CancelAction.prototype.perform = function () {
|
||||
var domainObject = this.domainObject,
|
||||
self = this;
|
||||
var domainObject = this.domainObject;
|
||||
|
||||
// Look up the object's "editor.completion" capability;
|
||||
// this is introduced by EditableDomainObject which is
|
||||
// used to insulate underlying objects from changes made
|
||||
// during editing.
|
||||
function getEditorCapability() {
|
||||
return domainObject.getCapability("editor");
|
||||
function returnToBrowse () {
|
||||
var parent;
|
||||
domainObject.getCapability("location").getOriginal().then(function (original) {
|
||||
parent = original.getCapability("context").getParent();
|
||||
parent.getCapability("action").perform("navigate");
|
||||
});
|
||||
}
|
||||
|
||||
// Invoke any save behavior introduced by the editor.completion
|
||||
// capability.
|
||||
function doCancel(editor) {
|
||||
return editor.cancel();
|
||||
}
|
||||
|
||||
//Discard current 'editable' object, and retrieve original
|
||||
// un-edited object.
|
||||
function returnToBrowse() {
|
||||
return self.navigationService.setNavigation(self.domainObject.getOriginalObject());
|
||||
}
|
||||
|
||||
return doCancel(getEditorCapability())
|
||||
return this.domainObject.getCapability("editor").cancel()
|
||||
.then(returnToBrowse);
|
||||
};
|
||||
|
||||
@ -82,7 +66,7 @@ define(
|
||||
CancelAction.appliesTo = function (context) {
|
||||
var domainObject = (context || {}).domainObject;
|
||||
return domainObject !== undefined &&
|
||||
domainObject.hasCapability("editor");
|
||||
domainObject.getCapability("status").get("editing");
|
||||
};
|
||||
|
||||
return CancelAction;
|
||||
|
@ -25,8 +25,8 @@
|
||||
* Module defining EditAction. Created by vwoeltje on 11/14/14.
|
||||
*/
|
||||
define(
|
||||
['../objects/EditableDomainObject'],
|
||||
function (EditableDomainObject) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
// A no-op action to return in the event that the action cannot
|
||||
@ -73,25 +73,12 @@ define(
|
||||
*/
|
||||
EditAction.prototype.perform = function () {
|
||||
var self = this;
|
||||
if (!this.domainObject.hasCapability("editor")) {
|
||||
//TODO: This is only necessary because the drop gesture is
|
||||
// wrapping the object itself, need to refactor this later.
|
||||
// All responsibility for switching into edit mode should be
|
||||
// in the edit action, and not duplicated in the gesture
|
||||
this.domainObject = new EditableDomainObject(this.domainObject, this.$q);
|
||||
}
|
||||
this.navigationService.setNavigation(this.domainObject);
|
||||
this.domainObject.getCapability('status').set('editing', true);
|
||||
|
||||
//Register a listener to automatically cancel this edit action
|
||||
//if the user navigates away from this object.
|
||||
function cancelEditing(navigatedTo){
|
||||
if (!navigatedTo || navigatedTo.getId() !== self.domainObject.getId()) {
|
||||
self.domainObject.getCapability('editor').cancel();
|
||||
self.navigationService.removeListener(cancelEditing);
|
||||
}
|
||||
function cancelEditing(){
|
||||
self.domainObject.getCapability('editor').cancel();
|
||||
self.navigationService.removeListener(cancelEditing);
|
||||
}
|
||||
this.navigationService.addListener(cancelEditing);
|
||||
this.domainObject.useCapability("editor");
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -115,15 +115,11 @@ define(
|
||||
return copyService.perform(domainObject, parent, allowClone);
|
||||
}
|
||||
|
||||
function cancelEditingAfterClone(clonedObject) {
|
||||
return domainObject.getCapability("editor").cancel()
|
||||
function saveEdit(clonedObject) {
|
||||
return domainObject.getCapability("editor").save()
|
||||
.then(resolveWith(clonedObject));
|
||||
}
|
||||
|
||||
// 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() {
|
||||
//This is a new 'virtual object' that has not been persisted
|
||||
// yet.
|
||||
@ -132,11 +128,10 @@ define(
|
||||
.then(doWizardSave)
|
||||
.then(getParent)
|
||||
.then(cloneIntoParent)
|
||||
.then(cancelEditingAfterClone)
|
||||
.then(saveEdit)
|
||||
.catch(resolveWith(false));
|
||||
} else {
|
||||
return domainObject.getCapability("editor").save()
|
||||
.then(resolveWith(domainObject.getOriginalObject()));
|
||||
return domainObject.getCapability("editor").save();
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +157,7 @@ define(
|
||||
SaveAction.appliesTo = function (context) {
|
||||
var domainObject = (context || {}).domainObject;
|
||||
return domainObject !== undefined &&
|
||||
domainObject.hasCapability("editor");
|
||||
domainObject.getCapability("status").get("editing");
|
||||
};
|
||||
|
||||
return SaveAction;
|
||||
|
@ -1,60 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
function () {
|
||||
'use strict';
|
||||
var DISALLOWED_ACTIONS = ["move", "copy", "link", "window", "follow"];
|
||||
/**
|
||||
* Editable Action Capability. Overrides the action capability
|
||||
* normally exhibited by a domain object and filters out certain
|
||||
* actions not applicable when an object is in edit mode.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {PersistenceCapability}
|
||||
*/
|
||||
function EditableActionCapability(
|
||||
actionCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
) {
|
||||
var action = Object.create(actionCapability);
|
||||
|
||||
action.getActions = function(domainObject) {
|
||||
return actionCapability.getActions(domainObject).filter(function(action){
|
||||
return DISALLOWED_ACTIONS.indexOf(action.getMetadata().key) === -1;
|
||||
});
|
||||
};
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
return EditableActionCapability;
|
||||
}
|
||||
);
|
@ -1,60 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
['./EditableLookupCapability'],
|
||||
function (EditableLookupCapability) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Wrapper for the "composition" capability;
|
||||
* ensures that any domain objects reachable in Edit mode
|
||||
* are also wrapped as EditableDomainObjects.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {CompositionCapability}
|
||||
*/
|
||||
return function EditableCompositionCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
) {
|
||||
// This is a "lookup" style capability (it looks up other
|
||||
// domain objects), but we do not want to return the same
|
||||
// specific value every time (composition may change)
|
||||
return new EditableLookupCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache,
|
||||
false // Not idempotent
|
||||
);
|
||||
};
|
||||
}
|
||||
);
|
@ -1,78 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
['./EditableLookupCapability'],
|
||||
function (EditableLookupCapability) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Wrapper for the "context" capability;
|
||||
* ensures that any domain objects reachable in Edit mode
|
||||
* are also wrapped as EditableDomainObjects.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {ContextCapability}
|
||||
*/
|
||||
return function EditableContextCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
) {
|
||||
// This is a "lookup" style capability (it looks up other
|
||||
// domain objects), and it should be idempotent
|
||||
var capability = new EditableLookupCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache,
|
||||
true // Idempotent
|
||||
),
|
||||
// Track the real root object for the Elements pane
|
||||
trueRoot = capability.getRoot();
|
||||
|
||||
// Provide access to the real root, for the Elements pane.
|
||||
capability.getTrueRoot = function () {
|
||||
return trueRoot;
|
||||
};
|
||||
|
||||
// Hide ancestry after the root of this subgraph
|
||||
if (cache.isRoot(domainObject)) {
|
||||
capability.getRoot = function () {
|
||||
return editableObject;
|
||||
};
|
||||
capability.getPath = function () {
|
||||
return [editableObject];
|
||||
};
|
||||
}
|
||||
|
||||
return capability;
|
||||
};
|
||||
}
|
||||
);
|
@ -1,60 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
['./EditableLookupCapability'],
|
||||
function (EditableLookupCapability) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Wrapper for the "instantiation" capability;
|
||||
* ensures that any domain objects instantiated in Edit mode
|
||||
* are also wrapped as EditableDomainObjects.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {CompositionCapability}
|
||||
*/
|
||||
return function EditableInstantiationCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
) {
|
||||
// This is a "lookup" style capability (it looks up other
|
||||
// domain objects), but we do not want to return the same
|
||||
// specific value every time (composition may change)
|
||||
return new EditableLookupCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache,
|
||||
false // Not idempotent
|
||||
);
|
||||
};
|
||||
}
|
||||
);
|
@ -1,125 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
[],
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Wrapper for both "context" and "composition" capabilities;
|
||||
* ensures that any domain objects reachable in Edit mode
|
||||
* are also wrapped as EditableDomainObjects.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
*/
|
||||
return function EditableLookupCapability(
|
||||
contextCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache,
|
||||
idempotent
|
||||
) {
|
||||
var capability = Object.create(contextCapability),
|
||||
method;
|
||||
|
||||
// Check for domain object interface. If something has these
|
||||
// three methods, we assume it's a domain object.
|
||||
function isDomainObject(obj) {
|
||||
return obj !== undefined &&
|
||||
typeof obj.getId === 'function' &&
|
||||
typeof obj.getModel === 'function' &&
|
||||
typeof obj.getCapability === 'function';
|
||||
}
|
||||
|
||||
// Check an object returned by the wrapped capability; if it
|
||||
// is a domain object, we want to make it editable and/or get
|
||||
// it from the cache of editable domain objects. This will
|
||||
// prevent changes made in edit mode from modifying the actual
|
||||
// underlying domain object.
|
||||
function makeEditableObject(obj) {
|
||||
return isDomainObject(obj) ?
|
||||
cache.getEditableObject(obj) :
|
||||
obj;
|
||||
}
|
||||
|
||||
// Wrap a returned value (see above); if it's an array, wrap
|
||||
// all elements.
|
||||
function makeEditable(returnValue) {
|
||||
return Array.isArray(returnValue) ?
|
||||
returnValue.map(makeEditableObject) :
|
||||
makeEditableObject(returnValue);
|
||||
}
|
||||
|
||||
// Wrap a returned value (see above); if it's a promise, wrap
|
||||
// the resolved value.
|
||||
function wrapResult(result) {
|
||||
return (result && result.then) ? // promise-like
|
||||
result.then(makeEditable) :
|
||||
makeEditable(result);
|
||||
}
|
||||
|
||||
// Return a wrapped version of a function, which ensures
|
||||
// all results are editable domain objects.
|
||||
function wrapFunction(fn) {
|
||||
return function () {
|
||||
return wrapResult(contextCapability[fn].apply(
|
||||
capability,
|
||||
arguments
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
// Wrap a method such that it only delegates once.
|
||||
function oneTimeFunction(fn) {
|
||||
return function () {
|
||||
var result = wrapFunction(fn).apply(this, arguments);
|
||||
capability[fn] = function () {
|
||||
return result;
|
||||
};
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// Wrap a method of this capability
|
||||
function wrapMethod(fn) {
|
||||
if (typeof capability[fn] === 'function') {
|
||||
capability[fn] =
|
||||
(idempotent ? oneTimeFunction : wrapFunction)(fn);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap all methods; return only editable domain objects.
|
||||
for (method in contextCapability) {
|
||||
wrapMethod(method);
|
||||
}
|
||||
|
||||
return capability;
|
||||
};
|
||||
}
|
||||
);
|
@ -1,68 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Editable Persistence Capability. Overrides the persistence capability
|
||||
* normally exhibited by a domain object to ensure that changes made
|
||||
* during edit mode are not immediately stored to the database or other
|
||||
* backing storage.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {PersistenceCapability}
|
||||
*/
|
||||
function EditablePersistenceCapability(
|
||||
persistenceCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
) {
|
||||
var persistence = Object.create(persistenceCapability);
|
||||
|
||||
// Simply trigger refresh of in-view objects; do not
|
||||
// write anything to database.
|
||||
persistence.persist = function () {
|
||||
return cache.markDirty(editableObject);
|
||||
};
|
||||
|
||||
// Delegate refresh to the original object; this avoids refreshing
|
||||
// the editable instance of the object, and ensures that refresh
|
||||
// correctly targets the "real" version of the object.
|
||||
persistence.refresh = function () {
|
||||
return domainObject.getCapability('persistence').refresh();
|
||||
};
|
||||
|
||||
return persistence;
|
||||
}
|
||||
|
||||
return EditablePersistenceCapability;
|
||||
}
|
||||
);
|
@ -1,60 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
['./EditableLookupCapability'],
|
||||
function (EditableLookupCapability) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Wrapper for the "relationship" capability;
|
||||
* ensures that any domain objects reachable in Edit mode
|
||||
* are also wrapped as EditableDomainObjects.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {RelationshipCapability}
|
||||
*/
|
||||
return function EditableRelationshipCapability(
|
||||
relationshipCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
) {
|
||||
// This is a "lookup" style capability (it looks up other
|
||||
// domain objects), but we do not want to return the same
|
||||
// specific value every time (composition may change)
|
||||
return new EditableLookupCapability(
|
||||
relationshipCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache,
|
||||
false // Not idempotent
|
||||
);
|
||||
};
|
||||
}
|
||||
);
|
@ -26,117 +26,61 @@ define(
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
/**
|
||||
* Implements "save" and "cancel" as capabilities of
|
||||
* the object. In editing mode, user is seeing/using
|
||||
* a copy of the object (an EditableDomainObject)
|
||||
* which is disconnected from persistence; the Save
|
||||
* and Cancel actions can use this capability to
|
||||
* propagate changes from edit mode to the underlying
|
||||
* actual persistable object.
|
||||
*
|
||||
* Meant specifically for use by EditableDomainObject and the
|
||||
* associated cache; the constructor signature is particular
|
||||
* to a pattern used there and may contain unused arguments.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
*/
|
||||
function EditorCapability(
|
||||
persistenceCapability,
|
||||
editableObject,
|
||||
domainObject,
|
||||
cache
|
||||
transactionService,
|
||||
dirtyModelCache,
|
||||
domainObject
|
||||
) {
|
||||
this.editableObject = editableObject;
|
||||
this.transactionService = transactionService;
|
||||
this.dirtyModelCache = dirtyModelCache;
|
||||
this.domainObject = domainObject;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
// Simulate Promise.resolve (or $q.when); the former
|
||||
// causes a delayed reaction from Angular (since it
|
||||
// does not trigger a digest) and the latter is not
|
||||
// readily accessible, since we're a few classes
|
||||
// removed from the layer which gets dependency
|
||||
// injection.
|
||||
function resolvePromise(value) {
|
||||
return (value && value.then) ? value : {
|
||||
then: function (callback) {
|
||||
return resolvePromise(callback(value));
|
||||
}
|
||||
};
|
||||
EditorCapability.prototype.edit = function () {
|
||||
this.transactionService.startTransaction();
|
||||
this.domainObject.getCapability('status').set('editing', true);
|
||||
};
|
||||
|
||||
function isEditing (domainObject) {
|
||||
return domainObject.getCapability('status').get('editing') ||
|
||||
domainObject.hasCapability('context') && isEditing(domainObject.getCapability('context').getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save any changes that have been made to this domain object
|
||||
* (as well as to others that might have been retrieved and
|
||||
* modified during the editing session)
|
||||
* @param {boolean} nonrecursive if true, save only this
|
||||
* object (and not other objects with associated changes)
|
||||
* @returns {Promise} a promise that will be fulfilled after
|
||||
* persistence has completed.
|
||||
* @memberof platform/commonUI/edit.EditorCapability#
|
||||
* Determines whether this object, or any of its ancestors are
|
||||
* currently being edited.
|
||||
* @returns boolean
|
||||
*/
|
||||
EditorCapability.prototype.save = function (nonrecursive) {
|
||||
var domainObject = this.domainObject,
|
||||
editableObject = this.editableObject,
|
||||
self = this,
|
||||
cache = this.cache,
|
||||
returnPromise;
|
||||
EditorCapability.prototype.isEditing = function () {
|
||||
return isEditing(this.domainObject);
|
||||
};
|
||||
|
||||
// Update the underlying, "real" domain object's model
|
||||
// with changes made to the copy used for editing.
|
||||
function doMutate() {
|
||||
return domainObject.useCapability('mutation', function () {
|
||||
return editableObject.getModel();
|
||||
});
|
||||
}
|
||||
|
||||
// Persist the underlying domain object
|
||||
function doPersist() {
|
||||
return domainObject.getCapability('persistence').persist();
|
||||
}
|
||||
|
||||
editableObject.getCapability("status").set("editing", false);
|
||||
|
||||
if (nonrecursive) {
|
||||
returnPromise = resolvePromise(doMutate())
|
||||
.then(doPersist)
|
||||
.then(function(){
|
||||
self.cancel();
|
||||
});
|
||||
} else {
|
||||
returnPromise = resolvePromise(cache.saveAll());
|
||||
}
|
||||
//Return the original (non-editable) object
|
||||
return returnPromise.then(function() {
|
||||
return domainObject.getOriginalObject ? domainObject.getOriginalObject() : domainObject;
|
||||
EditorCapability.prototype.save = function () {
|
||||
var domainObject = this.domainObject;
|
||||
return this.transactionService.commit().then(function() {
|
||||
domainObject.getCapability('status').set('editing', false);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel editing; Discard any changes that have been made to
|
||||
* this domain object (as well as to others that might have
|
||||
* been retrieved and modified during the editing session)
|
||||
* @returns {Promise} a promise that will be fulfilled after
|
||||
* cancellation has completed.
|
||||
* @memberof platform/commonUI/edit.EditorCapability#
|
||||
*/
|
||||
EditorCapability.prototype.invoke = EditorCapability.prototype.edit;
|
||||
|
||||
EditorCapability.prototype.cancel = function () {
|
||||
this.editableObject.getCapability("status").set("editing", false);
|
||||
this.cache.markClean();
|
||||
return resolvePromise(undefined);
|
||||
var domainObject = this.domainObject;
|
||||
return this.transactionService.cancel().then(function(){
|
||||
domainObject.getCapability("status").set("editing", false);
|
||||
return domainObject;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if there are any unsaved changes.
|
||||
* @returns {boolean} true if there are unsaved changes
|
||||
* @memberof platform/commonUI/edit.EditorCapability#
|
||||
*/
|
||||
EditorCapability.prototype.dirty = function () {
|
||||
return this.cache.dirty();
|
||||
return this.dirtyModelCache.isDirty(this.domainObject);
|
||||
};
|
||||
|
||||
EditorCapability.prototype.appliesTo = function(context) {
|
||||
var domainObject = context.domainObject;
|
||||
return domainObject && domainObject.getType().hasFeature("creation");
|
||||
}
|
||||
|
||||
return EditorCapability;
|
||||
}
|
||||
);
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
['./TransactionalPersistenceCapability'],
|
||||
function (TransactionalPersistenceCapability) {
|
||||
'use strict';
|
||||
|
||||
function TransactionDecorator(
|
||||
$q,
|
||||
transactionService,
|
||||
dirtyModelCache,
|
||||
capabilityService
|
||||
) {
|
||||
this.capabilityService = capabilityService;
|
||||
this.transactionService = transactionService;
|
||||
this.dirtyModelCache = dirtyModelCache;
|
||||
this.$q = $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate PersistenceCapability to ignore persistence calls when a
|
||||
* transaction is in progress.
|
||||
*/
|
||||
TransactionDecorator.prototype.getCapabilities = function (model) {
|
||||
var self = this,
|
||||
capabilities = this.capabilityService.getCapabilities(model),
|
||||
persistenceCapability = capabilities.persistence;
|
||||
|
||||
capabilities.persistence = function (domainObject) {
|
||||
var original =
|
||||
(typeof persistenceCapability === 'function') ?
|
||||
persistenceCapability(domainObject) :
|
||||
persistenceCapability;
|
||||
return new TransactionalPersistenceCapability(
|
||||
self.$q,
|
||||
self.transactionService,
|
||||
self.dirtyModelCache,
|
||||
original,
|
||||
domainObject
|
||||
);
|
||||
};
|
||||
return capabilities;
|
||||
};
|
||||
|
||||
return TransactionDecorator;
|
||||
}
|
||||
);
|
@ -0,0 +1,75 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
[],
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
function TransactionalPersistenceCapability(
|
||||
$q,
|
||||
transactionService,
|
||||
dirtyModelCache,
|
||||
persistenceCapability,
|
||||
domainObject
|
||||
) {
|
||||
this.transactionService = transactionService;
|
||||
this.dirtyModelCache = dirtyModelCache;
|
||||
this.persistenceCapability = Object.create(persistenceCapability);
|
||||
this.domainObject = domainObject;
|
||||
this.$q = $q;
|
||||
}
|
||||
|
||||
TransactionalPersistenceCapability.prototype.persist = function () {
|
||||
var domainObject = this.domainObject,
|
||||
dirtyModelCache = this.dirtyModelCache;
|
||||
if (this.transactionService.isActive() && !this.transactionService.isCommitting()) {
|
||||
dirtyModelCache.markDirty(domainObject);
|
||||
//Using $q here because need to return something
|
||||
// from which 'catch' can be chained
|
||||
return this.$q.when(true);
|
||||
} else {
|
||||
return this.persistenceCapability.persist().then(function (result) {
|
||||
dirtyModelCache.markClean(domainObject);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TransactionalPersistenceCapability.prototype.refresh = function () {
|
||||
var domainObject = this.domainObject,
|
||||
dirtyModelCache = this.dirtyModelCache;
|
||||
|
||||
return this.persistenceCapability.refresh().then(function (result) {
|
||||
dirtyModelCache.markClean(domainObject);
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
TransactionalPersistenceCapability.prototype.getSpace = function () {
|
||||
return this.persistenceCapability.getSpace();
|
||||
};
|
||||
|
||||
return TransactionalPersistenceCapability;
|
||||
}
|
||||
);
|
@ -1,132 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Defines EditableDomainObject, which wraps domain objects
|
||||
* such that user code may work with and mutate a copy of the
|
||||
* domain object model; these changes may then be propagated
|
||||
* up to the real domain object (or not) by way of invoking
|
||||
* save or cancel behaviors of the "editor.completion"
|
||||
* capability (a capability intended as internal to edit
|
||||
* mode; invoked by way of the Save and Cancel actions.)
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'../capabilities/EditablePersistenceCapability',
|
||||
'../capabilities/EditableContextCapability',
|
||||
'../capabilities/EditableCompositionCapability',
|
||||
'../capabilities/EditableRelationshipCapability',
|
||||
'../capabilities/EditableInstantiationCapability',
|
||||
'../capabilities/EditorCapability',
|
||||
'../capabilities/EditableActionCapability',
|
||||
'./EditableDomainObjectCache'
|
||||
],
|
||||
function (
|
||||
EditablePersistenceCapability,
|
||||
EditableContextCapability,
|
||||
EditableCompositionCapability,
|
||||
EditableRelationshipCapability,
|
||||
EditableInstantiationCapability,
|
||||
EditorCapability,
|
||||
EditableActionCapability,
|
||||
EditableDomainObjectCache
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
var capabilityFactories = {
|
||||
persistence: EditablePersistenceCapability,
|
||||
context: EditableContextCapability,
|
||||
composition: EditableCompositionCapability,
|
||||
relationship: EditableRelationshipCapability,
|
||||
instantiation: EditableInstantiationCapability,
|
||||
editor: EditorCapability
|
||||
};
|
||||
|
||||
// Handle special case where "editor.completion" wraps persistence
|
||||
// (other capability overrides wrap capabilities of the same type.)
|
||||
function getDelegateArguments(name, args) {
|
||||
return name === "editor" ? ['persistence'] : args;
|
||||
}
|
||||
|
||||
/**
|
||||
* An EditableDomainObject overrides capabilities
|
||||
* which need to behave differently in edit mode,
|
||||
* and provides a "working copy" of the object's
|
||||
* model to allow changes to be easily cancelled.
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {DomainObject}
|
||||
*/
|
||||
function EditableDomainObject(domainObject, $q) {
|
||||
// The cache will hold all domain objects reached from
|
||||
// the initial EditableDomainObject; this ensures that
|
||||
// different versions of the same editable domain object
|
||||
// are not shown in different sections of the same Edit
|
||||
// UI, which might thereby fall out of sync.
|
||||
var cache,
|
||||
originalObject = domainObject,
|
||||
cachedObject;
|
||||
|
||||
// Constructor for EditableDomainObject, which adheres
|
||||
// to the same shared cache.
|
||||
function EditableDomainObjectImpl(domainObject, model) {
|
||||
var editableObject = Object.create(domainObject);
|
||||
|
||||
// Only provide the cloned model.
|
||||
editableObject.getModel = function () { return model; };
|
||||
|
||||
// Override certain capabilities
|
||||
editableObject.getCapability = function (name) {
|
||||
var delegateArguments = getDelegateArguments(name, arguments),
|
||||
capability = domainObject.getCapability.apply(
|
||||
this,
|
||||
delegateArguments
|
||||
),
|
||||
Factory = capabilityFactories[name];
|
||||
|
||||
return (Factory && capability) ?
|
||||
new Factory(capability, editableObject, domainObject, cache) :
|
||||
capability;
|
||||
};
|
||||
|
||||
|
||||
editableObject.setOriginalObject = function(object) {
|
||||
originalObject = object;
|
||||
};
|
||||
|
||||
editableObject.getOriginalObject = function() {
|
||||
return originalObject;
|
||||
};
|
||||
|
||||
return editableObject;
|
||||
}
|
||||
|
||||
cache = new EditableDomainObjectCache(EditableDomainObjectImpl, $q);
|
||||
cachedObject = cache.getEditableObject(domainObject);
|
||||
|
||||
return cachedObject;
|
||||
}
|
||||
|
||||
return EditableDomainObject;
|
||||
}
|
||||
);
|
@ -1,173 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
|
||||
/*
|
||||
* An editable domain object cache stores domain objects that have been
|
||||
* made editable, in a group that can be saved all-at-once. This supports
|
||||
* Edit mode, which is launched for a specific object but may contain
|
||||
* changes across many objects.
|
||||
*
|
||||
* Editable domain objects have certain specific capabilities overridden
|
||||
* to ensure that changes made while in edit mode do not propagate up
|
||||
* to the objects used in browse mode (or to persistence) until the user
|
||||
* initiates a Save.
|
||||
*/
|
||||
define(
|
||||
["./EditableModelCache"],
|
||||
function (EditableModelCache) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Construct a new cache for editable domain objects. This can be used
|
||||
* to get-or-create editable objects, particularly to support wrapping
|
||||
* of objects retrieved via composition or context capabilities as
|
||||
* editable domain objects.
|
||||
*
|
||||
* @param {Constructor<DomainObject>} EditableDomainObject a
|
||||
* constructor function which takes a regular domain object as
|
||||
* an argument, and returns an editable domain object as its
|
||||
* result.
|
||||
* @param $q Angular's $q, for promise handling
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
*/
|
||||
function EditableDomainObjectCache(EditableDomainObject, $q) {
|
||||
this.cache = new EditableModelCache();
|
||||
this.dirtyObjects = {};
|
||||
this.root = undefined;
|
||||
this.$q = $q;
|
||||
this.EditableDomainObject = EditableDomainObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap this domain object in an editable form, or pull such
|
||||
* an object from the cache if one already exists.
|
||||
*
|
||||
* @param {DomainObject} domainObject the regular domain object
|
||||
* @returns {DomainObject} the domain object in an editable form
|
||||
*/
|
||||
EditableDomainObjectCache.prototype.getEditableObject = function (domainObject) {
|
||||
var type = domainObject.getCapability('type'),
|
||||
EditableDomainObject = this.EditableDomainObject,
|
||||
editableObject,
|
||||
statusListener;
|
||||
|
||||
// Track the top-level domain object; this will have
|
||||
// some special behavior for its context capability.
|
||||
this.root = this.root || domainObject;
|
||||
|
||||
// Avoid double-wrapping (WTD-1017)
|
||||
if (domainObject.hasCapability('editor')) {
|
||||
return domainObject;
|
||||
}
|
||||
|
||||
// Don't bother wrapping non-editable objects
|
||||
if (!type || !type.hasFeature('creation')) {
|
||||
return domainObject;
|
||||
}
|
||||
|
||||
// Provide an editable form of the object
|
||||
editableObject = new EditableDomainObject(
|
||||
domainObject,
|
||||
this.cache.getCachedModel(domainObject)
|
||||
);
|
||||
|
||||
return editableObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a domain object is (effectively) the top-level
|
||||
* object in this editable subgraph.
|
||||
* @returns {boolean} true if it is the root
|
||||
*/
|
||||
EditableDomainObjectCache.prototype.isRoot = function (domainObject) {
|
||||
return domainObject === this.root;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark an editable domain object (presumably already cached)
|
||||
* as having received modifications during editing; it should be
|
||||
* included in the bulk save invoked when editing completes.
|
||||
*
|
||||
* @param {DomainObject} domainObject the domain object
|
||||
* @memberof platform/commonUI/edit.EditableDomainObjectCache#
|
||||
*/
|
||||
EditableDomainObjectCache.prototype.markDirty = function (domainObject) {
|
||||
this.dirtyObjects[domainObject.getId()] = domainObject;
|
||||
return this.$q.when(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark an object (presumably already cached) as having had its
|
||||
* changes saved (and thus no longer needing to be subject to a
|
||||
* save operation.)
|
||||
*
|
||||
* @param {DomainObject} domainObject the domain object
|
||||
*/
|
||||
EditableDomainObjectCache.prototype.markClean = function (domainObject) {
|
||||
var self = this;
|
||||
if (!domainObject) {
|
||||
Object.keys(this.dirtyObjects).forEach(function(key) {
|
||||
delete self.dirtyObjects[key];
|
||||
});
|
||||
} else {
|
||||
delete this.dirtyObjects[domainObject.getId()];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initiate a save on all objects that have been cached.
|
||||
* @return {Promise} A promise which will resolve when all objects are
|
||||
* persisted.
|
||||
*/
|
||||
EditableDomainObjectCache.prototype.saveAll = function () {
|
||||
// Get a list of all dirty objects
|
||||
var dirty = this.dirtyObjects,
|
||||
objects = Object.keys(dirty).map(function (k) {
|
||||
return dirty[k];
|
||||
});
|
||||
|
||||
// Clear dirty set, since we're about to save.
|
||||
this.dirtyObjects = {};
|
||||
|
||||
// Most save logic is handled by the "editor.completion"
|
||||
// capability, so that is delegated here.
|
||||
return this.$q.all(objects.map(function (object) {
|
||||
// Save; pass a nonrecursive flag to avoid looping
|
||||
return object.getCapability('editor').save(true);
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if any objects have been marked dirty in this cache.
|
||||
* @returns {boolean} true if objects are dirty
|
||||
*/
|
||||
EditableDomainObjectCache.prototype.dirty = function () {
|
||||
return Object.keys(this.dirtyObjects).length > 0;
|
||||
};
|
||||
|
||||
return EditableDomainObjectCache;
|
||||
}
|
||||
);
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* An editable model cache stores domain object models that have been
|
||||
* made editable, to support a group that can be saved all-at-once.
|
||||
* This is useful in Edit mode, which is launched for a specific
|
||||
* object but may contain changes across many objects.
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
*/
|
||||
function EditableModelCache() {
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
// Deep-copy a model. Models are JSONifiable, so this can be
|
||||
// done by stringification then destringification
|
||||
function clone(model) {
|
||||
return JSON.parse(JSON.stringify(model));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this domain object's model from the cache (or
|
||||
* place it in the cache if it isn't in the cache yet)
|
||||
* @returns a clone of the domain object's model
|
||||
*/
|
||||
EditableModelCache.prototype.getCachedModel = function (domainObject) {
|
||||
var id = domainObject.getId(),
|
||||
cache = this.cache;
|
||||
|
||||
return (cache[id] =
|
||||
cache[id] || clone(domainObject.getModel()));
|
||||
};
|
||||
|
||||
return EditableModelCache;
|
||||
}
|
||||
);
|
@ -37,11 +37,12 @@ define([], function () {
|
||||
}
|
||||
|
||||
EditableLinkPolicy.prototype.allow = function (action, context) {
|
||||
var key = action.getMetadata().key;
|
||||
var key = action.getMetadata().key,
|
||||
object;
|
||||
|
||||
if (key === 'link') {
|
||||
return !((context.selectedObject || context.domainObject)
|
||||
.hasCapability('editor'));
|
||||
object = context.selectedObject || context.domainObject;
|
||||
return !(object.hasCapability("editor") && object.getCapability("editor").isEditing());
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
|
@ -39,8 +39,8 @@ define([], function () {
|
||||
selectedObject = context.selectedObject,
|
||||
key = action.getMetadata().key;
|
||||
|
||||
if (key === 'move' && domainObject.hasCapability('editor')) {
|
||||
return !!selectedObject && selectedObject.hasCapability('editor');
|
||||
if (key === 'move' && domainObject.hasCapability('editor') && domainObject.getCapability('editor').isEditing()) {
|
||||
return !!selectedObject && selectedObject.hasCapability('editor') && selectedObject.getCapability('editor').isEditing();
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
|
@ -39,7 +39,7 @@ define(
|
||||
// If a view is flagged as non-editable, only allow it
|
||||
// while we're not in Edit mode.
|
||||
if ((view || {}).editable === false) {
|
||||
return !domainObject.hasCapability('editor');
|
||||
return !(domainObject.hasCapability('editor') && domainObject.getCapability('editor').isEditing());
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
|
@ -19,15 +19,29 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
/*global define*/
|
||||
define(
|
||||
["../../src/objects/EditableDomainObject"],
|
||||
function (EditableDomainObject) {
|
||||
"use strict";
|
||||
[],
|
||||
function() {
|
||||
function DirtyModelCache(topic) {
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
describe("Editable domain object", function () {
|
||||
DirtyModelCache.prototype.get = function () {
|
||||
return this.cache;
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
DirtyModelCache.prototype.isDirty = function (domainObject) {
|
||||
return !!this.cache[domainObject.getId()];
|
||||
};
|
||||
|
||||
DirtyModelCache.prototype.markDirty = function (domainObject) {
|
||||
this.cache[domainObject.getId()] = domainObject;
|
||||
};
|
||||
|
||||
DirtyModelCache.prototype.markClean = function (domainObject) {
|
||||
delete this.cache[domainObject.getId()];
|
||||
};
|
||||
|
||||
return DirtyModelCache;
|
||||
});
|
118
platform/commonUI/edit/src/services/TransactionService.js
Normal file
118
platform/commonUI/edit/src/services/TransactionService.js
Normal file
@ -0,0 +1,118 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
[],
|
||||
function() {
|
||||
/**
|
||||
* Implements an application-wide transaction state. Once a
|
||||
* transaction is started, calls to PersistenceCapability.persist()
|
||||
* will be deferred until a subsequent call to
|
||||
* TransactionService.commit() is made.
|
||||
*
|
||||
* @param $q
|
||||
* @constructor
|
||||
*/
|
||||
function TransactionService($q, dirtyModelCache) {
|
||||
this.$q = $q;
|
||||
this.transaction = false;
|
||||
this.committing = false;
|
||||
this.cache = dirtyModelCache;
|
||||
}
|
||||
|
||||
TransactionService.prototype.startTransaction = function () {
|
||||
if (this.transaction)
|
||||
console.error("Transaction already in progress")
|
||||
this.transaction = true;
|
||||
};
|
||||
|
||||
TransactionService.prototype.isActive = function () {
|
||||
return this.transaction;
|
||||
};
|
||||
|
||||
TransactionService.prototype.isCommitting = function () {
|
||||
return this.committing;
|
||||
};
|
||||
|
||||
/**
|
||||
* All persist calls deferred since the beginning of the transaction
|
||||
* will be committed. Any failures will be reported via a promise
|
||||
* rejection.
|
||||
* @returns {*}
|
||||
*/
|
||||
TransactionService.prototype.commit = function () {
|
||||
var self = this;
|
||||
cache = this.cache.get();
|
||||
|
||||
this.committing = true;
|
||||
|
||||
function keyToObject(key) {
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
function objectToPromise(object) {
|
||||
return object.getCapability('persistence').persist();
|
||||
}
|
||||
|
||||
return this.$q.all(
|
||||
Object.keys(cache)
|
||||
.map(keyToObject)
|
||||
.map(objectToPromise))
|
||||
.then(function () {
|
||||
self.transaction = false;
|
||||
this.committing = false;
|
||||
}).catch(function() {
|
||||
return this.committing = false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel the current transaction, replacing any dirty objects from
|
||||
* persistence. Not a true rollback, as it cannot be used to undo any
|
||||
* persist calls that were successful in the event one of a batch of
|
||||
* persists failing.
|
||||
*
|
||||
* @returns {*}
|
||||
*/
|
||||
TransactionService.prototype.cancel = function () {
|
||||
var self = this,
|
||||
cache = this.cache.get();
|
||||
|
||||
function keyToObject(key) {
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
function objectToPromise(object) {
|
||||
return self.$q.when(object.getModel().persisted && object.getCapability('persistence').refresh());
|
||||
}
|
||||
|
||||
return this.$q.all(Object.keys(cache)
|
||||
.map(keyToObject)
|
||||
.map(objectToPromise))
|
||||
.then(function () {
|
||||
self.transaction = false;
|
||||
this.committing = false;
|
||||
});
|
||||
};
|
||||
|
||||
return TransactionService;
|
||||
});
|
@ -1,75 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/capabilities/EditableCompositionCapability"],
|
||||
function (EditableCompositionCapability) {
|
||||
"use strict";
|
||||
|
||||
describe("An editable composition capability", function () {
|
||||
var mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockTestObject,
|
||||
someValue,
|
||||
mockFactory,
|
||||
capability;
|
||||
|
||||
beforeEach(function () {
|
||||
// EditableContextCapability should watch ALL
|
||||
// methods for domain objects, so give it an
|
||||
// arbitrary interface to wrap.
|
||||
mockContext =
|
||||
jasmine.createSpyObj("context", [ "getDomainObject" ]);
|
||||
mockTestObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
mockFactory =
|
||||
jasmine.createSpyObj("factory", ["getEditableObject"]);
|
||||
|
||||
someValue = { x: 42 };
|
||||
|
||||
mockContext.getDomainObject.andReturn(mockTestObject);
|
||||
mockFactory.getEditableObject.andReturn(someValue);
|
||||
|
||||
capability = new EditableCompositionCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockFactory
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
// Most behavior is tested for EditableLookupCapability,
|
||||
// so just verify that this isse
|
||||
it("presumes non-idempotence of its wrapped capability", function () {
|
||||
expect(capability.getDomainObject())
|
||||
.toEqual(capability.getDomainObject());
|
||||
expect(mockContext.getDomainObject.calls.length).toEqual(2);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,89 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/capabilities/EditableContextCapability"],
|
||||
function (EditableContextCapability) {
|
||||
"use strict";
|
||||
|
||||
describe("An editable context capability", function () {
|
||||
var mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockTestObject,
|
||||
someValue,
|
||||
mockFactory,
|
||||
capability;
|
||||
|
||||
beforeEach(function () {
|
||||
// EditableContextCapability should watch ALL
|
||||
// methods for domain objects, so give it an
|
||||
// arbitrary interface to wrap.
|
||||
mockContext =
|
||||
jasmine.createSpyObj("context", [ "getDomainObject", "getRoot" ]);
|
||||
mockTestObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
mockFactory = jasmine.createSpyObj(
|
||||
"factory",
|
||||
["getEditableObject", "isRoot"]
|
||||
);
|
||||
|
||||
someValue = { x: 42 };
|
||||
|
||||
mockContext.getRoot.andReturn(mockTestObject);
|
||||
mockContext.getDomainObject.andReturn(mockTestObject);
|
||||
mockFactory.getEditableObject.andReturn(someValue);
|
||||
mockFactory.isRoot.andReturn(true);
|
||||
|
||||
capability = new EditableContextCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockFactory
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
it("presumes idempotence of its wrapped capability", function () {
|
||||
expect(capability.getDomainObject())
|
||||
.toEqual(capability.getDomainObject());
|
||||
expect(mockContext.getDomainObject.calls.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("hides the root object", function () {
|
||||
expect(capability.getRoot()).toEqual(mockEditableObject);
|
||||
expect(capability.getPath()).toEqual([mockEditableObject]);
|
||||
});
|
||||
|
||||
it("exposes the root object through a different method", function () {
|
||||
// Should still go through the factory...
|
||||
expect(capability.getTrueRoot()).toEqual(someValue);
|
||||
// ...with value of the unwrapped capability's getRoot
|
||||
expect(mockFactory.getEditableObject)
|
||||
.toHaveBeenCalledWith(mockTestObject);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -1,146 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/capabilities/EditableLookupCapability"],
|
||||
function (EditableLookupCapability) {
|
||||
"use strict";
|
||||
|
||||
describe("An editable lookup capability", function () {
|
||||
var mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockTestObject,
|
||||
someValue,
|
||||
factory,
|
||||
capability;
|
||||
|
||||
beforeEach(function () {
|
||||
// EditableContextCapability should watch ALL
|
||||
// methods for domain objects, so give it an
|
||||
// arbitrary interface to wrap.
|
||||
mockContext = jasmine.createSpyObj(
|
||||
"context",
|
||||
[
|
||||
"getSomething",
|
||||
"getDomainObject",
|
||||
"getDomainObjectArray"
|
||||
]
|
||||
);
|
||||
mockTestObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
factory = {
|
||||
getEditableObject: function (v) {
|
||||
return {
|
||||
isFromTestFactory: true,
|
||||
calledWith: v
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
someValue = { x: 42 };
|
||||
|
||||
mockContext.getSomething.andReturn(someValue);
|
||||
mockContext.getDomainObject.andReturn(mockTestObject);
|
||||
mockContext.getDomainObjectArray.andReturn([mockTestObject]);
|
||||
|
||||
capability = new EditableLookupCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
factory,
|
||||
false
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
it("wraps retrieved domain objects", function () {
|
||||
var object = capability.getDomainObject();
|
||||
expect(object.isFromTestFactory).toBe(true);
|
||||
expect(object.calledWith).toEqual(mockTestObject);
|
||||
});
|
||||
|
||||
it("wraps retrieved domain object arrays", function () {
|
||||
var object = capability.getDomainObjectArray()[0];
|
||||
expect(object.isFromTestFactory).toBe(true);
|
||||
expect(object.calledWith).toEqual(mockTestObject);
|
||||
});
|
||||
|
||||
it("does not wrap non-domain-objects", function () {
|
||||
expect(capability.getSomething()).toEqual(someValue);
|
||||
});
|
||||
|
||||
it("caches idempotent lookups", function () {
|
||||
capability = new EditableLookupCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
factory,
|
||||
true // idempotent
|
||||
);
|
||||
expect(capability.getDomainObject())
|
||||
.toEqual(capability.getDomainObject());
|
||||
expect(mockContext.getDomainObject.calls.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("does not cache non-idempotent lookups", function () {
|
||||
capability = new EditableLookupCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
factory,
|
||||
false // Not idempotent
|
||||
);
|
||||
expect(capability.getDomainObject())
|
||||
.toEqual(capability.getDomainObject());
|
||||
expect(mockContext.getDomainObject.calls.length).toEqual(2);
|
||||
});
|
||||
|
||||
it("wraps inherited methods", function () {
|
||||
var CapabilityClass = function(){
|
||||
};
|
||||
CapabilityClass.prototype.inheritedMethod=function () {
|
||||
return "an inherited method";
|
||||
};
|
||||
|
||||
mockContext = new CapabilityClass();
|
||||
|
||||
capability = new EditableLookupCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
factory,
|
||||
false
|
||||
);
|
||||
expect(capability.inheritedMethod()).toEqual("an inherited method");
|
||||
expect(capability.hasOwnProperty('inheritedMethod')).toBe(true);
|
||||
// The presence of an own property indicates that the method
|
||||
// has been wrapped on the object itself and this is a valid
|
||||
// test that the inherited method has been wrapped.
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,96 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/capabilities/EditablePersistenceCapability"],
|
||||
function (EditablePersistenceCapability) {
|
||||
"use strict";
|
||||
|
||||
describe("An editable persistence capability", function () {
|
||||
var mockPersistence,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockCache,
|
||||
mockPromise,
|
||||
capability;
|
||||
|
||||
beforeEach(function () {
|
||||
mockPersistence = jasmine.createSpyObj(
|
||||
"persistence",
|
||||
[ "persist", "refresh" ]
|
||||
);
|
||||
mockEditableObject = jasmine.createSpyObj(
|
||||
"editableObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"editableObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
mockCache = jasmine.createSpyObj(
|
||||
"cache",
|
||||
[ "markDirty" ]
|
||||
);
|
||||
mockPromise = jasmine.createSpyObj("promise", ["then"]);
|
||||
|
||||
mockCache.markDirty.andReturn(mockPromise);
|
||||
mockDomainObject.getCapability.andReturn(mockPersistence);
|
||||
|
||||
capability = new EditablePersistenceCapability(
|
||||
mockPersistence,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockCache
|
||||
);
|
||||
});
|
||||
|
||||
it("marks objects as dirty (in the cache) upon persist", function () {
|
||||
capability.persist();
|
||||
expect(mockCache.markDirty)
|
||||
.toHaveBeenCalledWith(mockEditableObject);
|
||||
});
|
||||
|
||||
it("does not invoke the underlying persistence capability", function () {
|
||||
capability.persist();
|
||||
expect(mockPersistence.persist).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("refreshes using the original domain object's persistence", function () {
|
||||
// Refreshing needs to delegate via the unwrapped domain object.
|
||||
// Otherwise, only the editable version of the object will be updated;
|
||||
// we instead want the real version of the object to receive these
|
||||
// changes.
|
||||
expect(mockDomainObject.getCapability).not.toHaveBeenCalled();
|
||||
expect(mockPersistence.refresh).not.toHaveBeenCalled();
|
||||
capability.refresh();
|
||||
expect(mockDomainObject.getCapability).toHaveBeenCalledWith('persistence');
|
||||
expect(mockPersistence.refresh).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns a promise from persist", function () {
|
||||
expect(capability.persist().then).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,75 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/capabilities/EditableRelationshipCapability"],
|
||||
function (EditableRelationshipCapability) {
|
||||
"use strict";
|
||||
|
||||
describe("An editable relationship capability", function () {
|
||||
var mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockTestObject,
|
||||
someValue,
|
||||
mockFactory,
|
||||
capability;
|
||||
|
||||
beforeEach(function () {
|
||||
// EditableContextCapability should watch ALL
|
||||
// methods for domain objects, so give it an
|
||||
// arbitrary interface to wrap.
|
||||
mockContext =
|
||||
jasmine.createSpyObj("context", [ "getDomainObject" ]);
|
||||
mockTestObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
mockFactory =
|
||||
jasmine.createSpyObj("factory", ["getEditableObject"]);
|
||||
|
||||
someValue = { x: 42 };
|
||||
|
||||
mockContext.getDomainObject.andReturn(mockTestObject);
|
||||
mockFactory.getEditableObject.andReturn(someValue);
|
||||
|
||||
capability = new EditableRelationshipCapability(
|
||||
mockContext,
|
||||
mockEditableObject,
|
||||
mockDomainObject,
|
||||
mockFactory
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
// Most behavior is tested for EditableLookupCapability,
|
||||
// so just verify that this isse
|
||||
it("presumes non-idempotence of its wrapped capability", function () {
|
||||
expect(capability.getDomainObject())
|
||||
.toEqual(capability.getDomainObject());
|
||||
expect(mockContext.getDomainObject.calls.length).toEqual(2);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,180 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/objects/EditableDomainObjectCache"],
|
||||
function (EditableDomainObjectCache) {
|
||||
'use strict';
|
||||
|
||||
describe("Editable domain object cache", function () {
|
||||
|
||||
var captured,
|
||||
completionCapability,
|
||||
object,
|
||||
mockQ,
|
||||
mockType,
|
||||
cache;
|
||||
|
||||
|
||||
// Constructors for test objects
|
||||
function TestObject(id) {
|
||||
return {
|
||||
getId: function () { return id; },
|
||||
getModel: function () { return {}; },
|
||||
getCapability: function (key) {
|
||||
return {
|
||||
editor: completionCapability,
|
||||
type: mockType
|
||||
}[key];
|
||||
},
|
||||
hasCapability: function (key) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function WrapObject(domainObject, model) {
|
||||
var result = Object.create(domainObject);
|
||||
result.wrapped = true;
|
||||
result.wrappedModel = model;
|
||||
result.hasCapability = function (name) {
|
||||
return name === 'editor';
|
||||
};
|
||||
captured.wraps = (captured.wraps || 0) + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockQ = jasmine.createSpyObj('$q', ['when', 'all']);
|
||||
mockType = jasmine.createSpyObj('type', ['hasFeature']);
|
||||
mockType.hasFeature.andReturn(true);
|
||||
captured = {};
|
||||
completionCapability = {
|
||||
save: function () {
|
||||
captured.saved = (captured.saved || 0) + 1;
|
||||
}
|
||||
};
|
||||
|
||||
cache = new EditableDomainObjectCache(WrapObject, mockQ);
|
||||
});
|
||||
|
||||
it("wraps objects using provided constructor", function () {
|
||||
var domainObject = new TestObject('test-id'),
|
||||
wrappedObject = cache.getEditableObject(domainObject);
|
||||
expect(wrappedObject.wrapped).toBeTruthy();
|
||||
expect(wrappedObject.getId()).toEqual(domainObject.getId());
|
||||
});
|
||||
|
||||
it("wraps objects repeatedly, wraps models once", function () {
|
||||
var domainObject = new TestObject('test-id'),
|
||||
wrappedObjects = [];
|
||||
|
||||
// Verify precondition
|
||||
expect(captured.wraps).toBeUndefined();
|
||||
|
||||
// Invoke a few more times; expect count not to increment
|
||||
wrappedObjects.push(cache.getEditableObject(domainObject));
|
||||
expect(captured.wraps).toEqual(1);
|
||||
wrappedObjects.push(cache.getEditableObject(domainObject));
|
||||
expect(captured.wraps).toEqual(2);
|
||||
wrappedObjects.push(cache.getEditableObject(domainObject));
|
||||
expect(captured.wraps).toEqual(3);
|
||||
|
||||
// Verify that the last call still gave us a wrapped object
|
||||
expect(wrappedObjects[0].wrapped).toBeTruthy();
|
||||
expect(wrappedObjects[0].getId()).toEqual(domainObject.getId());
|
||||
|
||||
// Verify that objects are distinct but models are identical
|
||||
expect(wrappedObjects[0].wrappedModel)
|
||||
.toBe(wrappedObjects[1].wrappedModel);
|
||||
expect(wrappedObjects[0]).not
|
||||
.toBe(wrappedObjects[1]);
|
||||
});
|
||||
|
||||
it("saves objects that have been marked dirty", function () {
|
||||
var objects = ['a', 'b', 'c'].map(TestObject).map(function (domainObject) {
|
||||
return cache.getEditableObject(domainObject);
|
||||
});
|
||||
|
||||
cache.markDirty(objects[0]);
|
||||
cache.markDirty(objects[2]);
|
||||
|
||||
cache.saveAll();
|
||||
|
||||
expect(captured.saved).toEqual(2);
|
||||
});
|
||||
|
||||
it("does not save objects that have been marked clean", function () {
|
||||
var objects = ['a', 'b', 'c'].map(TestObject).map(function (domainObject) {
|
||||
return cache.getEditableObject(domainObject);
|
||||
});
|
||||
|
||||
cache.markDirty(objects[0]);
|
||||
cache.markDirty(objects[2]);
|
||||
cache.markClean(objects[0]);
|
||||
|
||||
cache.saveAll();
|
||||
|
||||
expect(captured.saved).toEqual(1);
|
||||
});
|
||||
|
||||
it("tracks the root object of the Edit mode subgraph", function () {
|
||||
// Root object is the first object exposed to the cache
|
||||
var domainObjects = ['a', 'b', 'c'].map(TestObject);
|
||||
domainObjects.forEach(function (obj) {
|
||||
cache.getEditableObject(obj);
|
||||
});
|
||||
expect(cache.isRoot(domainObjects[0])).toBeTruthy();
|
||||
expect(cache.isRoot(domainObjects[1])).toBeFalsy();
|
||||
expect(cache.isRoot(domainObjects[2])).toBeFalsy();
|
||||
});
|
||||
|
||||
it("does not double-wrap objects", function () {
|
||||
var domainObject = new TestObject('test-id'),
|
||||
wrappedObject = cache.getEditableObject(domainObject);
|
||||
|
||||
// Same instance should be returned if you try to wrap
|
||||
// twice. This is necessary, since it's possible to (e.g.)
|
||||
// use a context capability on an object retrieved via
|
||||
// composition, in which case a result will already be
|
||||
// wrapped.
|
||||
expect(cache.getEditableObject(wrappedObject))
|
||||
.toBe(wrappedObject);
|
||||
});
|
||||
|
||||
it("does not wrap non-editable objects", function () {
|
||||
var domainObject = new TestObject('test-id');
|
||||
|
||||
mockType.hasFeature.andCallFake(function (key) {
|
||||
return key !== 'creation';
|
||||
});
|
||||
|
||||
expect(cache.getEditableObject(domainObject))
|
||||
.toBe(domainObject);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
);
|
@ -1,81 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/objects/EditableModelCache"],
|
||||
function (EditableModelCache) {
|
||||
"use strict";
|
||||
|
||||
describe("The editable model cache", function () {
|
||||
var mockObject,
|
||||
mockOtherObject,
|
||||
testModel,
|
||||
testId,
|
||||
otherModel,
|
||||
otherId,
|
||||
cache;
|
||||
|
||||
beforeEach(function () {
|
||||
testId = "test";
|
||||
testModel = { someKey: "some value" };
|
||||
otherId = "other";
|
||||
otherModel = { someKey: "some other value" };
|
||||
|
||||
mockObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel" ]
|
||||
);
|
||||
mockOtherObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel" ]
|
||||
);
|
||||
|
||||
mockObject.getId.andReturn(testId);
|
||||
mockObject.getModel.andReturn(testModel);
|
||||
mockOtherObject.getId.andReturn(otherId);
|
||||
mockOtherObject.getModel.andReturn(otherModel);
|
||||
|
||||
cache = new EditableModelCache();
|
||||
});
|
||||
|
||||
it("provides clones of domain object models", function () {
|
||||
var model = cache.getCachedModel(mockObject);
|
||||
// Should be identical...
|
||||
expect(model).toEqual(testModel);
|
||||
// ...but not pointer-identical
|
||||
expect(model).not.toBe(testModel);
|
||||
});
|
||||
|
||||
it("provides only one clone per object", function () {
|
||||
var model = cache.getCachedModel(mockObject);
|
||||
expect(cache.getCachedModel(mockObject)).toBe(model);
|
||||
});
|
||||
|
||||
it("maintains separate caches per-object", function () {
|
||||
expect(cache.getCachedModel(mockObject))
|
||||
.not.toEqual(cache.getCachedModel(mockOtherObject));
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
);
|
@ -48,7 +48,11 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
$scope.regions = filterRegions(typeCapability.getDefinition().inspector || new InspectorRegion());
|
||||
function setRegions() {
|
||||
$scope.regions = filterRegions(typeCapability.getDefinition().inspector || new InspectorRegion());
|
||||
}
|
||||
|
||||
setRegions();
|
||||
}
|
||||
|
||||
return InspectorController;
|
||||
|
@ -173,13 +173,10 @@ define(
|
||||
}, modified);
|
||||
}
|
||||
|
||||
// Only update if we don't have unsaved changes
|
||||
return (model.modified === model.persisted) ?
|
||||
this.persistenceService.readObject(
|
||||
return this.persistenceService.readObject(
|
||||
this.getSpace(),
|
||||
this.domainObject.getId()
|
||||
).then(updateModel) :
|
||||
fastPromise(false);
|
||||
).then(updateModel);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,10 @@ define(
|
||||
};
|
||||
}
|
||||
|
||||
// Check if we are in edit mode
|
||||
function inEditMode() {
|
||||
return swimlane.domainObject.hasCapability("editor");
|
||||
// Check if we are in edit mode (also check parents)
|
||||
function inEditMode(swimlane) {
|
||||
return swimlane.domainObject.hasCapability('editor') &&
|
||||
swimlane.domainObject.getCapability('editor').isEditing();
|
||||
}
|
||||
|
||||
// Boolean and (for reduce below)
|
||||
@ -175,7 +176,7 @@ define(
|
||||
* @returns {boolean} true if this should be allowed
|
||||
*/
|
||||
allowDropIn: function (id, domainObject) {
|
||||
return inEditMode() &&
|
||||
return inEditMode(swimlane) &&
|
||||
!pathContains(swimlane, id) &&
|
||||
!contains(swimlane, id) &&
|
||||
canDrop(swimlane.domainObject, domainObject);
|
||||
@ -190,7 +191,7 @@ define(
|
||||
allowDropAfter: function (id, domainObject) {
|
||||
var target = expandedForDropInto() ?
|
||||
swimlane : swimlane.parent;
|
||||
return inEditMode() &&
|
||||
return inEditMode(swimlane) &&
|
||||
target &&
|
||||
!pathContains(target, id) &&
|
||||
canDrop(target.domainObject, domainObject);
|
||||
|
@ -56,7 +56,8 @@ define(
|
||||
*/
|
||||
function MCTRepresentation(representations, views, representers, $q, templateLinker, $log) {
|
||||
var representationMap = {},
|
||||
gestureMap = {};
|
||||
gestureMap = {},
|
||||
listeners = 0;
|
||||
|
||||
// Assemble all representations and views
|
||||
// The distinction between views and representations is
|
||||
@ -94,6 +95,7 @@ define(
|
||||
couldEdit = false,
|
||||
lastIdPath = [],
|
||||
lastKey,
|
||||
statusListener,
|
||||
changeTemplate = templateLinker.link($scope, element);
|
||||
|
||||
// Populate scope with any capabilities indicated by the
|
||||
@ -170,7 +172,7 @@ define(
|
||||
representation = lookup($scope.key, domainObject),
|
||||
uses = ((representation || {}).uses || []),
|
||||
canRepresent = !!(representation && domainObject),
|
||||
canEdit = !!(domainObject && domainObject.hasCapability('editor')),
|
||||
canEdit = !!(domainObject && domainObject.hasCapability('editor') && domainObject.getCapability('editor').isEditing()),
|
||||
idPath = getIdPath(domainObject),
|
||||
key = $scope.key;
|
||||
|
||||
@ -242,6 +244,25 @@ define(
|
||||
// (to a different object)
|
||||
$scope.$watch("domainObject", refresh);
|
||||
|
||||
function listenForStatusChange(object) {
|
||||
if (statusListener) {
|
||||
statusListener();
|
||||
}
|
||||
statusListener = object.getCapability("status").listen(refresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for status changes to the object itself.
|
||||
*/
|
||||
$scope.$watch("domainObject", function(domainObject, oldDomainObject) {
|
||||
if (domainObject!==oldDomainObject){
|
||||
listenForStatusChange(domainObject);
|
||||
}
|
||||
});
|
||||
if ($scope.domainObject) {
|
||||
listenForStatusChange($scope.domainObject);
|
||||
}
|
||||
|
||||
// Finally, also update when there is a new version of that
|
||||
// same domain object; these changes should be tracked in the
|
||||
// model's "modified" field, by the mutation capability.
|
||||
@ -250,6 +271,11 @@ define(
|
||||
// Make sure any resources allocated by representers also get
|
||||
// released.
|
||||
$scope.$on("$destroy", destroyRepresenters);
|
||||
$scope.$on("$destroy", function () {
|
||||
if (statusListener) {
|
||||
statusListener();
|
||||
}
|
||||
});
|
||||
|
||||
// Do one initial refresh, so that we don't need another
|
||||
// digest iteration just to populate the scope. Failure to
|
||||
|
@ -25,9 +25,8 @@
|
||||
* Module defining DropGesture. Created by vwoeltje on 11/17/14.
|
||||
*/
|
||||
define(
|
||||
['./GestureConstants',
|
||||
'../../../commonUI/edit/src/objects/EditableDomainObject'],
|
||||
function (GestureConstants, EditableDomainObject) {
|
||||
['./GestureConstants'],
|
||||
function (GestureConstants) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
@ -43,7 +42,6 @@ define(
|
||||
*/
|
||||
function DropGesture(dndService, $q, navigationService, instantiate, typeService, element, domainObject) {
|
||||
var actionCapability = domainObject.getCapability('action'),
|
||||
editableDomainObject,
|
||||
scope = element.scope && element.scope(),
|
||||
action; // Action for the drop, when it occurs
|
||||
|
||||
@ -68,30 +66,13 @@ define(
|
||||
x: event.pageX - rect.left,
|
||||
y: event.pageY - rect.top
|
||||
},
|
||||
editableDomainObject
|
||||
domainObject
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function canCompose(domainObject, selectedObject){
|
||||
return domainObject.getCapability("action").getActions({
|
||||
key: 'compose',
|
||||
selectedObject: selectedObject
|
||||
}).length > 0;
|
||||
}
|
||||
|
||||
function dragOver(e) {
|
||||
//Refresh domain object on each dragOver to catch external
|
||||
// updates to the model
|
||||
//Don't use EditableDomainObject for folders, allow immediate persistence
|
||||
if (domainObject.hasCapability('editor') ||
|
||||
domainObject.getModel().type==='folder') {
|
||||
editableDomainObject = domainObject;
|
||||
} else {
|
||||
editableDomainObject = new EditableDomainObject(domainObject, $q);
|
||||
}
|
||||
|
||||
actionCapability = editableDomainObject.getCapability('action');
|
||||
actionCapability = domainObject.getCapability('action');
|
||||
|
||||
var event = (e || {}).originalEvent || e,
|
||||
selectedObject = dndService.getData(
|
||||
@ -117,18 +98,18 @@ define(
|
||||
function drop(e) {
|
||||
var event = (e || {}).originalEvent || e,
|
||||
id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE),
|
||||
domainObjectType = editableDomainObject.getModel().type;
|
||||
domainObjectType = domainObject.getModel().type;
|
||||
|
||||
// Handle the drop; add the dropped identifier to the
|
||||
// destination domain object's composition, and persist
|
||||
// the change.
|
||||
if (id) {
|
||||
e.preventDefault();
|
||||
$q.when(action && action.perform()).then(function (result) {
|
||||
//Don't go into edit mode for folders
|
||||
if (domainObjectType!=='folder') {
|
||||
editableDomainObject.getCapability('action').perform('edit');
|
||||
}
|
||||
if (domainObjectType!=='folder') {
|
||||
domainObject.getCapability('action').perform('edit');
|
||||
}
|
||||
|
||||
$q.when(action && action.perform()).then(function () {
|
||||
broadcastDrop(id, event);
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user