[Browse] Separate out back-arrow behavior

Supports integration of changes for mobile, nasa/openmct#95
This commit is contained in:
Victor Woeltjen 2015-09-15 12:06:35 -07:00
parent de6dfe1fdc
commit d981e7bb1d
6 changed files with 100 additions and 210 deletions

View File

@ -16,7 +16,14 @@
{
"key": "BrowseController",
"implementation": "BrowseController.js",
"depends": [ "$scope", "$route", "$location", "objectService", "navigationService", "urlService" ]
"depends": [
"$scope",
"$route",
"$location",
"objectService",
"navigationService",
"urlService"
]
},
{
"key": "BrowseObjectController",
@ -25,17 +32,22 @@
},
{
"key": "CreateMenuController",
"implementation": "creation/CreateMenuController",
"implementation": "creation/CreateMenuController.js",
"depends": [ "$scope" ]
},
{
"key": "LocatorController",
"implementation": "creation/LocatorController",
"implementation": "creation/LocatorController.js",
"depends": [ "$scope", "$timeout" ]
},
{
"key": "MenuArrowController",
"implementation": "MenuArrowController",
"implementation": "MenuArrowController.js",
"depends": [ "$scope" ]
},
{
"key": "BackArrowController",
"implementation": "BackArrowController.js",
"depends": [ "$scope" ]
}
],

View File

