From 549dfab5aa28a4296a6bbe74e279a507151bc2d9 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 26 Jan 2016 21:47:19 -0800 Subject: [PATCH 1/9] [Edit Mode] #627 remove edit concerns from browse controller --- platform/commonUI/browse/bundle.js | 4 + .../browse/res/templates/browse-object.html | 5 -- .../commonUI/browse/res/templates/browse.html | 4 +- .../browse/res/templates/view-object.html | 33 +++++++ .../commonUI/browse/src/BrowseController.js | 36 +++----- .../src/navigation/NavigationService.js | 33 +++++-- platform/commonUI/edit/bundle.js | 12 +++ .../edit/res/templates/edit-object.html | 88 ++++++++++--------- .../commonUI/edit/res/templates/edit.html | 2 +- .../edit/res/templates/inspector-edit.html | 80 +++++++++++++++++ .../commonUI/edit/src/actions/EditAction.js | 23 +++-- .../src/controllers/EditObjectController.js | 65 ++++++++++++++ .../edit/src/directives/MCTBeforeUnload.js | 24 +++-- .../edit/src/representers/EditRepresenter.js | 19 ++++ .../res/templates/inspector-browse.html | 64 ++++++++++++++ .../src/gestures/DropGesture.js | 10 ++- 16 files changed, 402 insertions(+), 100 deletions(-) create mode 100644 platform/commonUI/browse/res/templates/view-object.html create mode 100644 platform/commonUI/edit/res/templates/inspector-edit.html create mode 100644 platform/commonUI/edit/src/controllers/EditObjectController.js create mode 100644 platform/commonUI/general/res/templates/inspector-browse.html diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index bf76295b18..4715440b76 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -170,6 +170,10 @@ define([ } ], "representations": [ + { + "key": "view-region", + "templateUrl": "templates/view-object.html" + }, { "key": "browse-object", "template": browseObjectTemplate, diff --git a/platform/commonUI/browse/res/templates/browse-object.html b/platform/commonUI/browse/res/templates/browse-object.html index 562f8bdf6a..35d0d58f3f 100644 --- a/platform/commonUI/browse/res/templates/browse-object.html +++ b/platform/commonUI/browse/res/templates/browse-object.html @@ -47,11 +47,6 @@
- - diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index 3d3f22bd7d..5b74709b2e 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -63,7 +63,7 @@
@@ -71,7 +71,7 @@
- diff --git a/platform/commonUI/browse/res/templates/view-object.html b/platform/commonUI/browse/res/templates/view-object.html new file mode 100644 index 0000000000..b670e1645e --- /dev/null +++ b/platform/commonUI/browse/res/templates/view-object.html @@ -0,0 +1,33 @@ + + + + diff --git a/platform/commonUI/browse/src/BrowseController.js b/platform/commonUI/browse/src/BrowseController.js index d1d5aa92cc..9f1834f80d 100644 --- a/platform/commonUI/browse/src/BrowseController.js +++ b/platform/commonUI/browse/src/BrowseController.js @@ -60,13 +60,6 @@ define( ($route.current.params.ids || defaultPath).split("/") ); - function isDirty(){ - var editorCapability = $scope.navigatedObject && - $scope.navigatedObject.getCapability("editor"), - hasChanges = editorCapability && editorCapability.dirty(); - return hasChanges; - } - function updateRoute(domainObject) { var priorRoute = $route.current, // Act as if params HADN'T changed to avoid page reload @@ -83,9 +76,7 @@ define( // urlService.urlForLocation used to adjust current // path to new, addressed, path based on // domainObject - $location.path(urlService.urlForLocation("browse", - domainObject.hasCapability('editor') ? - domainObject.getOriginalObject() : domainObject)); + $location.path(urlService.urlForLocation("browse", domainObject)); } @@ -97,17 +88,15 @@ define( return; } - if (isDirty() && !confirm(CONFIRM_MSG)) { - $scope.treeModel.selectedObject = $scope.navigatedObject; - navigationService.setNavigation($scope.navigatedObject); - } else { - if ($scope.navigatedObject && $scope.navigatedObject.hasCapability("editor")){ - $scope.navigatedObject.getCapability("editor").cancel(); - } + if (navigationService.setNavigation(domainObject)) { $scope.navigatedObject = domainObject; $scope.treeModel.selectedObject = domainObject; - navigationService.setNavigation(domainObject); updateRoute(domainObject); + } else { + //If navigation was unsuccessful (ie. blocked), reset + // the selected object in the tree to the currently + // navigated object + $scope.treeModel.selectedObject = $scope.navigatedObject ; } } @@ -184,18 +173,13 @@ define( selectedObject: navigationService.getNavigation() }; - $scope.beforeUnloadWarning = function() { - return isDirty() ? - "Unsaved changes will be lost if you leave this page." : - undefined; - }; - // Listen for changes in navigation state. navigationService.addListener(setNavigation); - // Also listen for changes which come from the tree + // Also listen for changes which come from the tree. Changes in + // the tree will trigger a change in browse navigation state. $scope.$watch("treeModel.selectedObject", setNavigation); - + // Clean up when the scope is destroyed $scope.$on("$destroy", function () { navigationService.removeListener(setNavigation); diff --git a/platform/commonUI/browse/src/navigation/NavigationService.js b/platform/commonUI/browse/src/navigation/NavigationService.js index 87e5582ef7..e2b7168b3c 100644 --- a/platform/commonUI/browse/src/navigation/NavigationService.js +++ b/platform/commonUI/browse/src/navigation/NavigationService.js @@ -37,7 +37,7 @@ define( */ function NavigationService() { this.navigated = undefined; - this.callbacks = []; + this.callbacks = {}; } /** @@ -53,12 +53,20 @@ define( * @param {DomainObject} domainObject the domain object to navigate to */ NavigationService.prototype.setNavigation = function (value) { + var canNavigate = true; if (this.navigated !== value) { - this.navigated = value; - this.callbacks.forEach(function (callback) { - callback(value); - }); + canNavigate = (this.callbacks['before'] || []) + .reduce(function (previous, callback) { + return callback(value) && previous; + }, true); + if (canNavigate) { + this.navigated = value; + this.callbacks['after'].forEach(function (callback) { + callback(value); + }); + } } + return canNavigate; }; /** @@ -67,9 +75,13 @@ define( * this changes. * @param {function} callback the callback to invoke when * navigation state changes + * @param {string} [event=after] the navigation event to listen to. + * One of 'before' or 'after'. */ - NavigationService.prototype.addListener = function (callback) { - this.callbacks.push(callback); + NavigationService.prototype.addListener = function (callback, event) { + event = event || 'after'; + this.callbacks[event] = this.callbacks[event] || []; + this.callbacks[event].push(callback); }; /** @@ -77,9 +89,12 @@ define( * @param {function} callback the callback which should * no longer be invoked when navigation state * changes + * @param {string} [event=after] the navigation event to the + * callback is registered to. One of 'before' or 'after'. */ - NavigationService.prototype.removeListener = function (callback) { - this.callbacks = this.callbacks.filter(function (cb) { + NavigationService.prototype.removeListener = function (callback, event) { + event = event || 'after'; + this.callbacks[event] = this.callbacks[event].filter(function (cb) { return cb !== callback; }); }; diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index c4b0da1798..9fc0c98939 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -26,6 +26,7 @@ define([ "./src/controllers/EditActionController", "./src/controllers/EditPanesController", "./src/controllers/ElementsController", + "./src/controllers/EditObjectController", "./src/directives/MCTBeforeUnload", "./src/actions/LinkAction", "./src/actions/EditAction", @@ -48,6 +49,7 @@ define([ EditActionController, EditPanesController, ElementsController, + EditObjectController, MCTBeforeUnload, LinkAction, EditAction, @@ -106,6 +108,13 @@ define([ "depends": [ "$scope" ] + }, + { + "key": "EditObjectController", + "implementation": EditObjectController, + "depends": [ + "$scope" + ] } ], "directives": [ @@ -206,6 +215,9 @@ define([ "template": editObjectTemplate, "uses": [ "view" + ], + "gestures": [ + "drop" ] }, { diff --git a/platform/commonUI/edit/res/templates/edit-object.html b/platform/commonUI/edit/res/templates/edit-object.html index 71dc233a82..7b2f32e1b3 100644 --- a/platform/commonUI/edit/res/templates/edit-object.html +++ b/platform/commonUI/edit/res/templates/edit-object.html @@ -19,50 +19,52 @@ this source code distribution or the Licensing information page available at runtime from the About dialog for additional information. --> - - -
- -
- - - +
+
+
+ +
- - +
+
+ +
+ + + + + +
+ + +
+
diff --git a/platform/commonUI/edit/res/templates/edit.html b/platform/commonUI/edit/res/templates/edit.html index 07a677bce8..489eed822b 100644 --- a/platform/commonUI/edit/res/templates/edit.html +++ b/platform/commonUI/edit/res/templates/edit.html @@ -21,7 +21,7 @@ -->
diff --git a/platform/commonUI/edit/res/templates/inspector-edit.html b/platform/commonUI/edit/res/templates/inspector-edit.html new file mode 100644 index 0000000000..5f3e4d522e --- /dev/null +++ b/platform/commonUI/edit/res/templates/inspector-edit.html @@ -0,0 +1,80 @@ + + +
+ +
+
+
Inspection
+
    +
  • + Properties +
    +
    {{ data.name }}
    +
    {{ data.value }}
    +
    +
  • +
  • + Location + + + + +
  • +
  • + Original Location + + + + +
  • +
+
+
+ +
+
+ Elements + + +
+
+
+
+
diff --git a/platform/commonUI/edit/src/actions/EditAction.js b/platform/commonUI/edit/src/actions/EditAction.js index 6b8ba3e042..d771f75dd4 100644 --- a/platform/commonUI/edit/src/actions/EditAction.js +++ b/platform/commonUI/edit/src/actions/EditAction.js @@ -72,13 +72,26 @@ define( * Enter edit mode. */ EditAction.prototype.perform = function () { - var editableObject; + var self = this; if (!this.domainObject.hasCapability("editor")) { - editableObject = new EditableDomainObject(this.domainObject, this.$q); - editableObject.getCapability('status').set('editing', true); - this.navigationService.setNavigation(editableObject); + //TODO: This is only necessary because the drop gesture is + // wrapping the object itself, need to refactor this later. + // All responsibility for switching into edit mode should be + // in the edit action, and not duplicated in the gesture + this.domainObject = new EditableDomainObject(this.domainObject, this.$q); } - //this.$location.path("/edit"); + this.navigationService.setNavigation(this.domainObject); + this.domainObject.getCapability('status').set('editing', true); + + //Register a listener to automatically cancel this edit action + //if the user navigates away from this object. + function cancelEditing(navigatedTo){ + if (!navigatedTo || navigatedTo.getId() !== self.domainObject.getId()) { + self.domainObject.getCapability('editor').cancel(); + self.navigationService.removeListener(cancelEditing); + } + } + this.navigationService.addListener(cancelEditing); }; /** diff --git a/platform/commonUI/edit/src/controllers/EditObjectController.js b/platform/commonUI/edit/src/controllers/EditObjectController.js new file mode 100644 index 0000000000..eb5d494cac --- /dev/null +++ b/platform/commonUI/edit/src/controllers/EditObjectController.js @@ -0,0 +1,65 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define,Promise*/ + +/** + * This bundle implements Edit mode. + * @namespace platform/commonUI/edit + */ +define( + [], + function () { + "use strict"; + + /** + * Controller which is responsible for populating the scope for + * Edit mode + * @memberof platform/commonUI/edit + * @constructor + */ + function EditObjectController($scope) { + this.scope = $scope; + } + + /** + * Get the warning to show if the user attempts to navigate + * away from Edit mode while unsaved changes are present. + * @returns {string} the warning to show, or undefined if + * there are no unsaved changes + */ + EditObjectController.prototype.getUnloadWarning = function () { + var navigatedObject = this.scope.domainObject, + editorCapability = navigatedObject && + navigatedObject.getCapability("editor"), + statusCapability = navigatedObject && + navigatedObject.getCapability("status"), + hasChanges = statusCapability && statusCapability.get('editing') + && editorCapability && editorCapability.dirty(); + + return hasChanges ? + "Unsaved changes will be lost if you leave this page." : + undefined; + }; + + return EditObjectController; + } +); diff --git a/platform/commonUI/edit/src/directives/MCTBeforeUnload.js b/platform/commonUI/edit/src/directives/MCTBeforeUnload.js index 3e7501c788..226e85f4a0 100644 --- a/platform/commonUI/edit/src/directives/MCTBeforeUnload.js +++ b/platform/commonUI/edit/src/directives/MCTBeforeUnload.js @@ -35,7 +35,7 @@ define( * @constructor * @param $window the window */ - function MCTBeforeUnload($window) { + function MCTBeforeUnload($window, navigationService) { var unloads = [], oldBeforeUnload = $window.onbeforeunload; @@ -57,6 +57,7 @@ define( // Stop using this unload expression function removeUnload() { + navigationService.removeListener(checkNavigationEvent, "before"); unloads = unloads.filter(function (callback) { return callback !== unload; }); @@ -65,17 +66,28 @@ define( } } - // Show a dialog before allowing a location change - function checkLocationChange(event) { + function shouldAllowNavigation(){ // Get an unload message (if any) var warning = unload(); // Prompt the user if there's an unload message - if (warning && !$window.confirm(warning)) { - // ...and prevent the route change if it was confirmed + return !warning || $window.confirm(warning); + } + + // Show a dialog before allowing a location change + function checkLocationChange(event) { + if (!shouldAllowNavigation()) { + // Prevent the route change if it was confirmed event.preventDefault(); } } + // Show a dialog before allowing a location change + function checkNavigationEvent(event) { + // Return a false value to the navigationService to + // indicate that the navigation event should be prevented + return shouldAllowNavigation(); + } + // If this is the first active instance of this directive, // register as the window's beforeunload handler if (unloads.length === 0) { @@ -90,6 +102,8 @@ define( // Also handle route changes scope.$on("$locationChangeStart", checkLocationChange); + + navigationService.addListener(checkNavigationEvent, "before"); } return { diff --git a/platform/commonUI/edit/src/representers/EditRepresenter.js b/platform/commonUI/edit/src/representers/EditRepresenter.js index 0844f65e67..e53318c1b0 100644 --- a/platform/commonUI/edit/src/representers/EditRepresenter.js +++ b/platform/commonUI/edit/src/representers/EditRepresenter.js @@ -49,6 +49,7 @@ define( var self = this; this.scope = scope; + this.listenHandle = undefined; // Mutate and persist a new version of a domain object's model. function doPersist(model) { @@ -100,10 +101,13 @@ define( // Place the "commit" method in the scope scope.commit = commit; scope.setEditable = setEditable; + } // Handle a specific representation of a specific domain object EditRepresenter.prototype.represent = function represent(representation, representedObject) { + var scope = this.scope, + self = this; // Track the key, to know which view configuration to save to. this.key = (representation || {}).key; // Track the represented object @@ -113,11 +117,26 @@ define( // Ensure existing watches are released this.destroy(); + + /** + * Listen for changes in object state. If the object becomes + * editable then change the view and inspector regions + * object representation accordingly + */ + this.listenHandle = this.domainObject.getCapability('status').listen(function(statuses){ + if (statuses.indexOf('editing')!=-1){ + scope.viewRegionTemplate = 'edit-object'; + scope.inspectorRegionTemplate = 'inspector-edit' + } else { + delete scope.viewRegionTemplate; + } + }); }; // Respond to the destruction of the current representation. EditRepresenter.prototype.destroy = function destroy() { // Nothing to clean up + this.listenHandle && this.listenHandle(); }; return EditRepresenter; diff --git a/platform/commonUI/general/res/templates/inspector-browse.html b/platform/commonUI/general/res/templates/inspector-browse.html new file mode 100644 index 0000000000..3a7a60f516 --- /dev/null +++ b/platform/commonUI/general/res/templates/inspector-browse.html @@ -0,0 +1,64 @@ + + +
+
Inspection
+
    +
  • + Properties +
    +
    {{ data.name }}
    +
    {{ data.value }}
    +
    +
  • +
  • + Location + + + + +
  • +
  • + Original Location + + + + +
  • +
+
+
+ diff --git a/platform/representation/src/gestures/DropGesture.js b/platform/representation/src/gestures/DropGesture.js index 1b7881a770..225211c3bd 100644 --- a/platform/representation/src/gestures/DropGesture.js +++ b/platform/representation/src/gestures/DropGesture.js @@ -165,16 +165,18 @@ define( if (shouldCreateVirtualPanel(domainObject, selectedObject)){ editableDomainObject = createVirtualPanel(domainObject, selectedObject); if (editableDomainObject) { - navigationService.setNavigation(editableDomainObject); + editableDomainObject.getCapability('action').perform('edit'); + //navigationService.setNavigation(editableDomainObject); broadcastDrop(id, event); - editableDomainObject.getCapability('status').set('editing', true); + //editableDomainObject.getCapability('status').set('editing', true); } } else { $q.when(action && action.perform()).then(function (result) { //Don't go into edit mode for folders if (domainObjectType!=='folder') { - navigationService.setNavigation(editableDomainObject); - editableDomainObject.getCapability('status').set('editing', true); + // navigationService.setNavigation(editableDomainObject); + //editableDomainObject.getCapability('status').set('editing', true); + editableDomainObject.getCapability('action').perform('edit'); } broadcastDrop(id, event); }); From fa46d31ac24d0a9e6d47a87ff542dd6d2355465f Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 26 Jan 2016 22:05:18 -0800 Subject: [PATCH 2/9] [Edit Mode] #627 slightly modified edit representer to detect newly created objects Added some comments, renamed controller variable in markup Removed edit references from BrowseController --- .../commonUI/browse/src/BrowseController.js | 5 +- .../browse/src/BrowseObjectController.js | 16 +--- .../src/navigation/NavigationService.js | 16 +++- platform/commonUI/edit/bundle.js | 19 ----- .../edit/res/templates/edit-object.html | 5 +- .../commonUI/edit/res/templates/edit.html | 32 ------- .../edit/src/controllers/EditController.js | 84 ------------------- .../src/controllers/EditObjectController.js | 25 ++++++ .../edit/src/representers/EditRepresenter.js | 12 ++- 9 files changed, 56 insertions(+), 158 deletions(-) delete mode 100644 platform/commonUI/edit/res/templates/edit.html delete mode 100644 platform/commonUI/edit/src/controllers/EditController.js diff --git a/platform/commonUI/browse/src/BrowseController.js b/platform/commonUI/browse/src/BrowseController.js index 9f1834f80d..f65333870d 100644 --- a/platform/commonUI/browse/src/BrowseController.js +++ b/platform/commonUI/browse/src/BrowseController.js @@ -27,10 +27,9 @@ */ define( [ - '../../../representation/src/gestures/GestureConstants', - '../../edit/src/objects/EditableDomainObject' + '../../../representation/src/gestures/GestureConstants' ], - function (GestureConstants, EditableDomainObject) { + function (GestureConstants) { "use strict"; var ROOT_ID = "ROOT", diff --git a/platform/commonUI/browse/src/BrowseObjectController.js b/platform/commonUI/browse/src/BrowseObjectController.js index b0a93a991a..daf157e2c3 100644 --- a/platform/commonUI/browse/src/BrowseObjectController.js +++ b/platform/commonUI/browse/src/BrowseObjectController.js @@ -22,11 +22,8 @@ /*global define,Promise*/ define( - [ - '../../../representation/src/gestures/GestureConstants', - '../../edit/src/objects/EditableDomainObject' - ], - function (GestureConstants, EditableDomainObject) { + [], + function () { "use strict"; /** @@ -57,10 +54,9 @@ define( function updateQueryParam(viewKey) { var unlisten, - priorRoute = $route.current, - isEditMode = $scope.domainObject && $scope.domainObject.hasCapability('editor'); + priorRoute = $route.current; - if (viewKey && !isEditMode) { + if (viewKey) { $location.search('view', viewKey); unlisten = $scope.$on('$locationChangeSuccess', function () { // Checks path to make sure /browse/ is at front @@ -76,10 +72,6 @@ define( $scope.$watch('domainObject', setViewForDomainObject); $scope.$watch('representation.selected.key', updateQueryParam); - $scope.cancelEditing = function() { - navigationService.setNavigation($scope.domainObject.getDomainObject()); - }; - $scope.doAction = function (action){ return $scope[action] && $scope[action](); }; diff --git a/platform/commonUI/browse/src/navigation/NavigationService.js b/platform/commonUI/browse/src/navigation/NavigationService.js index e2b7168b3c..1d43971166 100644 --- a/platform/commonUI/browse/src/navigation/NavigationService.js +++ b/platform/commonUI/browse/src/navigation/NavigationService.js @@ -50,6 +50,8 @@ define( /** * Set the current navigation state. This will invoke listeners. + * Changing the navigation state will be blocked if any of the + * 'before' navigation state change listeners return 'false'. * @param {DomainObject} domainObject the domain object to navigate to */ NavigationService.prototype.setNavigation = function (value) { @@ -57,7 +59,11 @@ define( if (this.navigated !== value) { canNavigate = (this.callbacks['before'] || []) .reduce(function (previous, callback) { - return callback(value) && previous; + //Check whether the callback returned a value of + // 'false' indicating that navigation should not + // continue. All other return values will allow + // navigation to continue + return (callback(value)!==false) && previous; }, true); if (canNavigate) { this.navigated = value; @@ -72,7 +78,11 @@ define( /** * Listen for changes in navigation. The passed callback will * be invoked with the new domain object of navigation when - * this changes. + * this changes. Callbacks can be registered to listen to pre or + * post-navigation events. The event to listen to is specified using + * the event parameter. In the case of pre-navigation events + * returning a false value will prevent the navigation event from + * going ahead. * @param {function} callback the callback to invoke when * navigation state changes * @param {string} [event=after] the navigation event to listen to. @@ -89,7 +99,7 @@ define( * @param {function} callback the callback which should * no longer be invoked when navigation state * changes - * @param {string} [event=after] the navigation event to the + * @param {string} [event=after] the navigation event that the * callback is registered to. One of 'before' or 'after'. */ NavigationService.prototype.removeListener = function (callback, event) { diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index 9fc0c98939..e4b0953267 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -22,7 +22,6 @@ /*global define*/ define([ - "./src/controllers/EditController", "./src/controllers/EditActionController", "./src/controllers/EditPanesController", "./src/controllers/ElementsController", @@ -37,7 +36,6 @@ define([ "./src/policies/EditActionPolicy", "./src/representers/EditRepresenter", "./src/representers/EditToolbarRepresenter", - "text!./res/templates/edit.html", "text!./res/templates/library.html", "text!./res/templates/edit-object.html", "text!./res/templates/edit-action-buttons.html", @@ -45,7 +43,6 @@ define([ "text!./res/templates/topbar-edit.html", 'legacyRegistry' ], function ( - EditController, EditActionController, EditPanesController, ElementsController, @@ -60,7 +57,6 @@ define([ EditActionPolicy, EditRepresenter, EditToolbarRepresenter, - editTemplate, libraryTemplate, editObjectTemplate, editActionButtonsTemplate, @@ -72,22 +68,7 @@ define([ legacyRegistry.register("platform/commonUI/edit", { "extensions": { - "routes": [ - { - "when": "/edit", - "template": editTemplate - } - ], "controllers": [ - { - "key": "EditController", - "implementation": EditController, - "depends": [ - "$scope", - "$q", - "navigationService" - ] - }, { "key": "EditActionController", "implementation": EditActionController, diff --git a/platform/commonUI/edit/res/templates/edit-object.html b/platform/commonUI/edit/res/templates/edit-object.html index 7b2f32e1b3..9da28714a7 100644 --- a/platform/commonUI/edit/res/templates/edit-object.html +++ b/platform/commonUI/edit/res/templates/edit-object.html @@ -19,9 +19,8 @@ this source code distribution or the Licensing information page available at runtime from the About dialog for additional information. --> -
-
+
-
- - - - - - -
diff --git a/platform/commonUI/edit/src/controllers/EditController.js b/platform/commonUI/edit/src/controllers/EditController.js deleted file mode 100644 index eaffe02186..0000000000 --- a/platform/commonUI/edit/src/controllers/EditController.js +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ -/*global define,Promise*/ - -/** - * This bundle implements Edit mode. - * @namespace platform/commonUI/edit - */ -define( - ["../objects/EditableDomainObject"], - function (EditableDomainObject) { - "use strict"; - - /** - * Controller which is responsible for populating the scope for - * Edit mode; introduces an editable version of the currently - * navigated domain object into the scope. - * @memberof platform/commonUI/edit - * @constructor - */ - function EditController($scope, $q, navigationService) { - var self = this; - - function setNavigation(domainObject) { - // Wrap the domain object such that all mutation is - // confined to edit mode (until Save) - self.navigatedDomainObject = - domainObject && new EditableDomainObject(domainObject, $q); - } - - setNavigation(navigationService.getNavigation()); - navigationService.addListener(setNavigation); - $scope.$on("$destroy", function () { - navigationService.removeListener(setNavigation); - }); - } - - /** - * Get the domain object which is navigated-to. - * @returns {DomainObject} the domain object that is navigated-to - */ - EditController.prototype.navigatedObject = function () { - return this.navigatedDomainObject; - }; - - /** - * Get the warning to show if the user attempts to navigate - * away from Edit mode while unsaved changes are present. - * @returns {string} the warning to show, or undefined if - * there are no unsaved changes - */ - EditController.prototype.getUnloadWarning = function () { - var navigatedObject = this.navigatedDomainObject, - editorCapability = navigatedObject && - navigatedObject.getCapability("editor"), - hasChanges = editorCapability && editorCapability.dirty(); - - return hasChanges ? - "Unsaved changes will be lost if you leave this page." : - undefined; - }; - - return EditController; - } -); diff --git a/platform/commonUI/edit/src/controllers/EditObjectController.js b/platform/commonUI/edit/src/controllers/EditObjectController.js index eb5d494cac..96c843b6ea 100644 --- a/platform/commonUI/edit/src/controllers/EditObjectController.js +++ b/platform/commonUI/edit/src/controllers/EditObjectController.js @@ -38,6 +38,31 @@ define( */ function EditObjectController($scope) { this.scope = $scope; + + var navigatedObject; + function setViewForDomainObject(domainObject) { + + var locationViewKey = $location.search().view; + + function selectViewIfMatching(view) { + if (view.key === locationViewKey) { + $scope.representation = $scope.representation || {}; + $scope.representation.selected = view; + } + } + + if (locationViewKey) { + ((domainObject && domainObject.useCapability('view')) || []) + .forEach(selectViewIfMatching); + } + navigatedObject = domainObject; + } + + $scope.$watch('domainObject', setViewForDomainObject); + + $scope.doAction = function (action){ + return $scope[action] && $scope[action](); + }; } /** diff --git a/platform/commonUI/edit/src/representers/EditRepresenter.js b/platform/commonUI/edit/src/representers/EditRepresenter.js index e53318c1b0..c062e6387f 100644 --- a/platform/commonUI/edit/src/representers/EditRepresenter.js +++ b/platform/commonUI/edit/src/representers/EditRepresenter.js @@ -118,6 +118,11 @@ define( // Ensure existing watches are released this.destroy(); + function setEditing(){ + scope.viewRegionTemplate = 'edit-object'; + scope.inspectorRegionTemplate = 'inspector-edit' + } + /** * Listen for changes in object state. If the object becomes * editable then change the view and inspector regions @@ -125,12 +130,15 @@ define( */ this.listenHandle = this.domainObject.getCapability('status').listen(function(statuses){ if (statuses.indexOf('editing')!=-1){ - scope.viewRegionTemplate = 'edit-object'; - scope.inspectorRegionTemplate = 'inspector-edit' + setEditing(); } else { delete scope.viewRegionTemplate; } }); + + if (representedObject.getCapability('status').get('editing')){ + setEditing(); + } }; // Respond to the destruction of the current representation. From 2f036a89e45d7790200f72b4edbc4d9a650f338d Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 26 Feb 2016 16:29:01 -0800 Subject: [PATCH 3/9] Refactoring out regions --- platform/commonUI/browse/bundle.js | 2 +- .../commonUI/browse/res/templates/browse.html | 6 +- .../edit/res/templates/inspector-edit.html | 80 ------------------- .../res/templates/inspector-browse.html | 64 --------------- 4 files changed, 4 insertions(+), 148 deletions(-) delete mode 100644 platform/commonUI/edit/res/templates/inspector-edit.html delete mode 100644 platform/commonUI/general/res/templates/inspector-browse.html diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index 4715440b76..1fcd810b96 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -171,7 +171,7 @@ define([ ], "representations": [ { - "key": "view-region", + "key": "view-object", "templateUrl": "templates/view-object.html" }, { diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index 5b74709b2e..08a5cd4d5e 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -63,7 +63,7 @@
@@ -71,8 +71,8 @@ - From 65ca78d8aa0c1547dd69b79339d449d064d2793f Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 26 Feb 2016 16:34:07 -0800 Subject: [PATCH 4/9] Added missing dependency on --- platform/commonUI/edit/bundle.js | 3 ++- platform/commonUI/edit/src/controllers/EditObjectController.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index e4b0953267..2e0e0a93f3 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -94,7 +94,8 @@ define([ "key": "EditObjectController", "implementation": EditObjectController, "depends": [ - "$scope" + "$scope", + "$location" ] } ], diff --git a/platform/commonUI/edit/src/controllers/EditObjectController.js b/platform/commonUI/edit/src/controllers/EditObjectController.js index 96c843b6ea..e46d5cffe1 100644 --- a/platform/commonUI/edit/src/controllers/EditObjectController.js +++ b/platform/commonUI/edit/src/controllers/EditObjectController.js @@ -36,7 +36,7 @@ define( * @memberof platform/commonUI/edit * @constructor */ - function EditObjectController($scope) { + function EditObjectController($scope, $location) { this.scope = $scope; var navigatedObject; From a910fa8f3732940fbd89dafabd1a6c0e6f578103 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 26 Feb 2016 17:04:58 -0800 Subject: [PATCH 5/9] Removed unused 'controller as' --- .../commonUI/general/res/templates/object-inspector.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/commonUI/general/res/templates/object-inspector.html b/platform/commonUI/general/res/templates/object-inspector.html index 56eaeb86cc..708814b3cc 100644 --- a/platform/commonUI/general/res/templates/object-inspector.html +++ b/platform/commonUI/general/res/templates/object-inspector.html @@ -20,7 +20,7 @@ at runtime from the About dialog for additional information. --> -
+
@@ -31,8 +31,8 @@ ng-model="ngModel" class="flex-elem grows vscroll l-flex-col"> -
-
+
+
@@ -45,5 +45,5 @@
-
+
From 2cc2c6a9d3237860789eab6a4d07651bc7b19e8d Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 26 Feb 2016 17:12:35 -0800 Subject: [PATCH 6/9] [Edit Mode] #627 removed edit concerns from browse controllers and markup Fixed elements not appearing in edit mode Fixed failing tests --- platform/commonUI/browse/bundle.js | 1 - .../commonUI/browse/res/templates/browse.html | 2 +- .../browse/res/templates/view-object.html | 2 +- .../commonUI/browse/src/BrowseController.js | 1 - .../src/navigation/NavigationService.js | 4 +- .../browse/test/BrowseControllerSpec.js | 32 ++++- .../test/navigation/NavigationServiceSpec.js | 20 +++- .../edit/src/representers/EditRepresenter.js | 12 +- .../test/controllers/EditControllerSpec.js | 109 +++++++++--------- .../test/directives/MCTBeforeUnloadSpec.js | 11 +- .../test/representers/EditRepresenterSpec.js | 19 ++- 11 files changed, 140 insertions(+), 73 deletions(-) diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index 1fcd810b96..cf4ee5b7a0 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -111,7 +111,6 @@ define([ "$scope", "$route", "$location", - "$q", "objectService", "navigationService", "urlService", diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index 08a5cd4d5e..75fcaaeb0a 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -72,7 +72,7 @@
diff --git a/platform/commonUI/browse/src/BrowseController.js b/platform/commonUI/browse/src/BrowseController.js index f65333870d..6013772965 100644 --- a/platform/commonUI/browse/src/BrowseController.js +++ b/platform/commonUI/browse/src/BrowseController.js @@ -49,7 +49,6 @@ define( $scope, $route, $location, - $q, objectService, navigationService, urlService, diff --git a/platform/commonUI/browse/src/navigation/NavigationService.js b/platform/commonUI/browse/src/navigation/NavigationService.js index 1d43971166..858a5d80eb 100644 --- a/platform/commonUI/browse/src/navigation/NavigationService.js +++ b/platform/commonUI/browse/src/navigation/NavigationService.js @@ -57,7 +57,7 @@ define( NavigationService.prototype.setNavigation = function (value) { var canNavigate = true; if (this.navigated !== value) { - canNavigate = (this.callbacks['before'] || []) + canNavigate = (this.callbacks.before || []) .reduce(function (previous, callback) { //Check whether the callback returned a value of // 'false' indicating that navigation should not @@ -67,7 +67,7 @@ define( }, true); if (canNavigate) { this.navigated = value; - this.callbacks['after'].forEach(function (callback) { + (this.callbacks.after || []).forEach(function (callback) { callback(value); }); } diff --git a/platform/commonUI/browse/test/BrowseControllerSpec.js b/platform/commonUI/browse/test/BrowseControllerSpec.js index e4fad10544..caab0ed7d8 100644 --- a/platform/commonUI/browse/test/BrowseControllerSpec.js +++ b/platform/commonUI/browse/test/BrowseControllerSpec.js @@ -29,8 +29,7 @@ define( function (BrowseController) { "use strict"; - //TODO: Disabled for NEM Beta - xdescribe("The browse controller", function () { + describe("The browse controller", function () { var mockScope, mockRoute, mockLocation, @@ -214,7 +213,10 @@ define( // prior to setting $route.current mockLocation.path.andReturn("/browse/"); + mockNavigationService.setNavigation.andReturn(true); + // Exercise the Angular workaround + mockNavigationService.addListener.mostRecentCall.args[0](); mockScope.$on.mostRecentCall.args[1](); expect(mockUnlisten).toHaveBeenCalled(); @@ -225,6 +227,32 @@ define( ); }); + it("after successful navigation event sets the selected tree " + + "object", function () { + mockScope.navigatedObject = mockDomainObject; + mockNavigationService.setNavigation.andReturn(true); + + //Simulate a change in selected tree object + mockScope.treeModel = {selectedObject: mockDomainObject}; + mockScope.$watch.mostRecentCall.args[1](mockNextObject); + + expect(mockScope.treeModel.selectedObject).toBe(mockNextObject); + expect(mockScope.treeModel.selectedObject).not.toBe(mockDomainObject); + }); + + it("after failed navigation event resets the selected tree" + + " object", function () { + mockScope.navigatedObject = mockDomainObject; + mockNavigationService.setNavigation.andReturn(false); + + //Simulate a change in selected tree object + mockScope.treeModel = {selectedObject: mockDomainObject}; + mockScope.$watch.mostRecentCall.args[1](mockNextObject); + + expect(mockScope.treeModel.selectedObject).not.toBe(mockNextObject); + expect(mockScope.treeModel.selectedObject).toBe(mockDomainObject); + }); + }); } ); diff --git a/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js b/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js index 6d7f3fd20d..3a354dee78 100644 --- a/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js +++ b/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js @@ -84,6 +84,24 @@ define( expect(callback).not.toHaveBeenCalled(); }); + it("adds listeners to the 'after' state by default", function(){ + expect(navigationService.callbacks.after).toBeUndefined(); + navigationService.addListener(function(){}); + expect(navigationService.callbacks.after).toBeDefined(); + expect(navigationService.callbacks.after.length).toBe(1); + }); + + it("allows navigationService events to be prevented", function(){ + var callback = jasmine.createSpy("callback"), + navigationResult; + callback.andReturn(false); + navigationService.addListener(callback, "before"); + navigationResult = navigationService.setNavigation({}); + expect(callback).toHaveBeenCalled(); + expect(navigationResult).toBe(false); + + }); + }); } -); \ No newline at end of file +); diff --git a/platform/commonUI/edit/src/representers/EditRepresenter.js b/platform/commonUI/edit/src/representers/EditRepresenter.js index c062e6387f..5d96aeaf78 100644 --- a/platform/commonUI/edit/src/representers/EditRepresenter.js +++ b/platform/commonUI/edit/src/representers/EditRepresenter.js @@ -102,6 +102,11 @@ define( scope.commit = commit; scope.setEditable = setEditable; + // Clean up when the scope is destroyed + scope.$on("$destroy", function () { + self.destroy(); + }); + } // Handle a specific representation of a specific domain object @@ -119,8 +124,7 @@ define( this.destroy(); function setEditing(){ - scope.viewRegionTemplate = 'edit-object'; - scope.inspectorRegionTemplate = 'inspector-edit' + scope.viewObjectTemplate = 'edit-object'; } /** @@ -132,7 +136,7 @@ define( if (statuses.indexOf('editing')!=-1){ setEditing(); } else { - delete scope.viewRegionTemplate; + delete scope.viewObjectTemplate; } }); @@ -144,7 +148,7 @@ define( // Respond to the destruction of the current representation. EditRepresenter.prototype.destroy = function destroy() { // Nothing to clean up - this.listenHandle && this.listenHandle(); + return this.listenHandle && this.listenHandle(); }; return EditRepresenter; diff --git a/platform/commonUI/edit/test/controllers/EditControllerSpec.js b/platform/commonUI/edit/test/controllers/EditControllerSpec.js index 4e66cebd08..0a39874eb8 100644 --- a/platform/commonUI/edit/test/controllers/EditControllerSpec.js +++ b/platform/commonUI/edit/test/controllers/EditControllerSpec.js @@ -22,89 +22,72 @@ /*global define,describe,it,expect,beforeEach,jasmine*/ define( - ["../../src/controllers/EditController"], - function (EditController) { + ["../../src/controllers/EditObjectController"], + function (EditObjectController) { "use strict"; describe("The Edit mode controller", function () { var mockScope, - mockQ, - mockNavigationService, mockObject, mockType, + mockLocation, + mockStatusCapability, + mockCapabilities, controller; + // Utility function; look for a $watch on scope and fire it + function fireWatch(expr, value) { + mockScope.$watch.calls.forEach(function (call) { + if (call.args[0] === expr) { + call.args[1](value); + } + }); + } + beforeEach(function () { mockScope = jasmine.createSpyObj( "$scope", - [ "$on" ] - ); - mockQ = jasmine.createSpyObj('$q', ['when', 'all']); - mockNavigationService = jasmine.createSpyObj( - "navigationService", - [ "getNavigation", "addListener", "removeListener" ] + [ "$on", "$watch" ] ); mockObject = jasmine.createSpyObj( "domainObject", - [ "getId", "getModel", "getCapability", "hasCapability" ] + [ "getId", "getModel", "getCapability", "hasCapability", "useCapability" ] ); mockType = jasmine.createSpyObj( "type", [ "hasFeature" ] ); + mockStatusCapability = jasmine.createSpyObj('statusCapability', + ["get"] + ); + + mockCapabilities = { + "type" : mockType, + "status": mockStatusCapability + }; + + mockLocation = jasmine.createSpyObj('$location', + ["search"] + ); + mockLocation.search.andReturn({"view": "fixed"}); - mockNavigationService.getNavigation.andReturn(mockObject); mockObject.getId.andReturn("test"); mockObject.getModel.andReturn({ name: "Test object" }); mockObject.getCapability.andCallFake(function (key) { - return key === 'type' && mockType; + return mockCapabilities[key]; }); mockType.hasFeature.andReturn(true); - controller = new EditController( + mockScope.domainObject = mockObject; + + controller = new EditObjectController( mockScope, - mockQ, - mockNavigationService + mockLocation ); }); - it("exposes the currently-navigated object", function () { - expect(controller.navigatedObject()).toBeDefined(); - expect(controller.navigatedObject().getId()).toEqual("test"); - }); - - it("adds an editor capability to the navigated object", function () { - // Should provide an editor capability... - expect(controller.navigatedObject().getCapability("editor")) - .toBeDefined(); - // Shouldn't have been the mock capability we provided - expect(controller.navigatedObject().getCapability("editor")) - .not.toEqual(mockType); - }); - - it("detaches its navigation listener when destroyed", function () { - var navCallback = mockNavigationService - .addListener.mostRecentCall.args[0]; - - expect(mockScope.$on).toHaveBeenCalledWith( - "$destroy", - jasmine.any(Function) - ); - - // Verify precondition - expect(mockNavigationService.removeListener) - .not.toHaveBeenCalled(); - - // Trigger destroy - mockScope.$on.mostRecentCall.args[1](); - - // Listener should have been removed - expect(mockNavigationService.removeListener) - .toHaveBeenCalledWith(navCallback); - }); - it("exposes a warning message for unload", function () { - var obj = controller.navigatedObject(), + var obj = mockObject, mockEditor = jasmine.createSpyObj('editor', ['dirty']); // Normally, should be undefined @@ -112,14 +95,32 @@ define( // Override the object's editor capability, make it look // like there are unsaved changes. - obj.getCapability = jasmine.createSpy(); - obj.getCapability.andReturn(mockEditor); + mockCapabilities.editor = mockEditor; mockEditor.dirty.andReturn(true); + mockStatusCapability.get.andReturn(true); // Should have some warning message here now expect(controller.getUnloadWarning()).toEqual(jasmine.any(String)); }); + + it("sets the active view from query parameters", function () { + var testViews = [ + { key: 'abc' }, + { key: 'def', someKey: 'some value' }, + { key: 'xyz' } + ]; + + mockObject.useCapability.andCallFake(function (c) { + return (c === 'view') && testViews; + }); + mockLocation.search.andReturn({ view: 'def' }); + + fireWatch('domainObject', mockObject); + expect(mockScope.representation.selected) + .toEqual(testViews[1]); + }); + }); } ); diff --git a/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js b/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js index 41070d76f5..fd94e3e90d 100644 --- a/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js +++ b/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js @@ -31,6 +31,7 @@ define( mockScope, testAttrs, mockEvent, + mockNavigationService, directive; function fireListener(eventType, value) { @@ -46,7 +47,8 @@ define( mockScope = jasmine.createSpyObj("$scope", ['$eval', '$on']); testAttrs = { mctBeforeUnload: "someExpression" }; mockEvent = jasmine.createSpyObj("event", ["preventDefault"]); - directive = new MCTBeforeUnload(mockWindow); + mockNavigationService = jasmine.createSpyObj("navigationService", ["addListener", "removeListener"]); + directive = new MCTBeforeUnload(mockWindow, mockNavigationService); directive.link(mockScope, {}, testAttrs); }); @@ -65,6 +67,10 @@ define( ); }); + it("listens for navigation changes", function () { + expect(mockNavigationService.addListener).toHaveBeenCalledWith(jasmine.any(Function), "before"); + }); + it("listens for its scope's destroy event", function () { expect(mockScope.$on).toHaveBeenCalledWith( "$destroy", @@ -108,9 +114,10 @@ define( it("cleans up listeners when destroyed", function () { fireListener("$destroy", mockEvent); expect(mockWindow.onbeforeunload).toBeUndefined(); + expect(mockNavigationService.removeListener).toHaveBeenCalled(); }); }); } -); \ No newline at end of file +); diff --git a/platform/commonUI/edit/test/representers/EditRepresenterSpec.js b/platform/commonUI/edit/test/representers/EditRepresenterSpec.js index 79b336202a..3dcaa34627 100644 --- a/platform/commonUI/edit/test/representers/EditRepresenterSpec.js +++ b/platform/commonUI/edit/test/representers/EditRepresenterSpec.js @@ -33,8 +33,8 @@ define( testRepresentation, mockDomainObject, mockPersistence, - mockCapabilities, mockStatusCapability, + mockCapabilities, representer; function mockPromise(value) { @@ -48,7 +48,7 @@ define( beforeEach(function () { mockQ = { when: mockPromise }; mockLog = jasmine.createSpyObj("$log", ["info", "debug"]); - mockScope = jasmine.createSpyObj("$scope", ["$watch"]); + mockScope = jasmine.createSpyObj("$scope", ["$watch", "$on"]); testRepresentation = { key: "test" }; mockDomainObject = jasmine.createSpyObj("domainObject", [ "getId", @@ -60,7 +60,7 @@ define( mockPersistence = jasmine.createSpyObj("persistence", ["persist"]); mockStatusCapability = - jasmine.createSpyObj("status", ["get"]); + jasmine.createSpyObj("statusCapability", ["get", "listen"]); mockStatusCapability.get.andReturn(false); mockCapabilities = { 'persistence': mockPersistence, @@ -82,6 +82,17 @@ define( expect(mockScope.commit).toEqual(jasmine.any(Function)); }); + it("Sets edit view template on edit mode", function () { + mockStatusCapability.listen.mostRecentCall.args[0](['editing']); + expect(mockScope.viewObjectTemplate).toEqual('edit-object'); + }); + + it("Cleans up listeners on scope destroy", function () { + representer.listenHandle = jasmine.createSpy('listen'); + mockScope.$on.mostRecentCall.args[1](); + expect(representer.listenHandle).toHaveBeenCalled(); + }); + it("mutates and persists upon observed changes", function () { mockScope.model = { someKey: "some value" }; mockScope.configuration = { someConfiguration: "something" }; @@ -112,4 +123,4 @@ define( }); } -); \ No newline at end of file +); From f192544be3062b60abff7f072787d8d20e48eb24 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 29 Feb 2016 17:22:13 -0800 Subject: [PATCH 7/9] Addressing issues from code review --- platform/commonUI/browse/bundle.js | 2 + .../commonUI/browse/src/BrowseController.js | 25 +++++-- .../src/navigation/NavigationService.js | 46 +++---------- .../browse/test/BrowseControllerSpec.js | 13 ++++ .../test/navigation/NavigationServiceSpec.js | 18 ----- platform/commonUI/edit/bundle.js | 14 +++- .../edit/src/capabilities/EditorCapability.js | 1 - .../src/controllers/EditObjectController.js | 19 +++--- .../edit/src/directives/MCTBeforeUnload.js | 24 ++----- .../edit/src/policies/EditNavigationPolicy.js | 68 +++++++++++++++++++ .../edit/src/representers/EditRepresenter.js | 1 - .../test/controllers/EditControllerSpec.js | 7 ++ .../src/gestures/DropGesture.js | 7 +- 13 files changed, 147 insertions(+), 98 deletions(-) create mode 100644 platform/commonUI/edit/src/policies/EditNavigationPolicy.js diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index cf4ee5b7a0..388d484bb1 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -111,9 +111,11 @@ define([ "$scope", "$route", "$location", + "$window", "objectService", "navigationService", "urlService", + "policyService", "DEFAULT_PATH" ] }, diff --git a/platform/commonUI/browse/src/BrowseController.js b/platform/commonUI/browse/src/BrowseController.js index 6013772965..54a230682c 100644 --- a/platform/commonUI/browse/src/BrowseController.js +++ b/platform/commonUI/browse/src/BrowseController.js @@ -33,6 +33,7 @@ define( "use strict"; var ROOT_ID = "ROOT", + DEFAULT_PATH = "mine", CONFIRM_MSG = "Unsaved changes will be lost if you leave this page."; /** @@ -46,12 +47,14 @@ define( * @constructor */ function BrowseController( - $scope, - $route, - $location, - objectService, - navigationService, - urlService, + $scope, + $route, + $location, + $window, + objectService, + navigationService, + urlService, + policyService, defaultPath ) { var path = [ROOT_ID].concat( @@ -81,14 +84,22 @@ define( // Callback for updating the in-scope reference to the object // that is currently navigated-to. function setNavigation(domainObject) { + var navigationAllowed = true; + if (domainObject === $scope.navigatedObject){ //do nothing; return; } - if (navigationService.setNavigation(domainObject)) { + policyService.allow("navigation", $scope.navigatedObject, domainObject, function(message){ + navigationAllowed = $window.confirm(message + "\r\n\r\n" + + " Are you sure you want to continue?"); + }); + + if (navigationAllowed) { $scope.navigatedObject = domainObject; $scope.treeModel.selectedObject = domainObject; + navigationService.setNavigation(domainObject); updateRoute(domainObject); } else { //If navigation was unsuccessful (ie. blocked), reset diff --git a/platform/commonUI/browse/src/navigation/NavigationService.js b/platform/commonUI/browse/src/navigation/NavigationService.js index 858a5d80eb..3b4d266bd1 100644 --- a/platform/commonUI/browse/src/navigation/NavigationService.js +++ b/platform/commonUI/browse/src/navigation/NavigationService.js @@ -37,7 +37,7 @@ define( */ function NavigationService() { this.navigated = undefined; - this.callbacks = {}; + this.callbacks = []; } /** @@ -50,48 +50,27 @@ define( /** * Set the current navigation state. This will invoke listeners. - * Changing the navigation state will be blocked if any of the - * 'before' navigation state change listeners return 'false'. * @param {DomainObject} domainObject the domain object to navigate to */ NavigationService.prototype.setNavigation = function (value) { - var canNavigate = true; if (this.navigated !== value) { - canNavigate = (this.callbacks.before || []) - .reduce(function (previous, callback) { - //Check whether the callback returned a value of - // 'false' indicating that navigation should not - // continue. All other return values will allow - // navigation to continue - return (callback(value)!==false) && previous; - }, true); - if (canNavigate) { - this.navigated = value; - (this.callbacks.after || []).forEach(function (callback) { - callback(value); - }); - } + this.navigated = value; + this.callbacks.forEach(function (callback) { + callback(value); + }); } - return canNavigate; + return true; }; /** * Listen for changes in navigation. The passed callback will * be invoked with the new domain object of navigation when - * this changes. Callbacks can be registered to listen to pre or - * post-navigation events. The event to listen to is specified using - * the event parameter. In the case of pre-navigation events - * returning a false value will prevent the navigation event from - * going ahead. + * this changes. * @param {function} callback the callback to invoke when * navigation state changes - * @param {string} [event=after] the navigation event to listen to. - * One of 'before' or 'after'. */ - NavigationService.prototype.addListener = function (callback, event) { - event = event || 'after'; - this.callbacks[event] = this.callbacks[event] || []; - this.callbacks[event].push(callback); + NavigationService.prototype.addListener = function (callback) { + this.callbacks.push(callback); }; /** @@ -99,12 +78,9 @@ define( * @param {function} callback the callback which should * no longer be invoked when navigation state * changes - * @param {string} [event=after] the navigation event that the - * callback is registered to. One of 'before' or 'after'. */ - NavigationService.prototype.removeListener = function (callback, event) { - event = event || 'after'; - this.callbacks[event] = this.callbacks[event].filter(function (cb) { + NavigationService.prototype.removeListener = function (callback) { + this.callbacks = this.callbacks.filter(function (cb) { return cb !== callback; }); }; diff --git a/platform/commonUI/browse/test/BrowseControllerSpec.js b/platform/commonUI/browse/test/BrowseControllerSpec.js index caab0ed7d8..e40e39f6ef 100644 --- a/platform/commonUI/browse/test/BrowseControllerSpec.js +++ b/platform/commonUI/browse/test/BrowseControllerSpec.js @@ -39,6 +39,8 @@ define( mockUrlService, mockDomainObject, mockNextObject, + mockWindow, + mockPolicyService, testDefaultRoot, controller; @@ -55,14 +57,25 @@ define( mockScope, mockRoute, mockLocation, + mockWindow, mockObjectService, mockNavigationService, mockUrlService, + mockPolicyService, testDefaultRoot ); } beforeEach(function () { + mockWindow = jasmine.createSpyObj('$window', [ + "confirm" + ]); + mockWindow.confirm.andReturn(true); + + mockPolicyService = jasmine.createSpyObj('policyService', [ + 'allow' + ]); + testDefaultRoot = "some-root-level-domain-object"; mockScope = jasmine.createSpyObj( diff --git a/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js b/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js index 3a354dee78..410a5f1562 100644 --- a/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js +++ b/platform/commonUI/browse/test/navigation/NavigationServiceSpec.js @@ -84,24 +84,6 @@ define( expect(callback).not.toHaveBeenCalled(); }); - it("adds listeners to the 'after' state by default", function(){ - expect(navigationService.callbacks.after).toBeUndefined(); - navigationService.addListener(function(){}); - expect(navigationService.callbacks.after).toBeDefined(); - expect(navigationService.callbacks.after.length).toBe(1); - }); - - it("allows navigationService events to be prevented", function(){ - var callback = jasmine.createSpy("callback"), - navigationResult; - callback.andReturn(false); - navigationService.addListener(callback, "before"); - navigationResult = navigationService.setNavigation({}); - expect(callback).toHaveBeenCalled(); - expect(navigationResult).toBe(false); - - }); - }); } ); diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index 2e0e0a93f3..7fbc5e7f31 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -34,6 +34,7 @@ define([ "./src/actions/SaveAction", "./src/actions/CancelAction", "./src/policies/EditActionPolicy", + "./src/policies/EditNavigationPolicy", "./src/representers/EditRepresenter", "./src/representers/EditToolbarRepresenter", "text!./res/templates/library.html", @@ -55,6 +56,7 @@ define([ SaveAction, CancelAction, EditActionPolicy, + EditNavigationPolicy, EditRepresenter, EditToolbarRepresenter, libraryTemplate, @@ -95,7 +97,8 @@ define([ "implementation": EditObjectController, "depends": [ "$scope", - "$location" + "$location", + "policyService" ] } ], @@ -183,7 +186,16 @@ define([ { "category": "action", "implementation": EditActionPolicy + }, + { + "category": "navigation", + "message": "There are unsaved changes.", + "implementation": EditNavigationPolicy, + "depends": [ + "$window" + ] } + ], "templates": [ { diff --git a/platform/commonUI/edit/src/capabilities/EditorCapability.js b/platform/commonUI/edit/src/capabilities/EditorCapability.js index f674880203..b48c1988e6 100644 --- a/platform/commonUI/edit/src/capabilities/EditorCapability.js +++ b/platform/commonUI/edit/src/capabilities/EditorCapability.js @@ -124,7 +124,6 @@ define( */ EditorCapability.prototype.cancel = function () { this.editableObject.getCapability("status").set("editing", false); - //TODO: Reset the cache as well here. this.cache.markClean(); return resolvePromise(undefined); }; diff --git a/platform/commonUI/edit/src/controllers/EditObjectController.js b/platform/commonUI/edit/src/controllers/EditObjectController.js index e46d5cffe1..d6121106ec 100644 --- a/platform/commonUI/edit/src/controllers/EditObjectController.js +++ b/platform/commonUI/edit/src/controllers/EditObjectController.js @@ -36,8 +36,9 @@ define( * @memberof platform/commonUI/edit * @constructor */ - function EditObjectController($scope, $location) { + function EditObjectController($scope, $location, policyService) { this.scope = $scope; + this.policyService = policyService; var navigatedObject; function setViewForDomainObject(domainObject) { @@ -73,16 +74,14 @@ define( */ EditObjectController.prototype.getUnloadWarning = function () { var navigatedObject = this.scope.domainObject, - editorCapability = navigatedObject && - navigatedObject.getCapability("editor"), - statusCapability = navigatedObject && - navigatedObject.getCapability("status"), - hasChanges = statusCapability && statusCapability.get('editing') - && editorCapability && editorCapability.dirty(); + policyMessage; + + this.policyService.allow("navigation", navigatedObject, undefined, function(message) { + policyMessage = message; + }); + + return policyMessage; - return hasChanges ? - "Unsaved changes will be lost if you leave this page." : - undefined; }; return EditObjectController; diff --git a/platform/commonUI/edit/src/directives/MCTBeforeUnload.js b/platform/commonUI/edit/src/directives/MCTBeforeUnload.js index 226e85f4a0..3e7501c788 100644 --- a/platform/commonUI/edit/src/directives/MCTBeforeUnload.js +++ b/platform/commonUI/edit/src/directives/MCTBeforeUnload.js @@ -35,7 +35,7 @@ define( * @constructor * @param $window the window */ - function MCTBeforeUnload($window, navigationService) { + function MCTBeforeUnload($window) { var unloads = [], oldBeforeUnload = $window.onbeforeunload; @@ -57,7 +57,6 @@ define( // Stop using this unload expression function removeUnload() { - navigationService.removeListener(checkNavigationEvent, "before"); unloads = unloads.filter(function (callback) { return callback !== unload; }); @@ -66,28 +65,17 @@ define( } } - function shouldAllowNavigation(){ + // Show a dialog before allowing a location change + function checkLocationChange(event) { // Get an unload message (if any) var warning = unload(); // Prompt the user if there's an unload message - return !warning || $window.confirm(warning); - } - - // Show a dialog before allowing a location change - function checkLocationChange(event) { - if (!shouldAllowNavigation()) { - // Prevent the route change if it was confirmed + if (warning && !$window.confirm(warning)) { + // ...and prevent the route change if it was confirmed event.preventDefault(); } } - // Show a dialog before allowing a location change - function checkNavigationEvent(event) { - // Return a false value to the navigationService to - // indicate that the navigation event should be prevented - return shouldAllowNavigation(); - } - // If this is the first active instance of this directive, // register as the window's beforeunload handler if (unloads.length === 0) { @@ -102,8 +90,6 @@ define( // Also handle route changes scope.$on("$locationChangeStart", checkLocationChange); - - navigationService.addListener(checkNavigationEvent, "before"); } return { diff --git a/platform/commonUI/edit/src/policies/EditNavigationPolicy.js b/platform/commonUI/edit/src/policies/EditNavigationPolicy.js new file mode 100644 index 0000000000..625f040a66 --- /dev/null +++ b/platform/commonUI/edit/src/policies/EditNavigationPolicy.js @@ -0,0 +1,68 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define*/ + +define( + [], + function () { + "use strict"; + + /** + * Policy controlling whether navigation events should proceed + * when object is being edited. + * @memberof platform/commonUI/edit + * @constructor + * @implements {Policy.} + */ + function EditNavigationPolicy($window, policyService) { + this.window = $window; + this.policyService = policyService; + } + + /** + * @private + */ + EditNavigationPolicy.prototype.isDirty = function(domainObject) { + var navigatedObject = domainObject, + editorCapability = navigatedObject && + navigatedObject.getCapability("editor"), + statusCapability = navigatedObject && + navigatedObject.getCapability("status"); + + return statusCapability && statusCapability.get('editing') + && editorCapability && editorCapability.dirty(); + }; + + /** + * Allow navigation if an object is not dirty, or if the user elects + * to proceed anyway. + * @param currentNavigation + * @returns {boolean|*} true if the object model is clean; or if + * it's dirty and the user wishes to proceed anyway. + */ + EditNavigationPolicy.prototype.allow = function (currentNavigation) { + return !this.isDirty(currentNavigation); + }; + + return EditNavigationPolicy; + } +); diff --git a/platform/commonUI/edit/src/representers/EditRepresenter.js b/platform/commonUI/edit/src/representers/EditRepresenter.js index 5d96aeaf78..533c8031e0 100644 --- a/platform/commonUI/edit/src/representers/EditRepresenter.js +++ b/platform/commonUI/edit/src/representers/EditRepresenter.js @@ -147,7 +147,6 @@ define( // Respond to the destruction of the current representation. EditRepresenter.prototype.destroy = function destroy() { - // Nothing to clean up return this.listenHandle && this.listenHandle(); }; diff --git a/platform/commonUI/edit/test/controllers/EditControllerSpec.js b/platform/commonUI/edit/test/controllers/EditControllerSpec.js index 0a39874eb8..0af357f9c0 100644 --- a/platform/commonUI/edit/test/controllers/EditControllerSpec.js +++ b/platform/commonUI/edit/test/controllers/EditControllerSpec.js @@ -33,6 +33,7 @@ define( mockLocation, mockStatusCapability, mockCapabilities, + mockPolicyService, controller; // Utility function; look for a $watch on scope and fire it @@ -45,6 +46,12 @@ define( } beforeEach(function () { + mockPolicyService = jasmine.createSpyObj( + "policyService", + [ + "allow" + ] + ); mockScope = jasmine.createSpyObj( "$scope", [ "$on", "$watch" ] diff --git a/platform/representation/src/gestures/DropGesture.js b/platform/representation/src/gestures/DropGesture.js index 225211c3bd..a8ff9ac397 100644 --- a/platform/representation/src/gestures/DropGesture.js +++ b/platform/representation/src/gestures/DropGesture.js @@ -128,8 +128,7 @@ define( var typeKey = 'telemetry.panel', type = typeService.getType(typeKey), model = type.getInitialModel(), - newPanel, - composeAction; + newPanel; model.type = typeKey; newPanel = new EditableDomainObject(instantiate(model), $q); @@ -166,16 +165,12 @@ define( editableDomainObject = createVirtualPanel(domainObject, selectedObject); if (editableDomainObject) { editableDomainObject.getCapability('action').perform('edit'); - //navigationService.setNavigation(editableDomainObject); broadcastDrop(id, event); - //editableDomainObject.getCapability('status').set('editing', true); } } else { $q.when(action && action.perform()).then(function (result) { //Don't go into edit mode for folders if (domainObjectType!=='folder') { - // navigationService.setNavigation(editableDomainObject); - //editableDomainObject.getCapability('status').set('editing', true); editableDomainObject.getCapability('action').perform('edit'); } broadcastDrop(id, event); From 7b5218c5ba1a409f65d20dfc607cc6d15a599044 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 2 Mar 2016 10:14:25 -0800 Subject: [PATCH 8/9] [Edit Mode] #627 Fixed failing tests Removed reference to defunct NavigationServiceDecorator Removed virtual panels from drop gesture --- platform/commonUI/browse/bundle.js | 6 ++ .../browse/test/BrowseControllerSpec.js | 6 +- .../test/controllers/EditControllerSpec.js | 16 ++--- .../test/directives/MCTBeforeUnloadSpec.js | 11 +--- .../src/gestures/DropGesture.js | 63 +++---------------- 5 files changed, 29 insertions(+), 73 deletions(-) diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index 388d484bb1..9b6e37fbe9 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -248,6 +248,12 @@ define([ "implementation": NavigationService } ], + "services": [ + { + "key": "navigationService", + "implementation": NavigationService + } + ], "policies": [ { "implementation": CreationPolicy, diff --git a/platform/commonUI/browse/test/BrowseControllerSpec.js b/platform/commonUI/browse/test/BrowseControllerSpec.js index e40e39f6ef..cc14b4d0e5 100644 --- a/platform/commonUI/browse/test/BrowseControllerSpec.js +++ b/platform/commonUI/browse/test/BrowseControllerSpec.js @@ -256,7 +256,11 @@ define( it("after failed navigation event resets the selected tree" + " object", function () { mockScope.navigatedObject = mockDomainObject; - mockNavigationService.setNavigation.andReturn(false); + mockWindow.confirm.andReturn(false); + mockPolicyService.allow.andCallFake(function(category, object, context, callback){ + callback("unsaved changes"); + return false; + }); //Simulate a change in selected tree object mockScope.treeModel = {selectedObject: mockDomainObject}; diff --git a/platform/commonUI/edit/test/controllers/EditControllerSpec.js b/platform/commonUI/edit/test/controllers/EditControllerSpec.js index 0af357f9c0..0ed0ddecc7 100644 --- a/platform/commonUI/edit/test/controllers/EditControllerSpec.js +++ b/platform/commonUI/edit/test/controllers/EditControllerSpec.js @@ -89,25 +89,25 @@ define( controller = new EditObjectController( mockScope, - mockLocation + mockLocation, + mockPolicyService ); }); it("exposes a warning message for unload", function () { var obj = mockObject, - mockEditor = jasmine.createSpyObj('editor', ['dirty']); + errorMessage = "Unsaved changes"; // Normally, should be undefined expect(controller.getUnloadWarning()).toBeUndefined(); - // Override the object's editor capability, make it look - // like there are unsaved changes. - mockCapabilities.editor = mockEditor; - mockEditor.dirty.andReturn(true); - mockStatusCapability.get.andReturn(true); + // Override the policy service to prevent navigation + mockPolicyService.allow.andCallFake(function(category, object, context, callback){ + callback(errorMessage); + }); // Should have some warning message here now - expect(controller.getUnloadWarning()).toEqual(jasmine.any(String)); + expect(controller.getUnloadWarning()).toEqual(errorMessage); }); diff --git a/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js b/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js index fd94e3e90d..41070d76f5 100644 --- a/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js +++ b/platform/commonUI/edit/test/directives/MCTBeforeUnloadSpec.js @@ -31,7 +31,6 @@ define( mockScope, testAttrs, mockEvent, - mockNavigationService, directive; function fireListener(eventType, value) { @@ -47,8 +46,7 @@ define( mockScope = jasmine.createSpyObj("$scope", ['$eval', '$on']); testAttrs = { mctBeforeUnload: "someExpression" }; mockEvent = jasmine.createSpyObj("event", ["preventDefault"]); - mockNavigationService = jasmine.createSpyObj("navigationService", ["addListener", "removeListener"]); - directive = new MCTBeforeUnload(mockWindow, mockNavigationService); + directive = new MCTBeforeUnload(mockWindow); directive.link(mockScope, {}, testAttrs); }); @@ -67,10 +65,6 @@ define( ); }); - it("listens for navigation changes", function () { - expect(mockNavigationService.addListener).toHaveBeenCalledWith(jasmine.any(Function), "before"); - }); - it("listens for its scope's destroy event", function () { expect(mockScope.$on).toHaveBeenCalledWith( "$destroy", @@ -114,10 +108,9 @@ define( it("cleans up listeners when destroyed", function () { fireListener("$destroy", mockEvent); expect(mockWindow.onbeforeunload).toBeUndefined(); - expect(mockNavigationService.removeListener).toHaveBeenCalled(); }); }); } -); +); \ No newline at end of file diff --git a/platform/representation/src/gestures/DropGesture.js b/platform/representation/src/gestures/DropGesture.js index a8ff9ac397..1e884c14f7 100644 --- a/platform/representation/src/gestures/DropGesture.js +++ b/platform/representation/src/gestures/DropGesture.js @@ -80,13 +80,6 @@ define( }).length > 0; } - function shouldCreateVirtualPanel(domainObject){ - return domainObject.useCapability('view').filter(function (view){ - return (view.key === 'plot' || view.key === 'scrolling') - && domainObject.getModel().type !== 'telemetry.panel'; - }).length > 0; - } - function dragOver(e) { //Refresh domain object on each dragOver to catch external // updates to the model @@ -111,9 +104,7 @@ define( key: 'compose', selectedObject: selectedObject })[0]; - //TODO: Fix this. Define an action for creating new - // virtual panel - if (action || shouldCreateVirtualPanel(domainObject, selectedObject)) { + if (action) { event.dataTransfer.dropEffect = 'move'; // Indicate that we will accept the drag @@ -123,61 +114,23 @@ define( } } - function createVirtualPanel(base, selectedObject){ - - var typeKey = 'telemetry.panel', - type = typeService.getType(typeKey), - model = type.getInitialModel(), - newPanel; - - model.type = typeKey; - newPanel = new EditableDomainObject(instantiate(model), $q); - if (!canCompose(newPanel, selectedObject)) { - return undefined; - } - - [base.getId(), selectedObject.getId()].forEach(function(id){ - newPanel.getCapability('composition').add(id); - }); - - newPanel.getCapability('location') - .setPrimaryLocation(base.getCapability('location') - .getContextualLocation()); - - newPanel.setOriginalObject(base); - return newPanel; - - } - function drop(e) { var event = (e || {}).originalEvent || e, id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE), - domainObjectType = editableDomainObject.getModel().type, - selectedObject = dndService.getData( - GestureConstants.MCT_EXTENDED_DRAG_TYPE - ); - + domainObjectType = editableDomainObject.getModel().type; + // Handle the drop; add the dropped identifier to the // destination domain object's composition, and persist // the change. if (id) { - if (shouldCreateVirtualPanel(domainObject, selectedObject)){ - editableDomainObject = createVirtualPanel(domainObject, selectedObject); - if (editableDomainObject) { + $q.when(action && action.perform()).then(function (result) { + //Don't go into edit mode for folders + if (domainObjectType!=='folder') { editableDomainObject.getCapability('action').perform('edit'); - broadcastDrop(id, event); } - } else { - $q.when(action && action.perform()).then(function (result) { - //Don't go into edit mode for folders - if (domainObjectType!=='folder') { - editableDomainObject.getCapability('action').perform('edit'); - } - broadcastDrop(id, event); - }); - } + broadcastDrop(id, event); + }); } - // TODO: Alert user if drag and drop is not allowed } // We can only handle drops if we have access to actions... From 670c06103f10b635b3128b66346e62b84610da2b Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 2 Mar 2016 11:45:15 -0800 Subject: [PATCH 9/9] [Edit Mode] Rebased over master --- platform/commonUI/browse/bundle.js | 10 +--------- platform/commonUI/browse/src/BrowseController.js | 4 +--- platform/commonUI/browse/src/BrowseObjectController.js | 2 +- platform/commonUI/edit/bundle.js | 5 +---- .../commonUI/edit/src/policies/EditNavigationPolicy.js | 3 +-- 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index 9b6e37fbe9..7fd785a7f5 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -135,9 +135,7 @@ define([ "depends": [ "$scope", "$location", - "$route", - "$q", - "navigationService" + "$route" ] }, { @@ -248,12 +246,6 @@ define([ "implementation": NavigationService } ], - "services": [ - { - "key": "navigationService", - "implementation": NavigationService - } - ], "policies": [ { "implementation": CreationPolicy, diff --git a/platform/commonUI/browse/src/BrowseController.js b/platform/commonUI/browse/src/BrowseController.js index 54a230682c..db7d9182cb 100644 --- a/platform/commonUI/browse/src/BrowseController.js +++ b/platform/commonUI/browse/src/BrowseController.js @@ -32,9 +32,7 @@ define( function (GestureConstants) { "use strict"; - var ROOT_ID = "ROOT", - DEFAULT_PATH = "mine", - CONFIRM_MSG = "Unsaved changes will be lost if you leave this page."; + var ROOT_ID = "ROOT"; /** * The BrowseController is used to populate the initial scope in Browse diff --git a/platform/commonUI/browse/src/BrowseObjectController.js b/platform/commonUI/browse/src/BrowseObjectController.js index daf157e2c3..71345d6f1b 100644 --- a/platform/commonUI/browse/src/BrowseObjectController.js +++ b/platform/commonUI/browse/src/BrowseObjectController.js @@ -32,7 +32,7 @@ define( * @memberof platform/commonUI/browse * @constructor */ - function BrowseObjectController($scope, $location, $route, $q, navigationService) { + function BrowseObjectController($scope, $location, $route) { var navigatedObject; function setViewForDomainObject(domainObject) { diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index 7fbc5e7f31..80a98a6927 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -190,10 +190,7 @@ define([ { "category": "navigation", "message": "There are unsaved changes.", - "implementation": EditNavigationPolicy, - "depends": [ - "$window" - ] + "implementation": EditNavigationPolicy } ], diff --git a/platform/commonUI/edit/src/policies/EditNavigationPolicy.js b/platform/commonUI/edit/src/policies/EditNavigationPolicy.js index 625f040a66..882e64935e 100644 --- a/platform/commonUI/edit/src/policies/EditNavigationPolicy.js +++ b/platform/commonUI/edit/src/policies/EditNavigationPolicy.js @@ -33,8 +33,7 @@ define( * @constructor * @implements {Policy.} */ - function EditNavigationPolicy($window, policyService) { - this.window = $window; + function EditNavigationPolicy(policyService) { this.policyService = policyService; }