Merge browse files from branch 'mobile' into open72

This commit is contained in:
slhale 2015-08-19 13:04:11 -07:00
parent f4b87cf70d
commit 8dad6a3fd5
4 changed files with 400 additions and 18 deletions

View File

@ -19,30 +19,33 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div content="jquery-wrapper" class="abs holder-all browse-mode">
<div content="jquery-wrapper" class="abs holder-all browse-mode" ng-controller="BrowseController">
<mct-include key="'topbar-browse'"></mct-include>
<div class="holder browse-area s-browse-area abs" ng-controller="BrowseController">
<div class="holder browse-area s-browse-area abs browse-wrapper" ng-class="treeClass ? 'browse-showtree' : 'browse-hidetree'">
<mct-split-pane class='contents abs' anchor='left'>
<div
class='split-pane-component treeview pane left'
>
<mct-representation key="'create-button'" mct-object="navigatedObject">
</mct-representation>
<div class='holder tree-holder abs'>
<div class='split-pane-component treeview pane mobile-pane left-menu desktop-browse'>
<div class='holder tree-holder abs mobile-tree-holder'>
<mct-representation key="'tree'"
mct-object="domainObject"
ng-model="treeModel">
</mct-representation>
</div>
</div>
<mct-splitter></mct-splitter>
<div class='split-pane-component items pane'>
<div class='holder abs' id='content-area'>
<mct-representation mct-object="navigatedObject" key="'browse-object'">
<mct-representation key="'create-button'" mct-object="navigatedObject">
</mct-representation>
</div>
</div>
<mct-splitter class="mobile-hide"></mct-splitter>
<div class='split-pane-component items pane mobile-pane right-repr'>
<div class='holder abs' id='content-area'>
<mct-representation mct-object="navigatedObject" key="'browse-object'">
</mct-representation>
</div>
<div class="left s-very-subtle key-properties ui-symbol mobile-menu-icon button-pos"
ng-click="treeSlide()">m</div>
</div>
</mct-split-pane>
</div>
<mct-include key="'bottombar'"></mct-include>
</div>

View File

@ -63,7 +63,6 @@ define(
// path to new, addressed, path based on
// domainObject
$location.path(urlService.urlForLocation("browse", domainObject));
}
// Callback for updating the in-scope reference to the object
@ -126,6 +125,36 @@ 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 parent = navigationService.getNavigation().getCapability('context').getParent(),
grandparent;
if (parent.getId() !== ROOT_ID) {
grandparent = parent.getCapability('context').getParent().getId();
navigateTo(parent);
if (grandparent && grandparent !== ROOT_ID) {
$scope.atRoot = false;
} else {
$scope.atRoot = true;
}
} else {
$scope.atRoot = true;
}
}
function checkRoot() {
var parent = navigationService.getNavigation().getCapability('context').getParent();
if (parent.getId() !== ROOT_ID) {
$scope.atRoot = false;
} else {
$scope.atRoot = true;
}
}
// Load the root object, put it in the scope.
// Also, load its immediate children, and (possibly)
@ -140,7 +169,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);
@ -151,6 +186,10 @@ define(
$scope.$on("$destroy", function () {
navigationService.removeListener(setNavigation);
});
$scope.backArrow = navigateToParent;
$scope.checkRoot = checkRoot;
}

View File

@ -39,6 +39,9 @@ define(
mockUrlService,
mockDomainObject,
mockNextObject,
mockParentContext,
mockParent,
mockGrandparent,
controller;
function mockPromise(value) {
@ -52,7 +55,7 @@ define(
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
[ "$on", "$watch" ]
[ "$on", "$watch", "treeSlide", "backArrow" ]
);
mockRoute = { current: { params: {} } };
mockLocation = jasmine.createSpyObj(
@ -88,6 +91,17 @@ define(
"nextObject",
[ "getId", "getCapability", "getModel", "useCapability" ]
);
mockParentContext = jasmine.createSpyObj('context', ['getParent']);
mockParent = jasmine.createSpyObj(
"domainObject",
[ "getId", "getCapability", "getModel", "useCapability" ]
);
mockGrandparent = jasmine.createSpyObj(
"domainObject",
[ "getId", "getCapability", "getModel", "useCapability" ]
);
mockObjectService.getObjects.andReturn(mockPromise({
ROOT: mockRootObject
@ -145,6 +159,13 @@ define(
);
expect(mockScope.navigatedObject).toEqual(mockDomainObject);
});
// Mocks the tree slide call that
// lets the html code know if the
// tree menu is open.
it("calls the treeSlide function", function () {
mockScope.treeSlide();
});
it("releases its navigation listener when its scope is destroyed", function () {
expect(mockScope.$on).toHaveBeenCalledWith(
@ -237,7 +258,104 @@ define(
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();
});
// 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();
});
});
}
);