@ -21,8 +21,7 @@
-->
<!-- Back Arrow Icon used on mobile-->
<a ng-controller="BrowseController"
<a ng-controller="BackArrowController"
class='type-icon icon ui-symbol s-back'
ng-class="checkRoot(); atRoot ? 'hidden' : ''"
ng-click='backArrow()'>{
</a>
ng-hide="atRoot"
ng-click='navigateToParent()'>{</a>

View File

@ -22,7 +22,9 @@
<span ng-controller="BrowseObjectController">
<div class="object-browse-bar bar l-flex">
<div class="items-select left">
<mct-representation key="'back-arrow'" class="l-back"></mct-representation>
<mct-representation key="'back-arrow'"
mct-object="domainObject"
class="l-back"></mct-representation>
<mct-representation key="'object-header'" mct-object="domainObject">
</mct-representation>
</div>

View File

@ -0,0 +1,64 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
function () {
'use strict';
function BackArrowController($scope) {
function navigateTo(parentObject) {
var action =
parentObject && parentObject.getCapability('action');
if (action) {
action.perform('navigate');
}
}
function navigateToParent() {
var domainObject = $scope.domainObject,
context =
domainObject && domainObject.getCapability('context');
if (context) {
navigateTo(context.getParent());
}
}
function checkRoot(domainObject) {
var context =
domainObject && domainObject.getCapability('context');
// We don't want to show the arrow if there is no context
// for this object, or if there is not a meaningful parent
// we can go back to.
$scope.atRoot = (!context) || (context.getPath().length < 3);
}
$scope.navigateToParent = navigateToParent;
$scope.$watch("domainObject", checkRoot);
}
return BackArrowController;
}
);

View File

@ -55,7 +55,7 @@ define(
unlisten = $scope.$on('$locationChangeSuccess', function () {
// Checks path to make sure /browse/ is at front
// if so, change $route.current
// if so, change $route.current
if ($location.path().indexOf("/browse/") === 0) {
$route.current = priorRoute;
}
@ -127,78 +127,6 @@ define(
navigateTo(domainObject);
}
}
// Uses the current navigation to get the
// current ContextCapability, then the
// parent is gotten from that. If the parent
// is not the root, then user is navigated to
// parent
function navigateToParent() {
var context = navigationService.getNavigation().getCapability('context'),
parentContext,
parent,
grandparentId;
// Checks if the current object has a context
if (context) {
// Sets the parent and the parent context
// which is checked
parent = context.getParent();
parentContext = parent.getCapability('context');
if ((parent.getId() !== ROOT_ID) && parentContext) {
// Gets the grandparent id
grandparentId = parentContext.getParent().getId();
// Navigates to the parent
navigateTo(parent);
// Checks after navigation if the user is located at the
// root (grandparent of original selected object, after
// navigation, user is at parent of original object and
// child of grandparent)
if (grandparentId && grandparentId !== ROOT_ID) {
$scope.atRoot = false;
return;
}
// Set at root if no grandparent exists and
// if grandparent is ROOT, after navigation
$scope.atRoot = true;
}
}
}
function checkRoot() {
var context = navigationService.getNavigation().getCapability('context'),
parentContext,
parent,
grandparent;
// Checks if the current object has a context
if (context) {
parent = context.getParent();
parentContext = parent.getCapability('context');
if ((parent.getId() !== ROOT_ID) && parentContext) {
grandparent = parentContext.getParent();
// Checks if the grandparent exists
// if it does not exist (for example in search),
// than do not show the back button
if (grandparent) {
$scope.atRoot = false;
return;
}
}
}
// In any other situation where the context or parent
// context does not exist or the user is at ROOT, than
// hide the back arrow
$scope.atRoot = true;
}
// Load the root object, put it in the scope.
// Also, load its immediate children, and (possibly)
@ -213,13 +141,13 @@ define(
$scope.treeModel = {
selectedObject: navigationService.getNavigation()
};
// SlideMenu boolean used to hide and show
// tree menu
$scope.treeSlide = function () {
$scope.treeClass = !$scope.treeClass;
};
// Listen for changes in navigation state.
navigationService.addListener(setNavigation);
@ -230,17 +158,12 @@ define(
$scope.$on("$destroy", function () {
navigationService.removeListener(setNavigation);
});
// If the user has selected an object (and is portrait
// on a phone), then hide the tree menu
$scope.$on("select-obj", function () {
$scope.treeSlide();
});
$scope.backArrow = navigateToParent;
$scope.checkRoot = checkRoot;
}
return BrowseController;

View File

@ -91,7 +91,7 @@ define(
"nextObject",
[ "getId", "getCapability", "getModel", "useCapability" ]
);
mockParentContext = jasmine.createSpyObj('context', ['getParent']);
mockParent = jasmine.createSpyObj(
@ -159,7 +159,7 @@ define(
);
expect(mockScope.navigatedObject).toEqual(mockDomainObject);
});
// Mocks the tree slide call that
// lets the html code know if the
// tree menu is open.
@ -168,7 +168,7 @@ define(
"select-obj",
jasmine.any(Function)
);
mockScope.$on.calls[1].args[1]();
});
@ -177,7 +177,7 @@ define(
"$destroy",
jasmine.any(Function)
);
mockScope.$on.calls[0].args[1]();
// Should remove the listener it added earlier
expect(mockNavigationService.removeListener).toHaveBeenCalledWith(
@ -249,132 +249,22 @@ define(
mockNavigationService.addListener.mostRecentCall.args[0](
mockNextObject
);
// Allows the path index to be checked
// prior to setting $route.current
// prior to setting $route.current
mockLocation.path.andReturn("/browse/");
// Exercise the Angular workaround
mockScope.$on.mostRecentCall.args[1]();
expect(mockUnlisten).toHaveBeenCalled();
// location.path to be called with the urlService's
// location.path to be called with the urlService's
// urlFor function with the next domainObject and mode
expect(mockLocation.path).toHaveBeenCalledWith(
mockUrlService.urlForLocation(mockMode, mockNextObject)
);
});
it("checks if the user is current navigated to the root", function () {
var mockContext = jasmine.createSpyObj('context', ['getParent']);
mockRoute.current.params.ids = "ROOT/mine";
mockParent.getId.andReturn("ROOT");
mockDomainObject.getCapability.andCallFake(function (c) {
return c === 'context' && mockContext;
});
mockNavigationService.getNavigation.andReturn(mockDomainObject);
mockContext.getParent.andReturn(mockParent);
mockParent.getCapability.andCallFake(function (c) {
return c === 'context' && mockParentContext;
});
mockParentContext.getParent.andReturn(mockGrandparent);
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService
);
mockScope.checkRoot();
mockRoute.current.params.ids = "mine/junk";
mockParent.getId.andReturn("mine");
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService
);
mockScope.checkRoot();
mockDomainObject.getCapability.andReturn(undefined);
mockNavigationService.getNavigation.andReturn(mockDomainObject);
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService
);
mockScope.checkRoot();
});
// Mocks the back arrow call that
// lets the html code know the back
// arrow navigation needs to be done
it("calls the backArrow function", function () {
var mockContext = jasmine.createSpyObj('context', ['getParent']);
mockRoute.current.params.ids = "mine/junk";
mockParent.getId.andReturn("mine");
mockDomainObject.getCapability.andCallFake(function (c) {
return c === 'context' && mockContext;
});
mockNavigationService.getNavigation.andReturn(mockDomainObject);
mockContext.getParent.andReturn(mockParent);
mockParent.getCapability.andCallFake(function (c) {
return c === 'context' && mockParentContext;
});
mockParentContext.getParent.andReturn(mockGrandparent);
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService
);
mockScope.backArrow();
mockRoute.current.params.ids = "mine/lessjunk/morejunk";
mockGrandparent.getId.andReturn("mine");
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService
);
mockScope.backArrow();
mockRoute.current.params.ids = "ROOT/mine";
mockParent.getId.andReturn("ROOT");
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService
);
mockScope.backArrow();
});
});
}
);