Compare commits
	
		
			7 Commits
		
	
	
		
			fix-mode
			...
			notebook-c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					03e9afb475 | ||
| 
						 | 
					2664f5e6a1 | ||
| 
						 | 
					24aca93370 | ||
| 
						 | 
					80355689ce | ||
| 
						 | 
					04c8961dfb | ||
| 
						 | 
					8c23d02cb5 | ||
| 
						 | 
					339de9fc58 | 
@@ -33,10 +33,6 @@ define([
 | 
			
		||||
    "./src/actions/CancelAction",
 | 
			
		||||
    "./src/policies/EditPersistableObjectsPolicy",
 | 
			
		||||
    "./src/representers/EditRepresenter",
 | 
			
		||||
    "./src/capabilities/EditorCapability",
 | 
			
		||||
    "./src/capabilities/TransactionCapabilityDecorator",
 | 
			
		||||
    "./src/services/TransactionManager",
 | 
			
		||||
    "./src/services/TransactionService",
 | 
			
		||||
    "./src/creation/CreateMenuController",
 | 
			
		||||
    "./src/creation/LocatorController",
 | 
			
		||||
    "./src/creation/CreationPolicy",
 | 
			
		||||
@@ -62,10 +58,6 @@ define([
 | 
			
		||||
    CancelAction,
 | 
			
		||||
    EditPersistableObjectsPolicy,
 | 
			
		||||
    EditRepresenter,
 | 
			
		||||
    EditorCapability,
 | 
			
		||||
    TransactionCapabilityDecorator,
 | 
			
		||||
    TransactionManager,
 | 
			
		||||
    TransactionService,
 | 
			
		||||
    CreateMenuController,
 | 
			
		||||
    LocatorController,
 | 
			
		||||
    CreationPolicy,
 | 
			
		||||
@@ -263,26 +255,6 @@ define([
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "components": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "decorator",
 | 
			
		||||
                        "provides": "capabilityService",
 | 
			
		||||
                        "implementation": TransactionCapabilityDecorator,
 | 
			
		||||
                        "depends": [
 | 
			
		||||
                            "$q",
 | 
			
		||||
                            "transactionManager"
 | 
			
		||||
                        ],
 | 
			
		||||
                        "priority": "fallback"
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "provider",
 | 
			
		||||
                        "provides": "transactionService",
 | 
			
		||||
                        "implementation": TransactionService,
 | 
			
		||||
                        "depends": [
 | 
			
		||||
                            "$q",
 | 
			
		||||
                            "$log",
 | 
			
		||||
                            "cacheService"
 | 
			
		||||
                        ]
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        "key": "CreateActionProvider",
 | 
			
		||||
                        "provides": "actionService",
 | 
			
		||||
@@ -313,33 +285,12 @@ define([
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "capabilities": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "key": "editor",
 | 
			
		||||
                        "name": "Editor Capability",
 | 
			
		||||
                        "description": "Provides transactional editing capabilities",
 | 
			
		||||
                        "implementation": EditorCapability,
 | 
			
		||||
                        "depends": [
 | 
			
		||||
                            "transactionService",
 | 
			
		||||
                            "openmct"
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "controls": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "key": "locator",
 | 
			
		||||
                        "template": locatorTemplate
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "services": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "key": "transactionManager",
 | 
			
		||||
                        "implementation": TransactionManager,
 | 
			
		||||
                        "depends": [
 | 
			
		||||
                            "transactionService"
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "runs": [
 | 
			
		||||
                    {
 | 
			
		||||
                        depends: [
 | 
			
		||||
 
 | 
			
		||||
@@ -1,113 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * A capability that implements an editing 'session' for a domain
 | 
			
		||||
         * object. An editing session is initiated via a call to .edit().
 | 
			
		||||
         * Once initiated, any persist operations will be queued pending a
 | 
			
		||||
         * subsequent call to [.save()](@link #save) or [.finish()](@link
 | 
			
		||||
         * #finish).
 | 
			
		||||
         * @param transactionService
 | 
			
		||||
         * @param domainObject
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function EditorCapability(
 | 
			
		||||
            transactionService,
 | 
			
		||||
            openmct,
 | 
			
		||||
            domainObject
 | 
			
		||||
        ) {
 | 
			
		||||
            this.transactionService = transactionService;
 | 
			
		||||
            this.openmct = openmct;
 | 
			
		||||
            this.domainObject = domainObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Initiate an editing session. This will start a transaction during
 | 
			
		||||
         * which any persist operations will be deferred until either save()
 | 
			
		||||
         * or finish() are called.
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.edit = function () {
 | 
			
		||||
            console.warn('DEPRECATED: cannot edit via edit capability, use openmct.editor instead.');
 | 
			
		||||
 | 
			
		||||
            if (!this.openmct.editor.isEditing()) {
 | 
			
		||||
                this.openmct.editor.edit();
 | 
			
		||||
                this.domainObject.getCapability('status').set('editing', true);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether this object, or any of its ancestors are
 | 
			
		||||
         * currently being edited.
 | 
			
		||||
         * @returns boolean
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.inEditContext = function () {
 | 
			
		||||
            return this.openmct.editor.isEditing();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Is this the root editing object (ie. the object that the user
 | 
			
		||||
         * clicked 'edit' on)?
 | 
			
		||||
         * @returns {*}
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.isEditContextRoot = function () {
 | 
			
		||||
            return this.openmct.editor.isEditing();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Save any unsaved changes from this editing session. This will
 | 
			
		||||
         * end the current transaction and continue with a new one.
 | 
			
		||||
         * @returns {*}
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.save = function () {
 | 
			
		||||
            console.warn('DEPRECATED: cannot save via edit capability, use openmct.editor instead.');
 | 
			
		||||
 | 
			
		||||
            return Promise.resolve();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        EditorCapability.prototype.invoke = EditorCapability.prototype.edit;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Finish the current editing session. This will discard any pending
 | 
			
		||||
         * persist operations
 | 
			
		||||
         * @returns {*}
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.finish = function () {
 | 
			
		||||
            console.warn('DEPRECATED: cannot finish via edit capability, use openmct.editor instead.');
 | 
			
		||||
 | 
			
		||||
            return Promise.resolve();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @returns {boolean} true if there have been any domain model
 | 
			
		||||
         * modifications since the last persist, false otherwise.
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.dirty = function () {
 | 
			
		||||
            return this.transactionService.size() > 0;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return EditorCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,75 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ['./TransactionalPersistenceCapability'],
 | 
			
		||||
    function (TransactionalPersistenceCapability) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wraps the [PersistenceCapability]{@link PersistenceCapability} with
 | 
			
		||||
         * transactional capabilities.
 | 
			
		||||
         * @param $q
 | 
			
		||||
         * @param transactionService
 | 
			
		||||
         * @param capabilityService
 | 
			
		||||
         * @see TransactionalPersistenceCapability
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function TransactionCapabilityDecorator(
 | 
			
		||||
            $q,
 | 
			
		||||
            transactionService,
 | 
			
		||||
            capabilityService
 | 
			
		||||
        ) {
 | 
			
		||||
            this.capabilityService = capabilityService;
 | 
			
		||||
            this.transactionService = transactionService;
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Decorate PersistenceCapability to queue persistence calls when a
 | 
			
		||||
         * transaction is in progress.
 | 
			
		||||
         */
 | 
			
		||||
        TransactionCapabilityDecorator.prototype.getCapabilities = function () {
 | 
			
		||||
            var self = this,
 | 
			
		||||
                capabilities = this.capabilityService.getCapabilities
 | 
			
		||||
                    .apply(this.capabilityService, arguments),
 | 
			
		||||
                persistenceCapability = capabilities.persistence;
 | 
			
		||||
 | 
			
		||||
            capabilities.persistence = function (domainObject) {
 | 
			
		||||
                var original =
 | 
			
		||||
                    (typeof persistenceCapability === 'function')
 | 
			
		||||
                        ? persistenceCapability(domainObject)
 | 
			
		||||
                        : persistenceCapability;
 | 
			
		||||
 | 
			
		||||
                return new TransactionalPersistenceCapability(
 | 
			
		||||
                    self.$q,
 | 
			
		||||
                    self.transactionService,
 | 
			
		||||
                    original,
 | 
			
		||||
                    domainObject
 | 
			
		||||
                );
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            return capabilities;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return TransactionCapabilityDecorator;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,91 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wraps persistence capability to enable transactions. Transactions
 | 
			
		||||
         * will cause persist calls not to be invoked immediately, but
 | 
			
		||||
         * rather queued until [EditorCapability.save()]{@link EditorCapability#save}
 | 
			
		||||
         * or [EditorCapability.cancel()]{@link EditorCapability#cancel} are
 | 
			
		||||
         * called.
 | 
			
		||||
         * @memberof platform/commonUI/edit/capabilities
 | 
			
		||||
         * @param $q
 | 
			
		||||
         * @param transactionManager
 | 
			
		||||
         * @param persistenceCapability
 | 
			
		||||
         * @param domainObject
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function TransactionalPersistenceCapability(
 | 
			
		||||
            $q,
 | 
			
		||||
            transactionManager,
 | 
			
		||||
            persistenceCapability,
 | 
			
		||||
            domainObject
 | 
			
		||||
        ) {
 | 
			
		||||
            this.transactionManager = transactionManager;
 | 
			
		||||
            this.persistenceCapability = persistenceCapability;
 | 
			
		||||
            this.domainObject = domainObject;
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The wrapped persist function. If a transaction is active, persist
 | 
			
		||||
         * will be queued until the transaction is committed or cancelled.
 | 
			
		||||
         * @returns {*}
 | 
			
		||||
         */
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.persist = function () {
 | 
			
		||||
            var wrappedPersistence = this.persistenceCapability;
 | 
			
		||||
 | 
			
		||||
            if (this.transactionManager.isActive()) {
 | 
			
		||||
                this.transactionManager.addToTransaction(
 | 
			
		||||
                    this.domainObject.getId(),
 | 
			
		||||
                    wrappedPersistence.persist.bind(wrappedPersistence),
 | 
			
		||||
                    wrappedPersistence.refresh.bind(wrappedPersistence)
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                //Need to return a promise from this function
 | 
			
		||||
                return this.$q.when(true);
 | 
			
		||||
            } else {
 | 
			
		||||
                return this.persistenceCapability.persist();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.refresh = function () {
 | 
			
		||||
            this.transactionManager
 | 
			
		||||
                .clearTransactionsFor(this.domainObject.getId());
 | 
			
		||||
 | 
			
		||||
            return this.persistenceCapability.refresh();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.getSpace = function () {
 | 
			
		||||
            return this.persistenceCapability.getSpace();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.persisted = function () {
 | 
			
		||||
            return this.persistenceCapability.persisted();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return TransactionalPersistenceCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,99 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
define([], function () {
 | 
			
		||||
    /**
 | 
			
		||||
     * A Transaction represents a set of changes that are intended to
 | 
			
		||||
     * be kept or discarded as a unit.
 | 
			
		||||
     * @param $log Angular's `$log` service, for logging messages
 | 
			
		||||
     * @constructor
 | 
			
		||||
     * @memberof platform/commonUI/edit/services
 | 
			
		||||
     */
 | 
			
		||||
    function Transaction($log) {
 | 
			
		||||
        this.$log = $log;
 | 
			
		||||
        this.callbacks = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a change to the current transaction, as expressed by functions
 | 
			
		||||
     * to either keep or discard the change.
 | 
			
		||||
     * @param {Function} commit called when the transaction is committed
 | 
			
		||||
     * @param {Function} cancel called when the transaction is cancelled
 | 
			
		||||
     * @returns {Function) a function which may be called to remove this
 | 
			
		||||
     *          pair of callbacks from the transaction
 | 
			
		||||
     */
 | 
			
		||||
    Transaction.prototype.add = function (commit, cancel) {
 | 
			
		||||
        var callback = {
 | 
			
		||||
            commit: commit,
 | 
			
		||||
            cancel: cancel
 | 
			
		||||
        };
 | 
			
		||||
        this.callbacks.push(callback);
 | 
			
		||||
 | 
			
		||||
        return function () {
 | 
			
		||||
            this.callbacks = this.callbacks.filter(function (c) {
 | 
			
		||||
                return c !== callback;
 | 
			
		||||
            });
 | 
			
		||||
        }.bind(this);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of changes in the current transaction.
 | 
			
		||||
     * @returns {number} the size of the current transaction
 | 
			
		||||
     */
 | 
			
		||||
    Transaction.prototype.size = function () {
 | 
			
		||||
        return this.callbacks.length;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Keep all changes associated with this transaction.
 | 
			
		||||
     * @method {platform/commonUI/edit/services.Transaction#commit}
 | 
			
		||||
     * @returns {Promise} a promise which will resolve when all callbacks
 | 
			
		||||
     *          have been handled.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Discard all changes associated with this transaction.
 | 
			
		||||
     * @method {platform/commonUI/edit/services.Transaction#cancel}
 | 
			
		||||
     * @returns {Promise} a promise which will resolve when all callbacks
 | 
			
		||||
     *          have been handled.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    ['commit', 'cancel'].forEach(function (method) {
 | 
			
		||||
        Transaction.prototype[method] = function () {
 | 
			
		||||
            var promises = [];
 | 
			
		||||
            var callback;
 | 
			
		||||
 | 
			
		||||
            while (this.callbacks.length > 0) {
 | 
			
		||||
                callback = this.callbacks.shift();
 | 
			
		||||
                try {
 | 
			
		||||
                    promises.push(callback[method]());
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    this.$log
 | 
			
		||||
                        .error("Error trying to " + method + " transaction.");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Promise.all(promises);
 | 
			
		||||
        };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return Transaction;
 | 
			
		||||
});
 | 
			
		||||
@@ -1,119 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define([], function () {
 | 
			
		||||
    /**
 | 
			
		||||
     * Manages transactions to support the TransactionalPersistenceCapability.
 | 
			
		||||
     * This assumes that all commit/cancel callbacks for a given domain
 | 
			
		||||
     * object are equivalent, and only need to be added once to any active
 | 
			
		||||
     * transaction. Violating this assumption may cause unexpected behavior.
 | 
			
		||||
     * @constructor
 | 
			
		||||
     * @memberof platform/commonUI/edit
 | 
			
		||||
     */
 | 
			
		||||
    function TransactionManager(transactionService) {
 | 
			
		||||
        this.transactionService = transactionService;
 | 
			
		||||
        this.clearTransactionFns = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a transaction is currently active.
 | 
			
		||||
     * @returns {boolean} true if there is a transaction active
 | 
			
		||||
     */
 | 
			
		||||
    TransactionManager.prototype.isActive = function () {
 | 
			
		||||
        return this.transactionService.isActive();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if callbacks associated with this domain object have already
 | 
			
		||||
     * been added to the active transaction.
 | 
			
		||||
     * @private
 | 
			
		||||
     * @param {string} id the identifier of the domain object to check
 | 
			
		||||
     * @returns {boolean} true if callbacks have been added
 | 
			
		||||
     */
 | 
			
		||||
    TransactionManager.prototype.isScheduled = function (id) {
 | 
			
		||||
        return Boolean(this.clearTransactionFns[id]);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add callbacks associated with this domain object to the active
 | 
			
		||||
     * transaction. Both callbacks are expected to return promises that
 | 
			
		||||
     * resolve when their associated behavior is complete.
 | 
			
		||||
     *
 | 
			
		||||
     * If callbacks associated with this domain object have already been
 | 
			
		||||
     * added to the active transaction, this call will be ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {string} id the identifier of the associated domain object
 | 
			
		||||
     * @param {Function} onCommit behavior to invoke when committing transaction
 | 
			
		||||
     * @param {Function} onCancel behavior to invoke when cancelling transaction
 | 
			
		||||
     */
 | 
			
		||||
    TransactionManager.prototype.addToTransaction = function (
 | 
			
		||||
        id,
 | 
			
		||||
        onCommit,
 | 
			
		||||
        onCancel
 | 
			
		||||
    ) {
 | 
			
		||||
        var release = this.releaseClearFn.bind(this, id);
 | 
			
		||||
 | 
			
		||||
        function chain(promiseFn, nextFn) {
 | 
			
		||||
            return function () {
 | 
			
		||||
                return promiseFn().then(nextFn);
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Clear any existing persistence calls for object with given ID. This ensures only the most recent persistence
 | 
			
		||||
         * call is executed. This should prevent stale objects being persisted and overwriting fresh ones.
 | 
			
		||||
         */
 | 
			
		||||
        if (this.isScheduled(id)) {
 | 
			
		||||
            this.clearTransactionsFor(id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.clearTransactionFns[id] =
 | 
			
		||||
            this.transactionService.addToTransaction(
 | 
			
		||||
                chain(onCommit, release),
 | 
			
		||||
                chain(onCancel, release)
 | 
			
		||||
            );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove any callbacks associated with this domain object from the
 | 
			
		||||
     * active transaction.
 | 
			
		||||
     * @param {string} id the identifier for the domain object
 | 
			
		||||
     */
 | 
			
		||||
    TransactionManager.prototype.clearTransactionsFor = function (id) {
 | 
			
		||||
        if (this.isScheduled(id)) {
 | 
			
		||||
            this.clearTransactionFns[id]();
 | 
			
		||||
            this.releaseClearFn(id);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Release the cached "remove from transaction" function that has been
 | 
			
		||||
     * stored in association with this domain object.
 | 
			
		||||
     * @param {string} id the identifier for the domain object
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    TransactionManager.prototype.releaseClearFn = function (id) {
 | 
			
		||||
        delete this.clearTransactionFns[id];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return TransactionManager;
 | 
			
		||||
});
 | 
			
		||||
@@ -1,138 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
define(
 | 
			
		||||
    ['./Transaction', './NestedTransaction'],
 | 
			
		||||
    function (Transaction, NestedTransaction) {
 | 
			
		||||
        /**
 | 
			
		||||
         * Implements an application-wide transaction state. Once a
 | 
			
		||||
         * transaction is started, calls to
 | 
			
		||||
         * [PersistenceCapability.persist()]{@link PersistenceCapability#persist}
 | 
			
		||||
         * will be deferred until a subsequent call to
 | 
			
		||||
         * [TransactionService.commit]{@link TransactionService#commit} is made.
 | 
			
		||||
         *
 | 
			
		||||
         * @memberof platform/commonUI/edit/services
 | 
			
		||||
         * @param $q
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function TransactionService($q, $log, cacheService) {
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
            this.$log = $log;
 | 
			
		||||
            this.cacheService = cacheService;
 | 
			
		||||
            this.transactions = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Starts a transaction. While a transaction is active all calls to
 | 
			
		||||
         * [PersistenceCapability.persist](@link PersistenceCapability#persist)
 | 
			
		||||
         * will be queued until [commit]{@link #commit} or [cancel]{@link
 | 
			
		||||
         * #cancel} are called
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.startTransaction = function () {
 | 
			
		||||
            var transaction = this.isActive()
 | 
			
		||||
                ? new NestedTransaction(this.transactions[0])
 | 
			
		||||
                : new Transaction(this.$log);
 | 
			
		||||
 | 
			
		||||
            this.transactions.push(transaction);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @returns {boolean} If true, indicates that a transaction is in progress
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.isActive = function () {
 | 
			
		||||
            return this.transactions.length > 0;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Adds provided functions to a queue to be called on
 | 
			
		||||
         * [.commit()]{@link #commit} or
 | 
			
		||||
         * [.cancel()]{@link #commit}
 | 
			
		||||
         * @param onCommit A function to call on commit
 | 
			
		||||
         * @param onCancel A function to call on cancel
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.addToTransaction = function (onCommit, onCancel) {
 | 
			
		||||
            if (this.isActive()) {
 | 
			
		||||
                return this.activeTransaction().add(onCommit, onCancel);
 | 
			
		||||
            } else {
 | 
			
		||||
                //Log error because this is a programming error if it occurs.
 | 
			
		||||
                this.$log.error("No transaction in progress");
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get the transaction at the top of the stack.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.activeTransaction = function () {
 | 
			
		||||
            return this.transactions[this.transactions.length - 1];
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * All persist calls deferred since the beginning of the transaction
 | 
			
		||||
         * will be committed.  If this is the last transaction, clears the
 | 
			
		||||
         * cache.
 | 
			
		||||
         *
 | 
			
		||||
         * @returns {Promise} resolved when all persist operations have
 | 
			
		||||
         * completed. Will reject if any commit operations fail
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.commit = function () {
 | 
			
		||||
            var transaction = this.transactions.pop();
 | 
			
		||||
            if (!transaction) {
 | 
			
		||||
                return Promise.reject();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!this.isActive()) {
 | 
			
		||||
                return transaction.commit()
 | 
			
		||||
                    .then(function (r) {
 | 
			
		||||
                        this.cacheService.flush();
 | 
			
		||||
 | 
			
		||||
                        return r;
 | 
			
		||||
                    }.bind(this));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return transaction.commit();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 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 transaction = this.transactions.pop();
 | 
			
		||||
 | 
			
		||||
            return transaction ? transaction.cancel() : Promise.reject();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get the size (the number of commit/cancel callbacks) of
 | 
			
		||||
         * the active transaction.
 | 
			
		||||
         * @returns {number} size of the active transaction
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.size = function () {
 | 
			
		||||
            return this.isActive() ? this.activeTransaction().size() : 0;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return TransactionService;
 | 
			
		||||
    });
 | 
			
		||||
@@ -1,192 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/capabilities/EditorCapability"],
 | 
			
		||||
    function (EditorCapability) {
 | 
			
		||||
 | 
			
		||||
        xdescribe("The editor capability", function () {
 | 
			
		||||
            var mockDomainObject,
 | 
			
		||||
                capabilities,
 | 
			
		||||
                mockParentObject,
 | 
			
		||||
                mockTransactionService,
 | 
			
		||||
                mockStatusCapability,
 | 
			
		||||
                mockParentStatus,
 | 
			
		||||
                mockContextCapability,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            function fastPromise(val) {
 | 
			
		||||
                return {
 | 
			
		||||
                    then: function (callback) {
 | 
			
		||||
                        return callback(val);
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockDomainObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getId", "getModel", "hasCapability", "getCapability", "useCapability"]
 | 
			
		||||
                );
 | 
			
		||||
                mockParentObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getId", "getModel", "hasCapability", "getCapability", "useCapability"]
 | 
			
		||||
                );
 | 
			
		||||
                mockTransactionService = jasmine.createSpyObj(
 | 
			
		||||
                    "transactionService",
 | 
			
		||||
                    [
 | 
			
		||||
                        "startTransaction",
 | 
			
		||||
                        "size",
 | 
			
		||||
                        "commit",
 | 
			
		||||
                        "cancel"
 | 
			
		||||
                    ]
 | 
			
		||||
                );
 | 
			
		||||
                mockTransactionService.commit.and.returnValue(fastPromise());
 | 
			
		||||
                mockTransactionService.cancel.and.returnValue(fastPromise());
 | 
			
		||||
                mockTransactionService.isActive = jasmine.createSpy('isActive');
 | 
			
		||||
 | 
			
		||||
                mockStatusCapability = jasmine.createSpyObj(
 | 
			
		||||
                    "statusCapability",
 | 
			
		||||
                    ["get", "set"]
 | 
			
		||||
                );
 | 
			
		||||
                mockParentStatus = jasmine.createSpyObj(
 | 
			
		||||
                    "statusCapability",
 | 
			
		||||
                    ["get", "set"]
 | 
			
		||||
                );
 | 
			
		||||
                mockContextCapability = jasmine.createSpyObj(
 | 
			
		||||
                    "contextCapability",
 | 
			
		||||
                    ["getParent"]
 | 
			
		||||
                );
 | 
			
		||||
                mockContextCapability.getParent.and.returnValue(mockParentObject);
 | 
			
		||||
 | 
			
		||||
                capabilities = {
 | 
			
		||||
                    context: mockContextCapability,
 | 
			
		||||
                    status: mockStatusCapability
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                mockDomainObject.hasCapability.and.callFake(function (name) {
 | 
			
		||||
                    return capabilities[name] !== undefined;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                mockDomainObject.getCapability.and.callFake(function (name) {
 | 
			
		||||
                    return capabilities[name];
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                mockParentObject.getCapability.and.returnValue(mockParentStatus);
 | 
			
		||||
                mockParentObject.hasCapability.and.returnValue(false);
 | 
			
		||||
 | 
			
		||||
                capability = new EditorCapability(
 | 
			
		||||
                    mockTransactionService,
 | 
			
		||||
                    mockDomainObject
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("starts a transaction when edit is invoked", function () {
 | 
			
		||||
                capability.edit();
 | 
			
		||||
                expect(mockTransactionService.startTransaction).toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("sets editing status on object", function () {
 | 
			
		||||
                capability.edit();
 | 
			
		||||
                expect(mockStatusCapability.set).toHaveBeenCalledWith("editing", true);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("uses editing status to determine editing context root", function () {
 | 
			
		||||
                capability.edit();
 | 
			
		||||
                mockStatusCapability.get.and.returnValue(false);
 | 
			
		||||
                expect(capability.isEditContextRoot()).toBe(false);
 | 
			
		||||
                mockStatusCapability.get.and.returnValue(true);
 | 
			
		||||
                expect(capability.isEditContextRoot()).toBe(true);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("inEditingContext returns true if parent object is being"
 | 
			
		||||
                + " edited", function () {
 | 
			
		||||
                mockStatusCapability.get.and.returnValue(false);
 | 
			
		||||
                mockParentStatus.get.and.returnValue(false);
 | 
			
		||||
                expect(capability.inEditContext()).toBe(false);
 | 
			
		||||
                mockParentStatus.get.and.returnValue(true);
 | 
			
		||||
                expect(capability.inEditContext()).toBe(true);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("save", function () {
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    capability.edit();
 | 
			
		||||
                    capability.save();
 | 
			
		||||
                });
 | 
			
		||||
                it("commits the transaction", function () {
 | 
			
		||||
                    expect(mockTransactionService.commit).toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
                it("begins a new transaction", function () {
 | 
			
		||||
                    expect(mockTransactionService.startTransaction).toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("finish", function () {
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    mockTransactionService.isActive.and.returnValue(true);
 | 
			
		||||
                    capability.edit();
 | 
			
		||||
                    capability.finish();
 | 
			
		||||
                });
 | 
			
		||||
                it("cancels the transaction", function () {
 | 
			
		||||
                    expect(mockTransactionService.cancel).toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
                it("resets the edit state", function () {
 | 
			
		||||
                    expect(mockStatusCapability.set).toHaveBeenCalledWith('editing', false);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("finish", function () {
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    mockTransactionService.isActive.and.returnValue(false);
 | 
			
		||||
                    capability.edit();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("does not cancel transaction when transaction is not active", function () {
 | 
			
		||||
                    capability.finish();
 | 
			
		||||
                    expect(mockTransactionService.cancel).not.toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("returns a promise", function () {
 | 
			
		||||
                    expect(capability.finish() instanceof Promise).toBe(true);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("dirty", function () {
 | 
			
		||||
                var model = {};
 | 
			
		||||
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    mockDomainObject.getModel.and.returnValue(model);
 | 
			
		||||
                    capability.edit();
 | 
			
		||||
                    capability.finish();
 | 
			
		||||
                });
 | 
			
		||||
                it("returns true if the object has been modified since it"
 | 
			
		||||
                    + " was last persisted", function () {
 | 
			
		||||
                    mockTransactionService.size.and.returnValue(0);
 | 
			
		||||
                    expect(capability.dirty()).toBe(false);
 | 
			
		||||
                    mockTransactionService.size.and.returnValue(1);
 | 
			
		||||
                    expect(capability.dirty()).toBe(true);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,54 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [
 | 
			
		||||
        "../../src/capabilities/TransactionalPersistenceCapability",
 | 
			
		||||
        "../../src/capabilities/TransactionCapabilityDecorator"
 | 
			
		||||
    ],
 | 
			
		||||
    function (TransactionalPersistenceCapability, TransactionCapabilityDecorator) {
 | 
			
		||||
 | 
			
		||||
        describe("The transaction capability decorator", function () {
 | 
			
		||||
            var mockQ,
 | 
			
		||||
                mockTransactionService,
 | 
			
		||||
                mockCapabilityService,
 | 
			
		||||
                provider;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockQ = {};
 | 
			
		||||
                mockTransactionService = {};
 | 
			
		||||
                mockCapabilityService = jasmine.createSpyObj("capabilityService", ["getCapabilities"]);
 | 
			
		||||
                mockCapabilityService.getCapabilities.and.returnValue({
 | 
			
		||||
                    persistence: function () {}
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                provider = new TransactionCapabilityDecorator(mockQ, mockTransactionService, mockCapabilityService);
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
            it("decorates the persistence capability", function () {
 | 
			
		||||
                var capabilities = provider.getCapabilities();
 | 
			
		||||
                expect(capabilities.persistence({}) instanceof TransactionalPersistenceCapability).toBe(true);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,111 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [
 | 
			
		||||
        "../../src/capabilities/TransactionalPersistenceCapability"
 | 
			
		||||
    ],
 | 
			
		||||
    function (TransactionalPersistenceCapability) {
 | 
			
		||||
 | 
			
		||||
        function fastPromise(val) {
 | 
			
		||||
            return {
 | 
			
		||||
                then: function (callback) {
 | 
			
		||||
                    return callback(val);
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        describe("The transactional persistence decorator", function () {
 | 
			
		||||
            var mockQ,
 | 
			
		||||
                mockTransactionManager,
 | 
			
		||||
                mockPersistence,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                testId,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                testId = "test-id";
 | 
			
		||||
 | 
			
		||||
                mockQ = jasmine.createSpyObj("$q", ["when"]);
 | 
			
		||||
                mockQ.when.and.callFake(function (val) {
 | 
			
		||||
                    return fastPromise(val);
 | 
			
		||||
                });
 | 
			
		||||
                mockTransactionManager = jasmine.createSpyObj(
 | 
			
		||||
                    "transactionService",
 | 
			
		||||
                    ["isActive", "addToTransaction", "clearTransactionsFor"]
 | 
			
		||||
                );
 | 
			
		||||
                mockPersistence = jasmine.createSpyObj(
 | 
			
		||||
                    "persistenceCapability",
 | 
			
		||||
                    ["persist", "refresh", "getSpace"]
 | 
			
		||||
                );
 | 
			
		||||
                mockPersistence.persist.and.returnValue(fastPromise());
 | 
			
		||||
                mockPersistence.refresh.and.returnValue(fastPromise());
 | 
			
		||||
 | 
			
		||||
                mockDomainObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getModel", "getId"]
 | 
			
		||||
                );
 | 
			
		||||
                mockDomainObject.getModel.and.returnValue({persisted: 1});
 | 
			
		||||
                mockDomainObject.getId.and.returnValue(testId);
 | 
			
		||||
 | 
			
		||||
                capability = new TransactionalPersistenceCapability(
 | 
			
		||||
                    mockQ,
 | 
			
		||||
                    mockTransactionManager,
 | 
			
		||||
                    mockPersistence,
 | 
			
		||||
                    mockDomainObject
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("if no transaction is active, passes through to persistence"
 | 
			
		||||
                + " provider", function () {
 | 
			
		||||
                mockTransactionManager.isActive.and.returnValue(false);
 | 
			
		||||
                capability.persist();
 | 
			
		||||
                expect(mockPersistence.persist).toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("if transaction is active, persist and cancel calls are"
 | 
			
		||||
                + " queued", function () {
 | 
			
		||||
                mockTransactionManager.isActive.and.returnValue(true);
 | 
			
		||||
                capability.persist();
 | 
			
		||||
                expect(mockTransactionManager.addToTransaction).toHaveBeenCalled();
 | 
			
		||||
                mockTransactionManager.addToTransaction.calls.mostRecent().args[1]();
 | 
			
		||||
                expect(mockPersistence.persist).toHaveBeenCalled();
 | 
			
		||||
                mockTransactionManager.addToTransaction.calls.mostRecent().args[2]();
 | 
			
		||||
                expect(mockPersistence.refresh).toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("wraps getSpace", function () {
 | 
			
		||||
                mockPersistence.getSpace.and.returnValue('foo');
 | 
			
		||||
                expect(capability.getSpace()).toEqual('foo');
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("clears transactions and delegates refresh calls", function () {
 | 
			
		||||
                capability.refresh();
 | 
			
		||||
                expect(mockTransactionManager.clearTransactionsFor)
 | 
			
		||||
                    .toHaveBeenCalledWith(testId);
 | 
			
		||||
                expect(mockPersistence.refresh)
 | 
			
		||||
                    .toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,75 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(["../../src/services/NestedTransaction"], function (NestedTransaction) {
 | 
			
		||||
    var TRANSACTION_METHODS = ['add', 'commit', 'cancel', 'size'];
 | 
			
		||||
 | 
			
		||||
    describe("A NestedTransaction", function () {
 | 
			
		||||
        var mockTransaction,
 | 
			
		||||
            nestedTransaction;
 | 
			
		||||
 | 
			
		||||
        beforeEach(function () {
 | 
			
		||||
            mockTransaction =
 | 
			
		||||
                jasmine.createSpyObj('transaction', TRANSACTION_METHODS);
 | 
			
		||||
            nestedTransaction = new NestedTransaction(mockTransaction);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it("exposes a Transaction's interface", function () {
 | 
			
		||||
            TRANSACTION_METHODS.forEach(function (method) {
 | 
			
		||||
                expect(nestedTransaction[method])
 | 
			
		||||
                    .toEqual(jasmine.any(Function));
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        describe("when callbacks are added", function () {
 | 
			
		||||
            var mockCommit,
 | 
			
		||||
                mockCancel;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockCommit = jasmine.createSpy('commit');
 | 
			
		||||
                mockCancel = jasmine.createSpy('cancel');
 | 
			
		||||
                nestedTransaction.add(mockCommit, mockCancel);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not interact with its parent transaction", function () {
 | 
			
		||||
                TRANSACTION_METHODS.forEach(function (method) {
 | 
			
		||||
                    expect(mockTransaction[method])
 | 
			
		||||
                        .not.toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("and the transaction is committed", function () {
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    nestedTransaction.commit();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("adds to its parent transaction", function () {
 | 
			
		||||
                    expect(mockTransaction.add).toHaveBeenCalledWith(
 | 
			
		||||
                        jasmine.any(Function),
 | 
			
		||||
                        jasmine.any(Function)
 | 
			
		||||
                    );
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -1,141 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/services/TransactionManager"],
 | 
			
		||||
    function (TransactionManager) {
 | 
			
		||||
        describe("TransactionManager", function () {
 | 
			
		||||
            var mockTransactionService,
 | 
			
		||||
                testId,
 | 
			
		||||
                mockOnCommit,
 | 
			
		||||
                mockOnCancel,
 | 
			
		||||
                mockRemoves,
 | 
			
		||||
                mockPromise,
 | 
			
		||||
                manager;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockRemoves = [];
 | 
			
		||||
                mockTransactionService = jasmine.createSpyObj(
 | 
			
		||||
                    "transactionService",
 | 
			
		||||
                    ["addToTransaction", "isActive"]
 | 
			
		||||
                );
 | 
			
		||||
                mockOnCommit = jasmine.createSpy('commit');
 | 
			
		||||
                mockOnCancel = jasmine.createSpy('cancel');
 | 
			
		||||
                testId = 'test-id';
 | 
			
		||||
                mockPromise = jasmine.createSpyObj('promise', ['then']);
 | 
			
		||||
 | 
			
		||||
                mockOnCommit.and.returnValue(mockPromise);
 | 
			
		||||
                mockOnCancel.and.returnValue(mockPromise);
 | 
			
		||||
 | 
			
		||||
                mockTransactionService.addToTransaction.and.callFake(function () {
 | 
			
		||||
                    var mockRemove =
 | 
			
		||||
                        jasmine.createSpy('remove-' + mockRemoves.length);
 | 
			
		||||
                    mockRemoves.push(mockRemove);
 | 
			
		||||
 | 
			
		||||
                    return mockRemove;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                manager = new TransactionManager(mockTransactionService);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("delegates isActive calls", function () {
 | 
			
		||||
                [false, true].forEach(function (state) {
 | 
			
		||||
                    mockTransactionService.isActive.and.returnValue(state);
 | 
			
		||||
                    expect(manager.isActive()).toBe(state);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("when addToTransaction is called", function () {
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    manager.addToTransaction(
 | 
			
		||||
                        testId,
 | 
			
		||||
                        mockOnCommit,
 | 
			
		||||
                        mockOnCancel
 | 
			
		||||
                    );
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("adds callbacks to the active transaction", function () {
 | 
			
		||||
                    expect(mockTransactionService.addToTransaction)
 | 
			
		||||
                        .toHaveBeenCalledWith(
 | 
			
		||||
                            jasmine.any(Function),
 | 
			
		||||
                            jasmine.any(Function)
 | 
			
		||||
                        );
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("invokes passed-in callbacks from its own callbacks", function () {
 | 
			
		||||
                    expect(mockOnCommit).not.toHaveBeenCalled();
 | 
			
		||||
                    mockTransactionService.addToTransaction
 | 
			
		||||
                        .calls.mostRecent().args[0]();
 | 
			
		||||
                    expect(mockOnCommit).toHaveBeenCalled();
 | 
			
		||||
 | 
			
		||||
                    expect(mockOnCancel).not.toHaveBeenCalled();
 | 
			
		||||
                    mockTransactionService.addToTransaction
 | 
			
		||||
                        .calls.mostRecent().args[1]();
 | 
			
		||||
                    expect(mockOnCancel).toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                describe("Adds callbacks to transaction", function () {
 | 
			
		||||
                    beforeEach(function () {
 | 
			
		||||
                        spyOn(manager, 'clearTransactionsFor');
 | 
			
		||||
                        manager.clearTransactionsFor.and.callThrough();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("and clears pending calls if same object", function () {
 | 
			
		||||
                        manager.addToTransaction(
 | 
			
		||||
                            testId,
 | 
			
		||||
                            jasmine.createSpy(),
 | 
			
		||||
                            jasmine.createSpy()
 | 
			
		||||
                        );
 | 
			
		||||
                        expect(manager.clearTransactionsFor).toHaveBeenCalledWith(testId);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("and does not clear pending calls if different object", function () {
 | 
			
		||||
                        manager.addToTransaction(
 | 
			
		||||
                            'other-id',
 | 
			
		||||
                            jasmine.createSpy(),
 | 
			
		||||
                            jasmine.createSpy()
 | 
			
		||||
                        );
 | 
			
		||||
                        expect(manager.clearTransactionsFor).not.toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    afterEach(function () {
 | 
			
		||||
                        expect(mockTransactionService.addToTransaction.calls.count()).toEqual(2);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("does not remove callbacks from the transaction", function () {
 | 
			
		||||
                    expect(mockRemoves[0]).not.toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                describe("and clearTransactionsFor is subsequently called", function () {
 | 
			
		||||
                    beforeEach(function () {
 | 
			
		||||
                        manager.clearTransactionsFor(testId);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("removes callbacks from the transaction", function () {
 | 
			
		||||
                        expect(mockRemoves[0]).toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,139 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/services/TransactionService"],
 | 
			
		||||
    function (TransactionService) {
 | 
			
		||||
 | 
			
		||||
        describe("The Transaction Service", function () {
 | 
			
		||||
            var mockQ,
 | 
			
		||||
                mockLog,
 | 
			
		||||
                mockCacheService,
 | 
			
		||||
                transactionService;
 | 
			
		||||
 | 
			
		||||
            function fastPromise(val) {
 | 
			
		||||
                return {
 | 
			
		||||
                    then: function (callback) {
 | 
			
		||||
                        return fastPromise(callback(val));
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockQ = jasmine.createSpyObj("$q", ["all"]);
 | 
			
		||||
                mockCacheService = jasmine.createSpyObj("cacheService", ["flush"]);
 | 
			
		||||
                mockQ.all.and.returnValue(fastPromise());
 | 
			
		||||
                mockLog = jasmine.createSpyObj("$log", ["error"]);
 | 
			
		||||
                transactionService = new TransactionService(mockQ, mockLog, mockCacheService);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("isActive returns true if a transaction is in progress", function () {
 | 
			
		||||
                expect(transactionService.isActive()).toBe(false);
 | 
			
		||||
                transactionService.startTransaction();
 | 
			
		||||
                expect(transactionService.isActive()).toBe(true);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("addToTransaction queues onCommit and onCancel functions", function () {
 | 
			
		||||
                var onCommit = jasmine.createSpy('onCommit'),
 | 
			
		||||
                    onCancel = jasmine.createSpy('onCancel');
 | 
			
		||||
 | 
			
		||||
                transactionService.startTransaction();
 | 
			
		||||
                transactionService.addToTransaction(onCommit, onCancel);
 | 
			
		||||
                expect(transactionService.size()).toBe(1);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("size function returns size of commit and cancel queues", function () {
 | 
			
		||||
                var onCommit = jasmine.createSpy('onCommit'),
 | 
			
		||||
                    onCancel = jasmine.createSpy('onCancel');
 | 
			
		||||
 | 
			
		||||
                transactionService.startTransaction();
 | 
			
		||||
                transactionService.addToTransaction(onCommit, onCancel);
 | 
			
		||||
                transactionService.addToTransaction(onCommit, onCancel);
 | 
			
		||||
                transactionService.addToTransaction(onCommit, onCancel);
 | 
			
		||||
                expect(transactionService.size()).toBe(3);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("commit", function () {
 | 
			
		||||
                var onCommits;
 | 
			
		||||
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    onCommits = [0, 1, 2].map(function (val) {
 | 
			
		||||
                        return jasmine.createSpy("onCommit" + val);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    transactionService.startTransaction();
 | 
			
		||||
                    onCommits.forEach(transactionService.addToTransaction.bind(transactionService));
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("commit calls all queued commit functions", function () {
 | 
			
		||||
                    expect(transactionService.size()).toBe(3);
 | 
			
		||||
 | 
			
		||||
                    return transactionService.commit().then(() => {
 | 
			
		||||
                        onCommits.forEach(function (spy) {
 | 
			
		||||
                            expect(spy).toHaveBeenCalled();
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("commit resets active state and clears queues", function () {
 | 
			
		||||
                    return transactionService.commit().then(() => {
 | 
			
		||||
                        expect(transactionService.isActive()).toBe(false);
 | 
			
		||||
                        expect(transactionService.size()).toBe(0);
 | 
			
		||||
                        expect(transactionService.size()).toBe(0);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("cancel", function () {
 | 
			
		||||
                var onCancels;
 | 
			
		||||
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    onCancels = [0, 1, 2].map(function (val) {
 | 
			
		||||
                        return jasmine.createSpy("onCancel" + val);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    transactionService.startTransaction();
 | 
			
		||||
                    onCancels.forEach(function (onCancel) {
 | 
			
		||||
                        transactionService.addToTransaction(undefined, onCancel);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("cancel calls all queued cancel functions", function () {
 | 
			
		||||
                    expect(transactionService.size()).toBe(3);
 | 
			
		||||
                    transactionService.cancel();
 | 
			
		||||
                    onCancels.forEach(function (spy) {
 | 
			
		||||
                        expect(spy).toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("cancel resets active state and clears queues", function () {
 | 
			
		||||
                    transactionService.cancel();
 | 
			
		||||
                    expect(transactionService.isActive()).toBe(false);
 | 
			
		||||
                    expect(transactionService.size()).toBe(0);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,109 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/services/Transaction"],
 | 
			
		||||
    function (Transaction) {
 | 
			
		||||
 | 
			
		||||
        describe("A Transaction", function () {
 | 
			
		||||
            var mockLog,
 | 
			
		||||
                transaction;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockLog = jasmine.createSpyObj(
 | 
			
		||||
                    '$log',
 | 
			
		||||
                    ['warn', 'info', 'error', 'debug']
 | 
			
		||||
                );
 | 
			
		||||
                transaction = new Transaction(mockLog);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("initially has a size of zero", function () {
 | 
			
		||||
                expect(transaction.size()).toEqual(0);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            describe("when callbacks are added", function () {
 | 
			
		||||
                var mockCommit,
 | 
			
		||||
                    mockCancel,
 | 
			
		||||
                    remove;
 | 
			
		||||
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    mockCommit = jasmine.createSpy('commit');
 | 
			
		||||
                    mockCancel = jasmine.createSpy('cancel');
 | 
			
		||||
                    remove = transaction.add(mockCommit, mockCancel);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("reports a new size", function () {
 | 
			
		||||
                    expect(transaction.size()).toEqual(1);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("returns a function to remove those callbacks", function () {
 | 
			
		||||
                    expect(remove).toEqual(jasmine.any(Function));
 | 
			
		||||
                    remove();
 | 
			
		||||
                    expect(transaction.size()).toEqual(0);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                describe("and the transaction is committed", function () {
 | 
			
		||||
                    beforeEach(function () {
 | 
			
		||||
                        transaction.commit();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("triggers the commit callback", function () {
 | 
			
		||||
                        expect(mockCommit).toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("does not trigger the cancel callback", function () {
 | 
			
		||||
                        expect(mockCancel).not.toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                describe("and the transaction is cancelled", function () {
 | 
			
		||||
                    beforeEach(function () {
 | 
			
		||||
                        transaction.cancel();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("triggers the cancel callback", function () {
 | 
			
		||||
                        expect(mockCancel).toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("does not trigger the commit callback", function () {
 | 
			
		||||
                        expect(mockCommit).not.toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                describe("and an exception is encountered during commit", function () {
 | 
			
		||||
                    beforeEach(function () {
 | 
			
		||||
                        mockCommit.and.callFake(function () {
 | 
			
		||||
                            throw new Error("test error");
 | 
			
		||||
                        });
 | 
			
		||||
                        transaction.commit();
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    it("logs an error", function () {
 | 
			
		||||
                        expect(mockLog.error).toHaveBeenCalled();
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@@ -45,7 +45,6 @@ define([
 | 
			
		||||
    "./src/capabilities/MutationCapability",
 | 
			
		||||
    "./src/capabilities/DelegationCapability",
 | 
			
		||||
    "./src/capabilities/InstantiationCapability",
 | 
			
		||||
    "./src/runs/TransactingMutationListener",
 | 
			
		||||
    "./src/services/Now",
 | 
			
		||||
    "./src/services/Throttle",
 | 
			
		||||
    "./src/services/Topic",
 | 
			
		||||
@@ -75,7 +74,6 @@ define([
 | 
			
		||||
    MutationCapability,
 | 
			
		||||
    DelegationCapability,
 | 
			
		||||
    InstantiationCapability,
 | 
			
		||||
    TransactingMutationListener,
 | 
			
		||||
    Now,
 | 
			
		||||
    Throttle,
 | 
			
		||||
    Topic,
 | 
			
		||||
@@ -363,12 +361,6 @@ define([
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "runs": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "implementation": TransactingMutationListener,
 | 
			
		||||
                        "depends": ["topic", "transactionService", "cacheService"]
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "constants": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "key": "PERSISTENCE_SPACE",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,55 +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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define([], function () {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Listens for mutation on domain objects and triggers persistence when
 | 
			
		||||
     * it occurs.
 | 
			
		||||
     * @param {Topic} topic the `topic` service; used to listen for mutation
 | 
			
		||||
     * @memberof platform/core
 | 
			
		||||
     */
 | 
			
		||||
    function TransactingMutationListener(
 | 
			
		||||
        topic,
 | 
			
		||||
        transactionService,
 | 
			
		||||
        cacheService
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        function hasChanged(domainObject) {
 | 
			
		||||
            var model = domainObject.getModel();
 | 
			
		||||
 | 
			
		||||
            return model.persisted === undefined || model.modified > model.persisted;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var mutationTopic = topic('mutation');
 | 
			
		||||
        mutationTopic.listen(function (domainObject) {
 | 
			
		||||
            var persistence = domainObject.getCapability('persistence');
 | 
			
		||||
            cacheService.put(domainObject.getId(), domainObject.getModel());
 | 
			
		||||
 | 
			
		||||
            if (hasChanged(domainObject)) {
 | 
			
		||||
                persistence.persist();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TransactingMutationListener;
 | 
			
		||||
});
 | 
			
		||||
@@ -1,112 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2021, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT 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 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/runs/TransactingMutationListener"],
 | 
			
		||||
    function (TransactingMutationListener) {
 | 
			
		||||
 | 
			
		||||
        describe("TransactingMutationListener", function () {
 | 
			
		||||
            var mockTopic,
 | 
			
		||||
                mockMutationTopic,
 | 
			
		||||
                mockCacheService,
 | 
			
		||||
                mockTransactionService,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockModel,
 | 
			
		||||
                mockPersistence;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockTopic = jasmine.createSpy('topic');
 | 
			
		||||
                mockMutationTopic =
 | 
			
		||||
                    jasmine.createSpyObj('mutation', ['listen']);
 | 
			
		||||
                mockCacheService =
 | 
			
		||||
                    jasmine.createSpyObj('cacheService', [
 | 
			
		||||
                        'put'
 | 
			
		||||
                    ]);
 | 
			
		||||
                mockTransactionService =
 | 
			
		||||
                    jasmine.createSpyObj('transactionService', [
 | 
			
		||||
                        'isActive',
 | 
			
		||||
                        'startTransaction',
 | 
			
		||||
                        'commit'
 | 
			
		||||
                    ]);
 | 
			
		||||
                mockDomainObject = jasmine.createSpyObj(
 | 
			
		||||
                    'domainObject',
 | 
			
		||||
                    ['getId', 'getCapability', 'getModel']
 | 
			
		||||
                );
 | 
			
		||||
                mockPersistence = jasmine.createSpyObj(
 | 
			
		||||
                    'persistence',
 | 
			
		||||
                    ['persist', 'refresh', 'persisted']
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                mockTopic.and.callFake(function (t) {
 | 
			
		||||
                    expect(t).toBe('mutation');
 | 
			
		||||
 | 
			
		||||
                    return mockMutationTopic;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                mockDomainObject.getId.and.returnValue('mockId');
 | 
			
		||||
                mockDomainObject.getCapability.and.callFake(function (c) {
 | 
			
		||||
                    expect(c).toBe('persistence');
 | 
			
		||||
 | 
			
		||||
                    return mockPersistence;
 | 
			
		||||
                });
 | 
			
		||||
                mockModel = {};
 | 
			
		||||
                mockDomainObject.getModel.and.returnValue(mockModel);
 | 
			
		||||
 | 
			
		||||
                mockPersistence.persisted.and.returnValue(true);
 | 
			
		||||
 | 
			
		||||
                return new TransactingMutationListener(
 | 
			
		||||
                    mockTopic,
 | 
			
		||||
                    mockTransactionService,
 | 
			
		||||
                    mockCacheService
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("listens for mutation", function () {
 | 
			
		||||
                expect(mockMutationTopic.listen)
 | 
			
		||||
                    .toHaveBeenCalledWith(jasmine.any(Function));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("calls persist if the model has changed", function () {
 | 
			
		||||
                mockModel.persisted = Date.now();
 | 
			
		||||
 | 
			
		||||
                //Mark the model dirty by setting the mutated date later than the last persisted date.
 | 
			
		||||
                mockModel.modified = mockModel.persisted + 1;
 | 
			
		||||
 | 
			
		||||
                mockMutationTopic.listen.calls.mostRecent()
 | 
			
		||||
                    .args[0](mockDomainObject);
 | 
			
		||||
 | 
			
		||||
                expect(mockPersistence.persist).toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not call persist if the model has not changed", function () {
 | 
			
		||||
                mockModel.persisted = Date.now();
 | 
			
		||||
 | 
			
		||||
                mockModel.modified = mockModel.persisted;
 | 
			
		||||
 | 
			
		||||
                mockMutationTopic.listen.calls.mostRecent()
 | 
			
		||||
                    .args[0](mockDomainObject);
 | 
			
		||||
 | 
			
		||||
                expect(mockPersistence.persist).not.toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -34,7 +34,6 @@ export default class Editor extends EventEmitter {
 | 
			
		||||
     * Initiate an editing session. This will start a transaction during
 | 
			
		||||
     * which any persist operations will be deferred until either save()
 | 
			
		||||
     * or finish() are called.
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    edit() {
 | 
			
		||||
        if (this.editing === true) {
 | 
			
		||||
@@ -42,8 +41,8 @@ export default class Editor extends EventEmitter {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.editing = true;
 | 
			
		||||
        this.getTransactionService().startTransaction();
 | 
			
		||||
        this.emit('isEditing', true);
 | 
			
		||||
        this.openmct.objects.startTransaction();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -56,41 +55,24 @@ export default class Editor extends EventEmitter {
 | 
			
		||||
    /**
 | 
			
		||||
     * Save any unsaved changes from this editing session. This will
 | 
			
		||||
     * end the current transaction.
 | 
			
		||||
     *
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    save() {
 | 
			
		||||
        return this.getTransactionService().commit().then((result) => {
 | 
			
		||||
            this.editing = false;
 | 
			
		||||
            this.emit('isEditing', false);
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }).catch((error) => {
 | 
			
		||||
            throw error;
 | 
			
		||||
        });
 | 
			
		||||
        return this.openmct.objects.CommitAllTransactions()
 | 
			
		||||
            .then(() => {
 | 
			
		||||
                this.editing = false;
 | 
			
		||||
                this.emit('isEditing', false);
 | 
			
		||||
            }).catch(error => {
 | 
			
		||||
                throw error;
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * End the currently active transaction and discard unsaved changes.
 | 
			
		||||
     *
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    cancel() {
 | 
			
		||||
        let cancelPromise = this.getTransactionService().cancel();
 | 
			
		||||
        this.editing = false;
 | 
			
		||||
        this.emit('isEditing', false);
 | 
			
		||||
 | 
			
		||||
        return cancelPromise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    getTransactionService() {
 | 
			
		||||
        if (!this.transactionService) {
 | 
			
		||||
            this.transactionService = this.openmct.$injector.get('transactionService');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this.transactionService;
 | 
			
		||||
        return this.openmct.objects.CancelAllTransactions();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								src/api/objects/ConflictError.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/api/objects/ConflictError.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
export default class ConflictError extends Error {
 | 
			
		||||
}
 | 
			
		||||
@@ -26,6 +26,8 @@ import RootRegistry from './RootRegistry';
 | 
			
		||||
import RootObjectProvider from './RootObjectProvider';
 | 
			
		||||
import EventEmitter from 'EventEmitter';
 | 
			
		||||
import InterceptorRegistry from './InterceptorRegistry';
 | 
			
		||||
import TransactionManager from './TransactionManager';
 | 
			
		||||
import ConflictError from './ConflictError';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utilities for loading, saving, and manipulating domain objects.
 | 
			
		||||
@@ -34,12 +36,14 @@ import InterceptorRegistry from './InterceptorRegistry';
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function ObjectAPI(typeRegistry, openmct) {
 | 
			
		||||
    this.openmct = openmct;
 | 
			
		||||
 | 
			
		||||
    this.typeRegistry = typeRegistry;
 | 
			
		||||
    this.eventEmitter = new EventEmitter();
 | 
			
		||||
    this.providers = {};
 | 
			
		||||
    this.rootRegistry = new RootRegistry();
 | 
			
		||||
    this.injectIdentifierService = function () {
 | 
			
		||||
        this.identifierService = openmct.$injector.get("identifierService");
 | 
			
		||||
        this.identifierService = this.openmct.$injector.get("identifierService");
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    this.rootProvider = new RootObjectProvider(this.rootRegistry);
 | 
			
		||||
@@ -47,6 +51,10 @@ function ObjectAPI(typeRegistry, openmct) {
 | 
			
		||||
    this.interceptorRegistry = new InterceptorRegistry();
 | 
			
		||||
 | 
			
		||||
    this.SYNCHRONIZED_OBJECT_TYPES = ['notebook', 'plan'];
 | 
			
		||||
 | 
			
		||||
    this.errors = {
 | 
			
		||||
        Conflict: ConflictError
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -312,6 +320,27 @@ ObjectAPI.prototype.save = function (domainObject) {
 | 
			
		||||
    return result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * After entering into edit mode, creates a new instance of TransactionManager to keep track of changes in Objects
 | 
			
		||||
 */
 | 
			
		||||
ObjectAPI.prototype.startTransaction = function () {
 | 
			
		||||
    this.transactionManager = new TransactionManager();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * When in edit mode, after save action commit/persists all stored transactions
 | 
			
		||||
 */
 | 
			
		||||
ObjectAPI.prototype.CommitAllTransactions = function () {
 | 
			
		||||
    return this.transactionManager.CommitAllTransactions(this.save.bind(this));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * When in edit mode, after cancel action discard all stored transactions
 | 
			
		||||
 */
 | 
			
		||||
ObjectAPI.prototype.CancelAllTransactions = function () {
 | 
			
		||||
    return this.transactionManager.CancelAllTransactions();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a root-level object.
 | 
			
		||||
 * @param {module:openmct.ObjectAPI~Identifier|function} an array of
 | 
			
		||||
@@ -401,6 +430,12 @@ ObjectAPI.prototype.mutate = function (domainObject, path, value) {
 | 
			
		||||
        //Destroy temporary mutable object
 | 
			
		||||
        this.destroyMutable(mutableDomainObject);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.transactionManager && this.openmct.editor.isEditing()) {
 | 
			
		||||
        this.transactionManager.addTransaction(domainObject);
 | 
			
		||||
    } else {
 | 
			
		||||
        this.save(domainObject);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,10 @@ describe("The Object API", () => {
 | 
			
		||||
 | 
			
		||||
        openmct.$injector.get.and.returnValue(mockIdentifierService);
 | 
			
		||||
        objectAPI = new ObjectAPI(typeRegistry, openmct);
 | 
			
		||||
 | 
			
		||||
        openmct.editor = {};
 | 
			
		||||
        openmct.editor.isEditing = () => false;
 | 
			
		||||
 | 
			
		||||
        mockDomainObject = {
 | 
			
		||||
            identifier: {
 | 
			
		||||
                namespace: TEST_NAMESPACE,
 | 
			
		||||
 
 | 
			
		||||
@@ -19,31 +19,36 @@
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
define(['./Transaction'], function (Transaction) {
 | 
			
		||||
    /**
 | 
			
		||||
     * A nested transaction is a transaction which takes place in the context
 | 
			
		||||
     * of a larger parent transaction. It becomes part of the parent
 | 
			
		||||
     * transaction when (and only when) committed.
 | 
			
		||||
     * @param parent
 | 
			
		||||
     * @constructor
 | 
			
		||||
     * @extends {platform/commonUI/edit/services.Transaction}
 | 
			
		||||
     * @memberof platform/commonUI/edit/services
 | 
			
		||||
     */
 | 
			
		||||
    function NestedTransaction(parent) {
 | 
			
		||||
        this.parent = parent;
 | 
			
		||||
        Transaction.call(this, parent.$log);
 | 
			
		||||
 | 
			
		||||
export default class TransactionManager {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.transactions = new Set();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NestedTransaction.prototype = Object.create(Transaction.prototype);
 | 
			
		||||
    addTransaction(object) {
 | 
			
		||||
        this.transactions.add(object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NestedTransaction.prototype.commit = function () {
 | 
			
		||||
        this.parent.add(
 | 
			
		||||
            Transaction.prototype.commit.bind(this),
 | 
			
		||||
            Transaction.prototype.cancel.bind(this)
 | 
			
		||||
        );
 | 
			
		||||
    CancelAllTransactions() {
 | 
			
		||||
        return this.clearTransactions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
    };
 | 
			
		||||
    CommitAllTransactions(save) {
 | 
			
		||||
        const promisesArray = [];
 | 
			
		||||
        this.transactions.forEach(o => {
 | 
			
		||||
            promisesArray.push(save(o));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    return NestedTransaction;
 | 
			
		||||
});
 | 
			
		||||
        this.clearTransactions();
 | 
			
		||||
 | 
			
		||||
        return Promise.all(promisesArray);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clearTransactions() {
 | 
			
		||||
        this.transactions = new Set();
 | 
			
		||||
        // TODO:
 | 
			
		||||
        // call `this.opemct.objects.refresh()`
 | 
			
		||||
 | 
			
		||||
        return Promise.resolve();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -592,13 +592,25 @@ export default {
 | 
			
		||||
 | 
			
		||||
            return section.id;
 | 
			
		||||
        },
 | 
			
		||||
        newEntry(embed = null) {
 | 
			
		||||
        async newEntry(embed = null) {
 | 
			
		||||
            let transaction = this.openmct.objects.startTransaction();
 | 
			
		||||
 | 
			
		||||
            this.resetSearch();
 | 
			
		||||
            const notebookStorage = this.createNotebookStorageObject();
 | 
			
		||||
            this.updateDefaultNotebook(notebookStorage);
 | 
			
		||||
            const id = addNotebookEntry(this.openmct, this.domainObject, notebookStorage, embed);
 | 
			
		||||
            this.focusEntryId = id;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                await transaction.CommitAllTransactions();
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                if (error instanceof this.openmct.objects.errors.Conflict) {
 | 
			
		||||
                    transaction.CancelAllTransactions().then(this.newEntry);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        orientationChange() {
 | 
			
		||||
            this.formatSidebar();
 | 
			
		||||
        },
 | 
			
		||||
 
 | 
			
		||||
@@ -148,10 +148,14 @@ describe("Notebook plugin:", () => {
 | 
			
		||||
                'observe'
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
            openmct.editor = {};
 | 
			
		||||
            openmct.editor.isEditing = () => false;
 | 
			
		||||
 | 
			
		||||
            const applicableViews = openmct.objectViews.get(notebookViewObject, [notebookViewObject]);
 | 
			
		||||
            notebookViewProvider = applicableViews.find(viewProvider => viewProvider.key === 'notebook-vue');
 | 
			
		||||
 | 
			
		||||
            testObjectProvider.get.and.returnValue(Promise.resolve(notebookViewObject));
 | 
			
		||||
            testObjectProvider.create.and.returnValue(Promise.resolve(notebookViewObject));
 | 
			
		||||
            openmct.objects.addProvider('test-namespace', testObjectProvider);
 | 
			
		||||
            testObjectProvider.observe.and.returnValue(() => {});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,7 @@ const notebookDomainObject = {
 | 
			
		||||
        namespace: ''
 | 
			
		||||
    },
 | 
			
		||||
    type: 'notebook',
 | 
			
		||||
    name: 'Test Notebook',
 | 
			
		||||
    configuration: {
 | 
			
		||||
        defaultSort: 'oldest',
 | 
			
		||||
        entries: notebookEntries,
 | 
			
		||||
@@ -118,6 +119,12 @@ describe('Notebook Entries:', () => {
 | 
			
		||||
            'create',
 | 
			
		||||
            'update'
 | 
			
		||||
        ]));
 | 
			
		||||
        openmct.editor = {
 | 
			
		||||
            isEditing: () => false
 | 
			
		||||
        };
 | 
			
		||||
        openmct.objects.isPersistable = () => true;
 | 
			
		||||
        openmct.objects.save = () => Promise.resolve(true);
 | 
			
		||||
 | 
			
		||||
        window.localStorage.setItem('notebook-storage', null);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -586,6 +586,10 @@ export default class CouchObjectProvider {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update(model) {
 | 
			
		||||
        // if (model.type === 'notebook') {
 | 
			
		||||
        //     throw new this.openmct.objects.errors.Conflict("Conflict while saving notebook");
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        let intermediateResponse = this.getIntermediateResponse();
 | 
			
		||||
        const key = model.identifier.key;
 | 
			
		||||
        this.enqueueObject(key, model, intermediateResponse);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user