View File

@ -0,0 +1,222 @@
/*****************************************************************************
* 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.
*****************************************************************************/
// Wrapper of the entire 2 panes, only enacted on
// phone and tablet. Also for the panes
.browse-wrapper,
.mobile-pane {
@include phoneandtablet {
position: absolute;
left: 0; top: 0;
right: 0;
white-space: nowrap;
}
}
// Default views of the panels
// if in desktop browser
.desktop-browse {
@include desktop {
min-width: 150px;
max-width: 800px;
width: $desktopMenuSize;
}
}
// When the tree is hidden, these are the
// classes used for the left menu and the
// right representation.
.browse-hidetree {
// NOTE: DISABLED SELECTION
// Selection disabled in both panes
// causing cut/copy/paste menu to
// not appear. Should me moved in
// future to properly work
@include phoneandtablet {
@include user-select(none);
}
// Sets the left tree menu when the tree
// is hidden.
.mobile-pane.left-menu {
@include phoneandtablet {
@include trans-prop-nice(opacity, .4s);
opacity: 0;
right: 100% !important;
width: auto !important;
overflow-y: hidden;
overflow-x: hidden;
}
}
// Sets the right represenation when
// the tree is hidden.
.mobile-pane.right-repr {
@include phoneandtablet {
@include slMenuTransitions;
left: auto !important;
width: 100% !important;
}
}
}
.mobile-tree-holder {
top: 30px;
}
// When the tree is shown, these are
// the classes used for the left menu
// and the right menu (for each device &
// orientation combination, separate
// parameters are used)
.browse-showtree {
// NOTE: DISABLED SELECTION
// Selection disabled in both panes
// causing cut/copy/paste menu to
// not appear. Should me moved in
// future to properly work
@include phoneandtablet {
@include user-select(none);
}
// Sets the left tree menu when the tree
// is shown.
.mobile-pane.left-menu {
@include phoneandtablet {
@include trans-prop-nice(opacity, .4s);
opacity: 1;
display: block !important;
width: auto !important;
}
// On both phones and tablets, the amount of
// space allowed for the right pane is specified
@include phonePortrait {
right: $phoneRepSizePortrait !important;
}
@include phoneLandscape {
right: $phoneRepSizeLandscape !important;
}
@include tabletPortrait {
right: $tabletRepSizePortrait !important;
}
@include tabletLandscape {
right: $tabletRepSizeLandscape !important;
}
}
// Sets the right represenation when
// the tree is shown.
.mobile-pane.right-repr {
@include phoneandtablet {
@include slMenuTransitions;
left: auto !important;
}
// On both phones and tablets, the width of
// the right pane is specified
@include phonePortrait {
width: $phoneRepSizePortrait !important;
}
@include phoneLandscape {
width: $phoneRepSizeLandscape !important;
}
@include tabletPortrait {
width: $tabletRepSizePortrait !important;
}
@include tabletLandscape {
width: $tabletRepSizeLandscape !important;
}
}
}
// Button position is set as absolute with transitions
.button-pos {
@include phoneandtablet {
position: absolute;
}
}
// Object header must be moved
// over to make space for the
// hamburger icon
.object-header {
@include phoneandtablet {
position: relative;
left: 44px;
.label {
.context-available {
opacity: 1 !important;
}
}
}
}
.desktop-hide {
@include desktop {
display: none;
}
}
// Hides objects on phone and tablet
.mobile-hide {
@include phoneandtablet {
display: none;
}
}
.mobile-important-hide {
@include phoneandtablet {
display: none !important;
}
}
.mobile-back-hide {
@include phoneandtablet {
pointer-events: none;
@include trans-prop-nice(opacity, .4s);
opacity: 0;
}
}
// Hides objects on phone and tablet
.mobile-back-unhide {
@include phoneandtablet {
pointer-events: all;
@include trans-prop-nice(opacity, .4s);
opacity: 1;
}
}
// Hides objects only on the phone
.phone-hide {
@include phone {
display: none;
}
}
.tree-holder {
@include phoneandtablet {
overflow-x: hidden !important;
}
}
.mobile-disable-select {
@include phoneandtablet {
@include user-select(none);
}
}