Merge pull request #8 from nasa/open1149
[Addressability] Use/populate URL
This commit is contained in:
@@ -2,19 +2,26 @@
|
|||||||
"extensions": {
|
"extensions": {
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
{
|
||||||
"when": "/browse",
|
"when": "/browse/:ids*",
|
||||||
"templateUrl": "templates/browse.html"
|
"templateUrl": "templates/browse.html",
|
||||||
|
"reloadOnSearch": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"when": "",
|
"when": "",
|
||||||
"templateUrl": "templates/browse.html"
|
"templateUrl": "templates/browse.html",
|
||||||
|
"reloadOnSearch": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"controllers": [
|
"controllers": [
|
||||||
{
|
{
|
||||||
"key": "BrowseController",
|
"key": "BrowseController",
|
||||||
"implementation": "BrowseController.js",
|
"implementation": "BrowseController.js",
|
||||||
"depends": [ "$scope", "objectService", "navigationService" ]
|
"depends": [ "$scope", "$route", "$location", "objectService", "navigationService" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "BrowseObjectController",
|
||||||
|
"implementation": "BrowseObjectController.js",
|
||||||
|
"depends": [ "$scope", "$location", "$route" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "CreateMenuController",
|
"key": "CreateMenuController",
|
||||||
@@ -151,4 +158,4 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<span>
|
<span ng-controller="BrowseObjectController">
|
||||||
<div class="object-browse-bar bar abs">
|
<div class="object-browse-bar bar abs">
|
||||||
<div class="items-select left abs">
|
<div class="items-select left abs">
|
||||||
<mct-representation key="'object-header'" mct-object="domainObject">
|
<mct-representation key="'object-header'" mct-object="domainObject">
|
||||||
@@ -44,4 +44,4 @@
|
|||||||
mct-object="representation.selected.key && domainObject">
|
mct-object="representation.selected.key && domainObject">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ define(
|
|||||||
function () {
|
function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ROOT_OBJECT = "ROOT";
|
var ROOT_ID = "ROOT",
|
||||||
|
DEFAULT_PATH = "mine";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The BrowseController is used to populate the initial scope in Browse
|
* The BrowseController is used to populate the initial scope in Browse
|
||||||
@@ -40,35 +41,98 @@ define(
|
|||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function BrowseController($scope, objectService, navigationService) {
|
function BrowseController($scope, $route, $location, objectService, navigationService) {
|
||||||
|
var path = [ROOT_ID].concat(
|
||||||
|
($route.current.params.ids || DEFAULT_PATH).split("/")
|
||||||
|
);
|
||||||
|
|
||||||
|
function updateRoute(domainObject) {
|
||||||
|
var context = domainObject &&
|
||||||
|
domainObject.getCapability('context'),
|
||||||
|
objectPath = context ? context.getPath() : [],
|
||||||
|
ids = objectPath.map(function (domainObject) {
|
||||||
|
return domainObject.getId();
|
||||||
|
}),
|
||||||
|
priorRoute = $route.current,
|
||||||
|
// Act as if params HADN'T changed to avoid page reload
|
||||||
|
unlisten;
|
||||||
|
|
||||||
|
unlisten = $scope.$on('$locationChangeSuccess', function () {
|
||||||
|
$route.current = priorRoute;
|
||||||
|
unlisten();
|
||||||
|
});
|
||||||
|
|
||||||
|
$location.path("/browse/" + ids.slice(1).join("/"));
|
||||||
|
}
|
||||||
|
|
||||||
// Callback for updating the in-scope reference to the object
|
// Callback for updating the in-scope reference to the object
|
||||||
// that is currently navigated-to.
|
// that is currently navigated-to.
|
||||||
function setNavigation(domainObject) {
|
function setNavigation(domainObject) {
|
||||||
$scope.navigatedObject = domainObject;
|
$scope.navigatedObject = domainObject;
|
||||||
$scope.treeModel.selectedObject = domainObject;
|
$scope.treeModel.selectedObject = domainObject;
|
||||||
navigationService.setNavigation(domainObject);
|
navigationService.setNavigation(domainObject);
|
||||||
|
updateRoute(domainObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigateTo(domainObject) {
|
||||||
|
// Check if an object has been navigated-to already...
|
||||||
|
// If not, or if an ID path has been explicitly set in the URL,
|
||||||
|
// navigate to the URL-specified object.
|
||||||
|
if (!navigationService.getNavigation() || $route.current.params.ids) {
|
||||||
|
// If not, pick a default as the last
|
||||||
|
// root-level component (usually "mine")
|
||||||
|
navigationService.setNavigation(domainObject);
|
||||||
|
$scope.navigatedObject = domainObject;
|
||||||
|
} else {
|
||||||
|
// Otherwise, just expose the currently navigated object.
|
||||||
|
$scope.navigatedObject = navigationService.getNavigation();
|
||||||
|
updateRoute($scope.navigatedObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findObject(domainObjects, id) {
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < domainObjects.length; i += 1) {
|
||||||
|
if (domainObjects[i].getId() === id) {
|
||||||
|
return domainObjects[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate to the domain object identified by path[index],
|
||||||
|
// which we expect to find in the composition of the passed
|
||||||
|
// domain object.
|
||||||
|
function doNavigate(domainObject, index) {
|
||||||
|
var composition = domainObject.useCapability("composition");
|
||||||
|
if (composition) {
|
||||||
|
composition.then(function (c) {
|
||||||
|
var nextObject = findObject(c, path[index]);
|
||||||
|
if (nextObject) {
|
||||||
|
if (index + 1 >= path.length) {
|
||||||
|
navigateTo(nextObject);
|
||||||
|
} else {
|
||||||
|
doNavigate(nextObject, index + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Couldn't find the next element of the path
|
||||||
|
// so navigate to the last path object we did find
|
||||||
|
navigateTo(domainObject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Similar to above case; this object has no composition,
|
||||||
|
// so navigate to it instead of subsequent path elements.
|
||||||
|
navigateTo(domainObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the root object, put it in the scope.
|
// Load the root object, put it in the scope.
|
||||||
// Also, load its immediate children, and (possibly)
|
// Also, load its immediate children, and (possibly)
|
||||||
// navigate to one of them, so that navigation state has
|
// navigate to one of them, so that navigation state has
|
||||||
// a useful initial value.
|
// a useful initial value.
|
||||||
objectService.getObjects([ROOT_OBJECT]).then(function (objects) {
|
objectService.getObjects([path[0]]).then(function (objects) {
|
||||||
var composition = objects[ROOT_OBJECT].useCapability("composition");
|
$scope.domainObject = objects[path[0]];
|
||||||
$scope.domainObject = objects[ROOT_OBJECT];
|
doNavigate($scope.domainObject, 1);
|
||||||
if (composition) {
|
|
||||||
composition.then(function (c) {
|
|
||||||
// Check if an object has been navigated-to already...
|
|
||||||
if (!navigationService.getNavigation()) {
|
|
||||||
// If not, pick a default as the last
|
|
||||||
// root-level component (usually "mine")
|
|
||||||
navigationService.setNavigation(c[c.length - 1]);
|
|
||||||
} else {
|
|
||||||
// Otherwise, just expose it in the scope
|
|
||||||
$scope.navigatedObject = navigationService.getNavigation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Provide a model for the tree to modify
|
// Provide a model for the tree to modify
|
||||||
@@ -91,4 +155,4 @@ define(
|
|||||||
|
|
||||||
return BrowseController;
|
return BrowseController;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
69
platform/commonUI/browse/src/BrowseObjectController.js
Normal file
69
platform/commonUI/browse/src/BrowseObjectController.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the `browse-object` representation of a domain
|
||||||
|
* object (the right-hand side of Browse mode.)
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function BrowseObjectController($scope, $location, $route) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateQueryParam(viewKey) {
|
||||||
|
var unlisten, priorRoute = $route.current;
|
||||||
|
|
||||||
|
if (viewKey) {
|
||||||
|
$location.search('view', viewKey);
|
||||||
|
unlisten = $scope.$on('$locationChangeSuccess', function () {
|
||||||
|
$route.current = priorRoute;
|
||||||
|
unlisten();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.$watch('domainObject', setViewForDomainObject);
|
||||||
|
$scope.$watch('representation.selected.key', updateQueryParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BrowseObjectController;
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -31,10 +31,13 @@ define(
|
|||||||
|
|
||||||
describe("The browse controller", function () {
|
describe("The browse controller", function () {
|
||||||
var mockScope,
|
var mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
mockObjectService,
|
mockObjectService,
|
||||||
mockNavigationService,
|
mockNavigationService,
|
||||||
mockRootObject,
|
mockRootObject,
|
||||||
mockDomainObject,
|
mockDomainObject,
|
||||||
|
mockNextObject,
|
||||||
controller;
|
controller;
|
||||||
|
|
||||||
function mockPromise(value) {
|
function mockPromise(value) {
|
||||||
@@ -50,6 +53,11 @@ define(
|
|||||||
"$scope",
|
"$scope",
|
||||||
[ "$on", "$watch" ]
|
[ "$on", "$watch" ]
|
||||||
);
|
);
|
||||||
|
mockRoute = { current: { params: {} } };
|
||||||
|
mockLocation = jasmine.createSpyObj(
|
||||||
|
"$location",
|
||||||
|
[ "path" ]
|
||||||
|
);
|
||||||
mockObjectService = jasmine.createSpyObj(
|
mockObjectService = jasmine.createSpyObj(
|
||||||
"objectService",
|
"objectService",
|
||||||
[ "getObjects" ]
|
[ "getObjects" ]
|
||||||
@@ -71,25 +79,38 @@ define(
|
|||||||
"domainObject",
|
"domainObject",
|
||||||
[ "getId", "getCapability", "getModel", "useCapability" ]
|
[ "getId", "getCapability", "getModel", "useCapability" ]
|
||||||
);
|
);
|
||||||
|
mockNextObject = jasmine.createSpyObj(
|
||||||
|
"nextObject",
|
||||||
|
[ "getId", "getCapability", "getModel", "useCapability" ]
|
||||||
|
);
|
||||||
|
|
||||||
mockObjectService.getObjects.andReturn(mockPromise({
|
mockObjectService.getObjects.andReturn(mockPromise({
|
||||||
ROOT: mockRootObject
|
ROOT: mockRootObject
|
||||||
}));
|
}));
|
||||||
|
mockRootObject.useCapability.andReturn(mockPromise([
|
||||||
|
mockDomainObject
|
||||||
|
]));
|
||||||
|
mockDomainObject.useCapability.andReturn(mockPromise([
|
||||||
|
mockNextObject
|
||||||
|
]));
|
||||||
|
mockNextObject.useCapability.andReturn(undefined);
|
||||||
|
mockNextObject.getId.andReturn("next");
|
||||||
|
mockDomainObject.getId.andReturn("mine");
|
||||||
|
|
||||||
controller = new BrowseController(
|
controller = new BrowseController(
|
||||||
mockScope,
|
mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
mockObjectService,
|
mockObjectService,
|
||||||
mockNavigationService
|
mockNavigationService
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses composition to set the navigated object, if there is none", function () {
|
it("uses composition to set the navigated object, if there is none", function () {
|
||||||
mockRootObject.useCapability.andReturn(mockPromise([
|
|
||||||
mockDomainObject
|
|
||||||
]));
|
|
||||||
controller = new BrowseController(
|
controller = new BrowseController(
|
||||||
mockScope,
|
mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
mockObjectService,
|
mockObjectService,
|
||||||
mockNavigationService
|
mockNavigationService
|
||||||
);
|
);
|
||||||
@@ -98,12 +119,11 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("does not try to override navigation", function () {
|
it("does not try to override navigation", function () {
|
||||||
// This behavior is needed if object navigation has been
|
|
||||||
// determined by query string parameters
|
|
||||||
mockRootObject.useCapability.andReturn(mockPromise([null]));
|
|
||||||
mockNavigationService.getNavigation.andReturn(mockDomainObject);
|
mockNavigationService.getNavigation.andReturn(mockDomainObject);
|
||||||
controller = new BrowseController(
|
controller = new BrowseController(
|
||||||
mockScope,
|
mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
mockObjectService,
|
mockObjectService,
|
||||||
mockNavigationService
|
mockNavigationService
|
||||||
);
|
);
|
||||||
@@ -130,6 +150,76 @@ define(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses route parameters to choose initially-navigated object", function () {
|
||||||
|
mockRoute.current.params.ids = "mine/next";
|
||||||
|
controller = new BrowseController(
|
||||||
|
mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
|
mockObjectService,
|
||||||
|
mockNavigationService
|
||||||
|
);
|
||||||
|
expect(mockScope.navigatedObject).toBe(mockNextObject);
|
||||||
|
expect(mockNavigationService.setNavigation)
|
||||||
|
.toHaveBeenCalledWith(mockNextObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles invalid IDs by going as far as possible", function () {
|
||||||
|
// Idea here is that if we get a bad path of IDs,
|
||||||
|
// browse controller should traverse down it until
|
||||||
|
// it hits an invalid ID.
|
||||||
|
mockRoute.current.params.ids = "mine/junk";
|
||||||
|
controller = new BrowseController(
|
||||||
|
mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
|
mockObjectService,
|
||||||
|
mockNavigationService
|
||||||
|
);
|
||||||
|
expect(mockScope.navigatedObject).toBe(mockDomainObject);
|
||||||
|
expect(mockNavigationService.setNavigation)
|
||||||
|
.toHaveBeenCalledWith(mockDomainObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles compositionless objects by going as far as possible", function () {
|
||||||
|
// Idea here is that if we get a path which passes
|
||||||
|
// through an object without a composition, browse controller
|
||||||
|
// should stop at it since remaining IDs cannot be loaded.
|
||||||
|
mockRoute.current.params.ids = "mine/next/junk";
|
||||||
|
controller = new BrowseController(
|
||||||
|
mockScope,
|
||||||
|
mockRoute,
|
||||||
|
mockLocation,
|
||||||
|
mockObjectService,
|
||||||
|
mockNavigationService
|
||||||
|
);
|
||||||
|
expect(mockScope.navigatedObject).toBe(mockNextObject);
|
||||||
|
expect(mockNavigationService.setNavigation)
|
||||||
|
.toHaveBeenCalledWith(mockNextObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("updates the displayed route to reflect current navigation", function () {
|
||||||
|
var mockContext = jasmine.createSpyObj('context', ['getPath']),
|
||||||
|
mockUnlisten = jasmine.createSpy('unlisten');
|
||||||
|
|
||||||
|
mockContext.getPath.andReturn(
|
||||||
|
[mockRootObject, mockDomainObject, mockNextObject]
|
||||||
|
);
|
||||||
|
mockNextObject.getCapability.andCallFake(function (c) {
|
||||||
|
return c === 'context' && mockContext;
|
||||||
|
});
|
||||||
|
mockScope.$on.andReturn(mockUnlisten);
|
||||||
|
// Provide a navigation change
|
||||||
|
mockNavigationService.addListener.mostRecentCall.args[0](
|
||||||
|
mockNextObject
|
||||||
|
);
|
||||||
|
expect(mockLocation.path).toHaveBeenCalledWith("/browse/mine/next");
|
||||||
|
|
||||||
|
// Exercise the Angular workaround
|
||||||
|
mockScope.$on.mostRecentCall.args[1]();
|
||||||
|
expect(mockUnlisten).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
99
platform/commonUI/browse/test/BrowseObjectControllerSpec.js
Normal file
99
platform/commonUI/browse/test/BrowseObjectControllerSpec.js
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../src/BrowseObjectController"],
|
||||||
|
function (BrowseObjectController) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The browse object controller", function () {
|
||||||
|
var mockScope,
|
||||||
|
mockLocation,
|
||||||
|
mockRoute,
|
||||||
|
mockUnlisten,
|
||||||
|
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", "$watch" ]
|
||||||
|
);
|
||||||
|
mockRoute = { current: { params: {} } };
|
||||||
|
mockLocation = jasmine.createSpyObj(
|
||||||
|
"$location",
|
||||||
|
[ "path", "search" ]
|
||||||
|
);
|
||||||
|
mockUnlisten = jasmine.createSpy("unlisten");
|
||||||
|
|
||||||
|
mockScope.$on.andReturn(mockUnlisten);
|
||||||
|
|
||||||
|
controller = new BrowseObjectController(
|
||||||
|
mockScope,
|
||||||
|
mockLocation,
|
||||||
|
mockRoute
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("updates query parameters when selected view changes", function () {
|
||||||
|
fireWatch("representation.selected.key", "xyz");
|
||||||
|
expect(mockLocation.search).toHaveBeenCalledWith('view', "xyz");
|
||||||
|
|
||||||
|
// Exercise the Angular workaround
|
||||||
|
mockScope.$on.mostRecentCall.args[1]();
|
||||||
|
expect(mockUnlisten).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets the active view from query parameters", function () {
|
||||||
|
var mockDomainObject = jasmine.createSpyObj(
|
||||||
|
"domainObject",
|
||||||
|
['getId', 'getModel', 'getCapability', 'useCapability']
|
||||||
|
),
|
||||||
|
testViews = [
|
||||||
|
{ key: 'abc' },
|
||||||
|
{ key: 'def', someKey: 'some value' },
|
||||||
|
{ key: 'xyz' }
|
||||||
|
];
|
||||||
|
|
||||||
|
mockDomainObject.useCapability.andCallFake(function (c) {
|
||||||
|
return (c === 'view') && testViews;
|
||||||
|
});
|
||||||
|
mockLocation.search.andReturn({ view: 'def' });
|
||||||
|
|
||||||
|
fireWatch('domainObject', mockDomainObject);
|
||||||
|
expect(mockScope.representation.selected)
|
||||||
|
.toEqual(testViews[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
[
|
[
|
||||||
"BrowseController",
|
"BrowseController",
|
||||||
|
"BrowseObjectController",
|
||||||
"creation/CreateAction",
|
"creation/CreateAction",
|
||||||
"creation/CreateActionProvider",
|
"creation/CreateActionProvider",
|
||||||
"creation/CreateMenuController",
|
"creation/CreateMenuController",
|
||||||
@@ -10,4 +11,4 @@
|
|||||||
"navigation/NavigationService",
|
"navigation/NavigationService",
|
||||||
"windowing/FullscreenAction",
|
"windowing/FullscreenAction",
|
||||||
"windowing/WindowTitler"
|
"windowing/WindowTitler"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -53,12 +53,14 @@ define(
|
|||||||
|
|
||||||
// Get list of views, read from capability
|
// Get list of views, read from capability
|
||||||
function updateOptions(views) {
|
function updateOptions(views) {
|
||||||
$timeout(function () {
|
if (Array.isArray(views)) {
|
||||||
$scope.ngModel.selected = findMatchingOption(
|
$timeout(function () {
|
||||||
views || [],
|
$scope.ngModel.selected = findMatchingOption(
|
||||||
($scope.ngModel || {}).selected
|
views,
|
||||||
);
|
($scope.ngModel || {}).selected
|
||||||
}, 0);
|
);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update view options when the in-scope results of using the
|
// Update view options when the in-scope results of using the
|
||||||
@@ -68,4 +70,4 @@ define(
|
|||||||
|
|
||||||
return ViewSwitcherController;
|
return ViewSwitcherController;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user