Merge branch 'master' into orphan-navigation-765

This commit is contained in:
Victor Woeltjen
2016-05-26 12:35:48 -07:00
497 changed files with 3412 additions and 2890 deletions

View File

@@ -1,3 +1,5 @@
{ {
"preset": "crockford" "preset": "crockford",
"requireMultipleVarDecl": false,
"requireVarDeclFirst": false
} }

View File

@@ -5,7 +5,7 @@
"eqeqeq": true, "eqeqeq": true,
"forin": true, "forin": true,
"freeze": true, "freeze": true,
"funcscope": true, "funcscope": false,
"futurehostile": true, "futurehostile": true,
"latedef": true, "latedef": true,
"noarg": true, "noarg": true,
@@ -16,6 +16,7 @@
"define", "define",
"Promise" "Promise"
], ],
"shadow": "outer",
"strict": "implied", "strict": "implied",
"undef": true, "undef": true,
"unused": "vars" "unused": "vars"

View File

@@ -22,17 +22,19 @@
#* at runtime from the About dialog for additional information. #* at runtime from the About dialog for additional information.
#***************************************************************************** #*****************************************************************************
# Script to build and deploy docs to github pages. # Script to build and deploy docs.
OUTPUT_DIRECTORY="target/docs" OUTPUT_DIRECTORY="target/docs"
REPOSITORY_URL="git@github.com:nasa/openmctweb.git" # Docs, once built, are pushed to the private website repo
REPOSITORY_URL="git@github.com:nasa/openmct-website.git"
WEBSITE_DIRECTORY="website"
BUILD_SHA=`git rev-parse head` BUILD_SHA=`git rev-parse HEAD`
# A remote will be created for the git repository we are pushing to. # A remote will be created for the git repository we are pushing to.
# Don't worry, as this entire directory will get trashed inbetween builds. # Don't worry, as this entire directory will get trashed inbetween builds.
REMOTE_NAME="documentation" REMOTE_NAME="documentation"
WEBSITE_BRANCH="gh-pages" WEBSITE_BRANCH="master"
# Clean output directory, JSDOC will recreate # Clean output directory, JSDOC will recreate
if [ -d $OUTPUT_DIRECTORY ]; then if [ -d $OUTPUT_DIRECTORY ]; then
@@ -40,23 +42,21 @@ if [ -d $OUTPUT_DIRECTORY ]; then
fi fi
npm run docs npm run docs
cd $OUTPUT_DIRECTORY || exit 1
echo "git init" echo "git clone $REPOSITORY_URL website"
git init git clone $REPOSITORY_URL website || exit 1
echo "cp -r $OUTPUT_DIRECTORY $WEBSITE_DIRECTORY/docs"
cp -r $OUTPUT_DIRECTORY $WEBSITE_DIRECTORY/docs
echo "cd $WEBSITE_DIRECTORY"
cd $WEBSITE_DIRECTORY || exit 1
# Configure github for CircleCI user. # Configure github for CircleCI user.
git config user.email "buildbot@circleci.com" git config user.email "buildbot@circleci.com"
git config user.name "BuildBot" git config user.name "BuildBot"
echo "git remote add $REMOTE_NAME $REPOSITORY_URL"
git remote add $REMOTE_NAME $REPOSITORY_URL
echo "git add ." echo "git add ."
git add . git add .
echo "git commit -m \"Generate docs from build $BUILD_SHA\"" echo "git commit -m \"Docs updated from build $BUILD_SHA\""
git commit -m "Generate docs from build $BUILD_SHA" git commit -m "Docs updated from build $BUILD_SHA"
# Push to the website repo
echo "git push $REMOTE_NAME HEAD:$WEBSITE_BRANCH -f" git push
git push $REMOTE_NAME HEAD:$WEBSITE_BRANCH -f
echo "Documentation pushed to gh-pages branch."

View File

@@ -1,8 +1,11 @@
deployment: deployment:
production: production:
branch: master branch: master
heroku: commands:
appname: openmctweb-demo - npm install canvas nomnoml
- ./build-docs.sh
- git fetch --unshallow
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
openmct-demo: openmct-demo:
branch: live_demo branch: live_demo
heroku: heroku:
@@ -14,3 +17,9 @@ deployment:
test: test:
post: post:
- gulp lint - gulp lint
- gulp checkstyle
general:
branches:
ignore:
- gh-pages

File diff suppressed because it is too large Load Diff

View File

@@ -45,11 +45,12 @@ define(
function buildTaxonomy(dictionary){ function buildTaxonomy(dictionary){
var models = {}; var models = {};
function addMeasurement(measurement){ function addMeasurement(measurement, parent){
var format = FORMAT_MAPPINGS[measurement.type]; var format = FORMAT_MAPPINGS[measurement.type];
models[makeId(measurement)] = { models[makeId(measurement)] = {
type: "msl.measurement", type: "msl.measurement",
name: measurement.name, name: measurement.name,
location: parent,
telemetry: { telemetry: {
key: measurement.identifier, key: measurement.identifier,
ranges: [{ ranges: [{
@@ -62,17 +63,24 @@ define(
}; };
} }
function addInstrument(subsystem) { function addInstrument(subsystem, spacecraftId) {
var measurements = (subsystem.measurements || []); var measurements = (subsystem.measurements || []),
models[makeId(subsystem)] = { instrumentId = makeId(subsystem);
models[instrumentId] = {
type: "msl.instrument", type: "msl.instrument",
name: subsystem.name, name: subsystem.name,
location: spacecraftId,
composition: measurements.map(makeId) composition: measurements.map(makeId)
}; };
measurements.forEach(addMeasurement); measurements.forEach(function(measurement) {
addMeasurement(measurement, instrumentId);
});
} }
(dictionary.instruments || []).forEach(addInstrument); (dictionary.instruments || []).forEach(function(instrument) {
addInstrument(instrument, "msl:curiosity");
});
return models; return models;
} }

View File

@@ -147,6 +147,6 @@ gulp.task('develop', ['serve', 'stylesheets', 'watch']);
gulp.task('install', [ 'static', 'scripts' ]); gulp.task('install', [ 'static', 'scripts' ]);
gulp.task('verify', [ 'lint', 'test' ]); gulp.task('verify', [ 'lint', 'test', 'checkstyle' ]);
gulp.task('build', [ 'verify', 'install' ]); gulp.task('build', [ 'verify', 'install' ]);

View File

@@ -41,10 +41,10 @@ requirejs.config({
"exports": "angular" "exports": "angular"
}, },
"angular-route": { "angular-route": {
"deps": [ "angular" ] "deps": ["angular"]
}, },
"moment-duration-format": { "moment-duration-format": {
"deps": [ "moment" ] "deps": ["moment"]
}, },
"screenfull": { "screenfull": {
"exports": "screenfull" "exports": "screenfull"

View File

@@ -24,24 +24,15 @@ define([
"./src/BrowseController", "./src/BrowseController",
"./src/PaneController", "./src/PaneController",
"./src/BrowseObjectController", "./src/BrowseObjectController",
"./src/creation/CreateMenuController",
"./src/creation/LocatorController",
"./src/MenuArrowController", "./src/MenuArrowController",
"./src/navigation/NavigationService", "./src/navigation/NavigationService",
"./src/creation/CreationPolicy",
"./src/navigation/NavigateAction", "./src/navigation/NavigateAction",
"./src/navigation/OrphanNavigationHandler", "./src/navigation/OrphanNavigationHandler",
"./src/windowing/NewTabAction", "./src/windowing/NewTabAction",
"./src/windowing/FullscreenAction", "./src/windowing/FullscreenAction",
"./src/creation/CreateActionProvider",
"./src/creation/AddActionProvider",
"./src/creation/CreationService",
"./src/windowing/WindowTitler", "./src/windowing/WindowTitler",
"text!./res/templates/browse.html", "text!./res/templates/browse.html",
"text!./res/templates/create/locator.html",
"text!./res/templates/browse-object.html", "text!./res/templates/browse-object.html",
"text!./res/templates/create/create-button.html",
"text!./res/templates/create/create-menu.html",
"text!./res/templates/items/grid-item.html", "text!./res/templates/items/grid-item.html",
"text!./res/templates/browse/object-header.html", "text!./res/templates/browse/object-header.html",
"text!./res/templates/menu-arrow.html", "text!./res/templates/menu-arrow.html",
@@ -54,24 +45,15 @@ define([
BrowseController, BrowseController,
PaneController, PaneController,
BrowseObjectController, BrowseObjectController,
CreateMenuController,
LocatorController,
MenuArrowController, MenuArrowController,
NavigationService, NavigationService,
CreationPolicy,
NavigateAction, NavigateAction,
OrphanNavigationHandler, OrphanNavigationHandler,
NewTabAction, NewTabAction,
FullscreenAction, FullscreenAction,
CreateActionProvider,
AddActionProvider,
CreationService,
WindowTitler, WindowTitler,
browseTemplate, browseTemplate,
locatorTemplate,
browseObjectTemplate, browseObjectTemplate,
createButtonTemplate,
createMenuTemplate,
gridItemTemplate, gridItemTemplate,
objectHeaderTemplate, objectHeaderTemplate,
menuArrowTemplate, menuArrowTemplate,
@@ -138,22 +120,6 @@ define([
"$route" "$route"
] ]
}, },
{
"key": "CreateMenuController",
"implementation": CreateMenuController,
"depends": [
"$scope"
]
},
{
"key": "LocatorController",
"implementation": LocatorController,
"depends": [
"$scope",
"$timeout",
"objectService"
]
},
{ {
"key": "MenuArrowController", "key": "MenuArrowController",
"implementation": MenuArrowController, "implementation": MenuArrowController,
@@ -162,12 +128,6 @@ define([
] ]
} }
], ],
"controls": [
{
"key": "locator",
"template": locatorTemplate
}
],
"representations": [ "representations": [
{ {
"key": "view-object", "key": "view-object",
@@ -183,17 +143,6 @@ define([
"view" "view"
] ]
}, },
{
"key": "create-button",
"template": createButtonTemplate
},
{
"key": "create-menu",
"template": createMenuTemplate,
"uses": [
"action"
]
},
{ {
"key": "grid-item", "key": "grid-item",
"template": gridItemTemplate, "template": gridItemTemplate,
@@ -246,12 +195,6 @@ define([
"implementation": NavigationService "implementation": NavigationService
} }
], ],
"policies": [
{
"implementation": CreationPolicy,
"category": "creation"
}
],
"actions": [ "actions": [
{ {
"key": "navigate", "key": "navigate",
@@ -304,42 +247,6 @@ define([
"editable": false "editable": false
} }
], ],
"components": [
{
"key": "CreateActionProvider",
"provides": "actionService",
"type": "provider",
"implementation": CreateActionProvider,
"depends": [
"$q",
"typeService",
"navigationService",
"policyService"
]
},
{
"key": "AddActionProvider",
"provides": "actionService",
"type": "provider",
"implementation": AddActionProvider,
"depends": [
"$q",
"typeService",
"dialogService",
"policyService"
]
},
{
"key": "CreationService",
"provides": "creationService",
"type": "provider",
"implementation": CreationService,
"depends": [
"$q",
"$log"
]
}
],
"runs": [ "runs": [
{ {
"implementation": WindowTitler, "implementation": WindowTitler,

View File

@@ -80,12 +80,12 @@ define(
function setNavigation(domainObject) { function setNavigation(domainObject) {
var navigationAllowed = true; var navigationAllowed = true;
if (domainObject === $scope.navigatedObject){ if (domainObject === $scope.navigatedObject) {
//do nothing; //do nothing;
return; return;
} }
policyService.allow("navigation", $scope.navigatedObject, domainObject, function(message){ policyService.allow("navigation", $scope.navigatedObject, domainObject, function (message) {
navigationAllowed = $window.confirm(message + "\r\n\r\n" + navigationAllowed = $window.confirm(message + "\r\n\r\n" +
" Are you sure you want to continue?"); " Are you sure you want to continue?");
}); });

View File

@@ -70,7 +70,7 @@ define(
$scope.$watch('domainObject', setViewForDomainObject); $scope.$watch('domainObject', setViewForDomainObject);
$scope.$watch('representation.selected.key', updateQueryParam); $scope.$watch('representation.selected.key', updateQueryParam);
$scope.doAction = function (action){ $scope.doAction = function (action) {
return $scope[action] && $scope[action](); return $scope[action] && $scope[action]();
}; };

View File

@@ -45,7 +45,7 @@ define(
/** /**
* @private * @private
*/ */
InspectorRegion.prototype.buildRegion = function() { InspectorRegion.prototype.buildRegion = function () {
var metadataRegion = { var metadataRegion = {
name: 'metadata', name: 'metadata',
title: 'Metadata Region', title: 'Metadata Region',

View File

@@ -78,12 +78,12 @@ define(
mockScope = jasmine.createSpyObj( mockScope = jasmine.createSpyObj(
"$scope", "$scope",
[ "$on", "$watch" ] ["$on", "$watch"]
); );
mockRoute = { current: { params: {} } }; mockRoute = { current: { params: {} } };
mockLocation = jasmine.createSpyObj( mockLocation = jasmine.createSpyObj(
"$location", "$location",
[ "path" ] ["path"]
); );
mockUrlService = jasmine.createSpyObj( mockUrlService = jasmine.createSpyObj(
"urlService", "urlService",
@@ -91,7 +91,7 @@ define(
); );
mockObjectService = jasmine.createSpyObj( mockObjectService = jasmine.createSpyObj(
"objectService", "objectService",
[ "getObjects" ] ["getObjects"]
); );
mockNavigationService = jasmine.createSpyObj( mockNavigationService = jasmine.createSpyObj(
"navigationService", "navigationService",
@@ -104,15 +104,15 @@ define(
); );
mockRootObject = jasmine.createSpyObj( mockRootObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability", "getModel", "useCapability" ] ["getId", "getCapability", "getModel", "useCapability"]
); );
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability", "getModel", "useCapability" ] ["getId", "getCapability", "getModel", "useCapability"]
); );
mockNextObject = jasmine.createSpyObj( mockNextObject = jasmine.createSpyObj(
"nextObject", "nextObject",
[ "getId", "getCapability", "getModel", "useCapability" ] ["getId", "getCapability", "getModel", "useCapability"]
); );
mockObjectService.getObjects.andReturn(mockPromise({ mockObjectService.getObjects.andReturn(mockPromise({
@@ -255,7 +255,7 @@ define(
" object", function () { " object", function () {
mockScope.navigatedObject = mockDomainObject; mockScope.navigatedObject = mockDomainObject;
mockWindow.confirm.andReturn(false); mockWindow.confirm.andReturn(false);
mockPolicyService.allow.andCallFake(function(category, object, context, callback){ mockPolicyService.allow.andCallFake(function (category, object, context, callback) {
callback("unsaved changes"); callback("unsaved changes");
return false; return false;
}); });

View File

@@ -44,12 +44,12 @@ define(
beforeEach(function () { beforeEach(function () {
mockScope = jasmine.createSpyObj( mockScope = jasmine.createSpyObj(
"$scope", "$scope",
[ "$on", "$watch" ] ["$on", "$watch"]
); );
mockRoute = { current: { params: {} } }; mockRoute = { current: { params: {} } };
mockLocation = jasmine.createSpyObj( mockLocation = jasmine.createSpyObj(
"$location", "$location",
[ "path", "search" ] ["path", "search"]
); );
mockUnlisten = jasmine.createSpy("unlisten"); mockUnlisten = jasmine.createSpy("unlisten");

View File

@@ -38,23 +38,23 @@ define(
beforeEach(function () { beforeEach(function () {
mockScope = jasmine.createSpyObj( mockScope = jasmine.createSpyObj(
"$scope", "$scope",
[ "" ] [""]
); );
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getCapability" ] ["getCapability"]
); );
mockEvent = jasmine.createSpyObj( mockEvent = jasmine.createSpyObj(
"event", "event",
[ "preventDefault" ] ["preventDefault"]
); );
mockContextMenuAction = jasmine.createSpyObj( mockContextMenuAction = jasmine.createSpyObj(
"action", "action",
[ "perform", "getActions" ] ["perform", "getActions"]
); );
mockActionContext = jasmine.createSpyObj( mockActionContext = jasmine.createSpyObj(
"actionContext", "actionContext",
[ "" ] [""]
); );
mockActionContext.domainObject = mockDomainObject; mockActionContext.domainObject = mockDomainObject;

View File

@@ -42,11 +42,11 @@ define(
} }
beforeEach(function () { beforeEach(function () {
mockScope = jasmine.createSpyObj("$scope", [ "$on" ]); mockScope = jasmine.createSpyObj("$scope", ["$on"]);
mockDomainObjects = ['a', 'b'].map(function (id) { mockDomainObjects = ['a', 'b'].map(function (id) {
var mockDomainObject = jasmine.createSpyObj( var mockDomainObject = jasmine.createSpyObj(
'domainObject-' + id, 'domainObject-' + id,
[ 'getId', 'getModel', 'getCapability' ] ['getId', 'getModel', 'getCapability']
); );
mockDomainObject.getId.andReturn(id); mockDomainObject.getId.andReturn(id);
@@ -56,7 +56,7 @@ define(
}); });
mockAgentService = jasmine.createSpyObj( mockAgentService = jasmine.createSpyObj(
"agentService", "agentService",
[ "isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape" ] ["isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape"]
); );
mockWindow = jasmine.createSpyObj("$window", ["open"]); mockWindow = jasmine.createSpyObj("$window", ["open"]);
}); });

View File

@@ -1,130 +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.
*****************************************************************************/
/**
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
*/
define(
["../../src/creation/CreateAction"],
function (CreateAction) {
describe("The create action", function () {
var mockType,
mockParent,
mockContext,
mockDialogService,
mockCreationService,
action;
function mockPromise(value) {
return {
then: function (callback) {
return mockPromise(callback(value));
}
};
}
beforeEach(function () {
mockType = jasmine.createSpyObj(
"type",
[
"getKey",
"getGlyph",
"getName",
"getDescription",
"getProperties",
"getInitialModel"
]
);
mockParent = jasmine.createSpyObj(
"domainObject",
[
"getId",
"getModel",
"getCapability"
]
);
mockContext = {
domainObject: mockParent
};
mockDialogService = jasmine.createSpyObj(
"dialogService",
[ "getUserInput" ]
);
mockCreationService = jasmine.createSpyObj(
"creationService",
[ "createObject" ]
);
mockType.getKey.andReturn("test");
mockType.getGlyph.andReturn("T");
mockType.getDescription.andReturn("a test type");
mockType.getName.andReturn("Test");
mockType.getProperties.andReturn([]);
mockType.getInitialModel.andReturn({});
mockDialogService.getUserInput.andReturn(mockPromise({}));
action = new CreateAction(
mockType,
mockParent,
mockContext,
mockDialogService,
mockCreationService
);
});
it("exposes type-appropriate metadata", function () {
var metadata = action.getMetadata();
expect(metadata.name).toEqual("Test");
expect(metadata.description).toEqual("a test type");
expect(metadata.glyph).toEqual("T");
});
//TODO: Disabled for NEM Beta
xit("invokes the creation service when performed", function () {
action.perform();
expect(mockCreationService.createObject).toHaveBeenCalledWith(
{ type: "test" },
mockParent
);
});
//TODO: Disabled for NEM Beta
xit("does not create an object if the user cancels", function () {
mockDialogService.getUserInput.andReturn({
then: function (callback, fail) {
fail();
}
});
action.perform();
expect(mockCreationService.createObject)
.not.toHaveBeenCalled();
});
});
}
);

View File

@@ -44,12 +44,12 @@ define(
beforeEach(function () { beforeEach(function () {
mockNavigationService = jasmine.createSpyObj( mockNavigationService = jasmine.createSpyObj(
"navigationService", "navigationService",
[ "setNavigation" ] ["setNavigation"]
); );
mockQ = { when: mockPromise }; mockQ = { when: mockPromise };
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getModel", "getCapability" ] ["getId", "getModel", "getCapability"]
); );
action = new NavigateAction( action = new NavigateAction(

View File

@@ -37,11 +37,11 @@ define(
beforeEach(function () { beforeEach(function () {
mockNavigationService = jasmine.createSpyObj( mockNavigationService = jasmine.createSpyObj(
'navigationService', 'navigationService',
[ 'getNavigation' ] ['getNavigation']
); );
mockRootScope = jasmine.createSpyObj( mockRootScope = jasmine.createSpyObj(
'$rootScope', '$rootScope',
[ '$watch' ] ['$watch']
); );
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
'domainObject', 'domainObject',

View File

@@ -155,8 +155,8 @@ define(
* @returns {boolean} true if dialog is currently visible, false * @returns {boolean} true if dialog is currently visible, false
* otherwise * otherwise
*/ */
DialogService.prototype.canShowDialog = function(dialogModel){ DialogService.prototype.canShowDialog = function (dialogModel) {
if (this.dialogVisible){ if (this.dialogVisible) {
// Only one dialog should be shown at a time. // Only one dialog should be shown at a time.
// The application design should be such that // The application design should be such that
// we never even try to do this. // we never even try to do this.
@@ -224,7 +224,7 @@ define(
* @param {typeClass} string tells overlayService that this overlay should use appropriate CSS class * @param {typeClass} string tells overlayService that this overlay should use appropriate CSS class
* @returns {boolean} * @returns {boolean}
*/ */
DialogService.prototype.showBlockingMessage = function(dialogModel) { DialogService.prototype.showBlockingMessage = function (dialogModel) {
if (this.canShowDialog(dialogModel)) { if (this.canShowDialog(dialogModel)) {
// Add the overlay using the OverlayService, which // Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM // will handle actual insertion into the DOM

View File

@@ -38,23 +38,23 @@ define(
beforeEach(function () { beforeEach(function () {
mockOverlayService = jasmine.createSpyObj( mockOverlayService = jasmine.createSpyObj(
"overlayService", "overlayService",
[ "createOverlay" ] ["createOverlay"]
); );
mockQ = jasmine.createSpyObj( mockQ = jasmine.createSpyObj(
"$q", "$q",
[ "defer" ] ["defer"]
); );
mockLog = jasmine.createSpyObj( mockLog = jasmine.createSpyObj(
"$log", "$log",
[ "warn", "info", "debug" ] ["warn", "info", "debug"]
); );
mockOverlay = jasmine.createSpyObj( mockOverlay = jasmine.createSpyObj(
"overlay", "overlay",
[ "dismiss" ] ["dismiss"]
); );
mockDeferred = jasmine.createSpyObj( mockDeferred = jasmine.createSpyObj(
"deferred", "deferred",
[ "resolve", "reject"] ["resolve", "reject"]
); );
mockDeferred.promise = "mock promise"; mockDeferred.promise = "mock promise";
@@ -120,7 +120,7 @@ define(
}); });
it("invokes the overlay service with the correct parameters when" + it("invokes the overlay service with the correct parameters when" +
" a blocking dialog is requested", function() { " a blocking dialog is requested", function () {
var dialogModel = {}; var dialogModel = {};
expect(dialogService.showBlockingMessage(dialogModel)).toBe(true); expect(dialogService.showBlockingMessage(dialogModel)).toBe(true);
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith( expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(

View File

@@ -38,13 +38,13 @@ define(
overlayService; overlayService;
beforeEach(function () { beforeEach(function () {
mockDocument = jasmine.createSpyObj("$document", [ "find" ]); mockDocument = jasmine.createSpyObj("$document", ["find"]);
mockCompile = jasmine.createSpy("$compile"); mockCompile = jasmine.createSpy("$compile");
mockRootScope = jasmine.createSpyObj("$rootScope", [ "$new" ]); mockRootScope = jasmine.createSpyObj("$rootScope", ["$new"]);
mockBody = jasmine.createSpyObj("body", [ "prepend" ]); mockBody = jasmine.createSpyObj("body", ["prepend"]);
mockTemplate = jasmine.createSpy("template"); mockTemplate = jasmine.createSpy("template");
mockElement = jasmine.createSpyObj("element", [ "remove" ]); mockElement = jasmine.createSpyObj("element", ["remove"]);
mockScope = jasmine.createSpyObj("scope", [ "$destroy" ]); mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
mockDocument.find.andReturn(mockBody); mockDocument.find.andReturn(mockBody);
mockCompile.andReturn(mockTemplate); mockCompile.andReturn(mockTemplate);

View File

@@ -26,7 +26,7 @@ define([
"./src/controllers/ElementsController", "./src/controllers/ElementsController",
"./src/controllers/EditObjectController", "./src/controllers/EditObjectController",
"./src/directives/MCTBeforeUnload", "./src/directives/MCTBeforeUnload",
"./src/actions/LinkAction", "./src/actions/EditAndComposeAction",
"./src/actions/EditAction", "./src/actions/EditAction",
"./src/actions/PropertiesAction", "./src/actions/PropertiesAction",
"./src/actions/RemoveAction", "./src/actions/RemoveAction",
@@ -43,6 +43,15 @@ define([
"./src/capabilities/EditorCapability", "./src/capabilities/EditorCapability",
"./src/capabilities/TransactionCapabilityDecorator", "./src/capabilities/TransactionCapabilityDecorator",
"./src/services/TransactionService", "./src/services/TransactionService",
"./src/creation/CreateMenuController",
"./src/creation/LocatorController",
"./src/creation/CreationPolicy",
"./src/creation/CreateActionProvider",
"./src/creation/AddActionProvider",
"./src/creation/CreationService",
"text!./res/templates/create/locator.html",
"text!./res/templates/create/create-button.html",
"text!./res/templates/create/create-menu.html",
"text!./res/templates/library.html", "text!./res/templates/library.html",
"text!./res/templates/edit-object.html", "text!./res/templates/edit-object.html",
"text!./res/templates/edit-action-buttons.html", "text!./res/templates/edit-action-buttons.html",
@@ -55,7 +64,7 @@ define([
ElementsController, ElementsController,
EditObjectController, EditObjectController,
MCTBeforeUnload, MCTBeforeUnload,
LinkAction, EditAndComposeAction,
EditAction, EditAction,
PropertiesAction, PropertiesAction,
RemoveAction, RemoveAction,
@@ -72,6 +81,15 @@ define([
EditorCapability, EditorCapability,
TransactionCapabilityDecorator, TransactionCapabilityDecorator,
TransactionService, TransactionService,
CreateMenuController,
LocatorController,
CreationPolicy,
CreateActionProvider,
AddActionProvider,
CreationService,
locatorTemplate,
createButtonTemplate,
createMenuTemplate,
libraryTemplate, libraryTemplate,
editObjectTemplate, editObjectTemplate,
editActionButtonsTemplate, editActionButtonsTemplate,
@@ -112,6 +130,22 @@ define([
"$location", "$location",
"policyService" "policyService"
] ]
},
{
"key": "CreateMenuController",
"implementation": CreateMenuController,
"depends": [
"$scope"
]
},
{
"key": "LocatorController",
"implementation": LocatorController,
"depends": [
"$scope",
"$timeout",
"objectService"
]
} }
], ],
"directives": [ "directives": [
@@ -126,7 +160,7 @@ define([
"actions": [ "actions": [
{ {
"key": "compose", "key": "compose",
"implementation": LinkAction "implementation": EditAndComposeAction
}, },
{ {
"key": "edit", "key": "edit",
@@ -221,8 +255,11 @@ define([
"category": "navigation", "category": "navigation",
"message": "There are unsaved changes.", "message": "There are unsaved changes.",
"implementation": EditNavigationPolicy "implementation": EditNavigationPolicy
},
{
"implementation": CreationPolicy,
"category": "creation"
} }
], ],
"templates": [ "templates": [
{ {
@@ -261,6 +298,17 @@ define([
{ {
"key": "topbar-edit", "key": "topbar-edit",
"template": topbarEditTemplate "template": topbarEditTemplate
},
{
"key": "create-button",
"template": createButtonTemplate
},
{
"key": "create-menu",
"template": createMenuTemplate,
"uses": [
"action"
]
} }
], ],
"components": [ "components": [
@@ -282,7 +330,40 @@ define([
"$q", "$q",
"$log" "$log"
] ]
},
{
"key": "CreateActionProvider",
"provides": "actionService",
"type": "provider",
"implementation": CreateActionProvider,
"depends": [
"typeService",
"policyService"
]
},
{
"key": "AddActionProvider",
"provides": "actionService",
"type": "provider",
"implementation": AddActionProvider,
"depends": [
"$q",
"typeService",
"dialogService",
"policyService"
]
},
{
"key": "CreationService",
"provides": "creationService",
"type": "provider",
"implementation": CreationService,
"depends": [
"$q",
"$log"
]
} }
], ],
"representers": [ "representers": [
{ {
@@ -298,7 +379,7 @@ define([
], ],
"constants": [ "constants": [
{ {
"key":"editModeBlacklist", "key": "editModeBlacklist",
"value": ["copy", "follow", "window", "link", "locate"] "value": ["copy", "follow", "window", "link", "locate"]
}, },
{ {
@@ -317,6 +398,12 @@ define([
] ]
} }
], ],
"controls": [
{
"key": "locator",
"template": locatorTemplate
}
]
} }
}); });
}); });

View File

@@ -44,7 +44,7 @@ define(
CancelAction.prototype.perform = function () { CancelAction.prototype.perform = function () {
var domainObject = this.domainObject; var domainObject = this.domainObject;
function returnToBrowse () { function returnToBrowse() {
var parent; var parent;
//If the object existed already, navigate to refresh view //If the object existed already, navigate to refresh view

View File

@@ -70,10 +70,16 @@ define(
*/ */
EditAction.prototype.perform = function () { EditAction.prototype.perform = function () {
var self = this; var self = this;
function cancelEditing(){ function cancelEditing() {
self.domainObject.getCapability('editor').cancel(); self.domainObject.getCapability('editor').cancel();
self.navigationService.removeListener(cancelEditing); self.navigationService.removeListener(cancelEditing);
} }
//If this is not the currently navigated object, then navigate
// to it.
if (this.navigationService.getNavigation() !== this.domainObject) {
this.navigationService.setNavigation(this.domainObject);
}
this.navigationService.addListener(cancelEditing); this.navigationService.addListener(cancelEditing);
this.domainObject.useCapability("editor"); this.domainObject.useCapability("editor");
}; };

View File

@@ -31,13 +31,14 @@ define(
* @memberof platform/commonUI/edit * @memberof platform/commonUI/edit
* @implements {Action} * @implements {Action}
*/ */
function LinkAction(context) { function EditAndComposeAction(context) {
this.domainObject = (context || {}).domainObject; this.domainObject = (context || {}).domainObject;
this.selectedObject = (context || {}).selectedObject; this.selectedObject = (context || {}).selectedObject;
} }
LinkAction.prototype.perform = function () { EditAndComposeAction.prototype.perform = function () {
var self = this; var self = this,
editAction = this.domainObject.getCapability('action').getActions("edit")[0];
// Persist changes to the domain object // Persist changes to the domain object
function doPersist() { function doPersist() {
@@ -54,9 +55,13 @@ define(
.then(doPersist); .then(doPersist);
} }
if (editAction) {
editAction.perform();
}
return this.selectedObject && doLink(); return this.selectedObject && doLink();
}; };
return LinkAction; return EditAndComposeAction;
} }
); );

View File

@@ -63,10 +63,10 @@ define(
}); });
} }
function showDialog(type) { function showDialog(objType) {
// Create a dialog object to generate the form structure, etc. // Create a dialog object to generate the form structure, etc.
var dialog = var dialog =
new PropertiesDialog(type, domainObject.getModel()); new PropertiesDialog(objType, domainObject.getModel());
// Show the dialog // Show the dialog
return dialogService.getUserInput( return dialogService.getUserInput(

View File

@@ -75,8 +75,8 @@ define(
* Invoke persistence on a domain object. This will be called upon * Invoke persistence on a domain object. This will be called upon
* the removed object's parent (as its composition will have changed.) * the removed object's parent (as its composition will have changed.)
*/ */
function doPersist(domainObject) { function doPersist(domainObj) {
var persistence = domainObject.getCapability('persistence'); var persistence = domainObj.getCapability('persistence');
return persistence && persistence.persist(); return persistence && persistence.persist();
} }

View File

@@ -48,7 +48,7 @@ define(
SaveAction.prototype.perform = function () { SaveAction.prototype.perform = function () {
var domainObject = this.domainObject; var domainObject = this.domainObject;
function resolveWith(object){ function resolveWith(object) {
return function () { return function () {
return object; return object;
}; };

View File

@@ -22,7 +22,7 @@
define( define(
['../../../browse/src/creation/CreateWizard'], ['../creation/CreateWizard'],
function (CreateWizard) { function (CreateWizard) {
/** /**
@@ -42,7 +42,7 @@ define(
context context
) { ) {
this.domainObject = (context || {}).domainObject; this.domainObject = (context || {}).domainObject;
this.injectObjectService = function(){ this.injectObjectService = function () {
this.objectService = $injector.get("objectService"); this.objectService = $injector.get("objectService");
}; };
this.policyService = policyService; this.policyService = policyService;
@@ -65,7 +65,7 @@ define(
/** /**
* @private * @private
*/ */
SaveAsAction.prototype.getObjectService = function(){ SaveAsAction.prototype.getObjectService = function () {
// Lazily acquire object service (avoids cyclical dependency) // Lazily acquire object service (avoids cyclical dependency)
if (!this.objectService) { if (!this.objectService) {
this.injectObjectService(); this.injectObjectService();
@@ -73,7 +73,7 @@ define(
return this.objectService; return this.objectService;
}; };
function resolveWith(object){ function resolveWith(object) {
return function () { return function () {
return object; return object;
}; };
@@ -116,13 +116,13 @@ define(
).then(wizard.populateObjectFromInput.bind(wizard)); ).then(wizard.populateObjectFromInput.bind(wizard));
} }
function fetchObject(objectId){ function fetchObject(objectId) {
return self.getObjectService().getObjects([objectId]).then(function(objects){ return self.getObjectService().getObjects([objectId]).then(function (objects) {
return objects[objectId]; return objects[objectId];
}); });
} }
function getParent(object){ function getParent(object) {
return fetchObject(object.getModel().location); return fetchObject(object.getModel().location);
} }

View File

@@ -52,11 +52,11 @@ define(
this.domainObject.getCapability('status').set('editing', true); this.domainObject.getCapability('status').set('editing', true);
}; };
function isEditContextRoot (domainObject) { function isEditContextRoot(domainObject) {
return domainObject.getCapability('status').get('editing'); return domainObject.getCapability('status').get('editing');
} }
function isEditing (domainObject) { function isEditing(domainObject) {
return isEditContextRoot(domainObject) || return isEditContextRoot(domainObject) ||
domainObject.hasCapability('context') && domainObject.hasCapability('context') &&
isEditing(domainObject.getCapability('context').getParent()); isEditing(domainObject.getCapability('context').getParent());
@@ -87,7 +87,7 @@ define(
*/ */
EditorCapability.prototype.save = function () { EditorCapability.prototype.save = function () {
var domainObject = this.domainObject; var domainObject = this.domainObject;
return this.transactionService.commit().then(function() { return this.transactionService.commit().then(function () {
domainObject.getCapability('status').set('editing', false); domainObject.getCapability('status').set('editing', false);
}); });
}; };
@@ -101,7 +101,7 @@ define(
*/ */
EditorCapability.prototype.cancel = function () { EditorCapability.prototype.cancel = function () {
var domainObject = this.domainObject; var domainObject = this.domainObject;
return this.transactionService.cancel().then(function(){ return this.transactionService.cancel().then(function () {
domainObject.getCapability("status").set("editing", false); domainObject.getCapability("status").set("editing", false);
return domainObject; return domainObject;
}); });

View File

@@ -60,14 +60,14 @@ define(
var self = this; var self = this;
function onCommit() { function onCommit() {
return self.persistenceCapability.persist().then(function(result) { return self.persistenceCapability.persist().then(function (result) {
self.persistPending = false; self.persistPending = false;
return result; return result;
}); });
} }
function onCancel() { function onCancel() {
return self.persistenceCapability.refresh().then(function(result) { return self.persistenceCapability.refresh().then(function (result) {
self.persistPending = false; self.persistPending = false;
return result; return result;
}); });

View File

@@ -59,7 +59,7 @@ define(
$scope.$watch('domainObject', setViewForDomainObject); $scope.$watch('domainObject', setViewForDomainObject);
$scope.doAction = function (action){ $scope.doAction = function (action) {
return $scope[action] && $scope[action](); return $scope[action] && $scope[action]();
}; };
} }
@@ -74,8 +74,8 @@ define(
var navigatedObject = this.scope.domainObject, var navigatedObject = this.scope.domainObject,
policyMessage; policyMessage;
this.policyService.allow("navigation", navigatedObject, undefined, function(message) { this.policyService.allow("navigation", navigatedObject, undefined, function (message) {
policyMessage = message; policyMessage = message;
}); });
return policyMessage; return policyMessage;

View File

@@ -30,7 +30,7 @@ define(
* @constructor * @constructor
*/ */
function ElementsController($scope) { function ElementsController($scope) {
function filterBy(text){ function filterBy(text) {
if (typeof text === 'undefined') { if (typeof text === 'undefined') {
return $scope.searchText; return $scope.searchText;
} else { } else {

View File

@@ -81,13 +81,13 @@ define(
newModel.type = this.type.getKey(); newModel.type = this.type.getKey();
newObject = parentObject.getCapability('instantiation').instantiate(newModel); newObject = parentObject.getCapability('instantiation').instantiate(newModel);
newObject.useCapability('mutation', function(model){ newObject.useCapability('mutation', function (model) {
model.location = parentObject.getId(); model.location = parentObject.getId();
}); });
wizard = new CreateWizard(newObject, this.parent, this.policyService); wizard = new CreateWizard(newObject, this.parent, this.policyService);
function populateObjectFromInput (formValue) { function populateObjectFromInput(formValue) {
return wizard.populateObjectFromInput(formValue, newObject); return wizard.populateObjectFromInput(formValue, newObject);
} }
@@ -99,7 +99,7 @@ define(
}); });
} }
function addToParent (populatedObject) { function addToParent(populatedObject) {
parentObject.getCapability('composition').add(populatedObject); parentObject.getCapability('composition').add(populatedObject);
return persistAndReturn(parentObject); return persistAndReturn(parentObject);
} }
@@ -125,7 +125,7 @@ define(
* @returns {AddActionMetadata} metadata about this action * @returns {AddActionMetadata} metadata about this action
*/ */
AddAction.prototype.getMetadata = function () { AddAction.prototype.getMetadata = function () {
return this.metadata; return this.metadata;
}; };
return AddAction; return AddAction;

View File

@@ -43,11 +43,8 @@ define(
* override this) * override this)
* @param {ActionContext} context the context in which the * @param {ActionContext} context the context in which the
* action is being performed * action is being performed
* @param {NavigationService} navigationService the navigation service,
* which handles changes in navigation. It allows the object
* being browsed/edited to be set.
*/ */
function CreateAction(type, parent, context, $q, navigationService) { function CreateAction(type, parent, context) {
this.metadata = { this.metadata = {
key: 'create', key: 'create',
glyph: type.getGlyph(), glyph: type.getGlyph(),
@@ -56,24 +53,8 @@ define(
description: type.getDescription(), description: type.getDescription(),
context: context context: context
}; };
this.type = type; this.type = type;
this.parent = parent; this.parent = parent;
this.navigationService = navigationService;
this.$q = $q;
}
// Get a count of views which are not flagged as non-editable.
function countEditableViews(domainObject) {
var views = domainObject && domainObject.useCapability('view'),
count = 0;
// A view is editable unless explicitly flagged as not
(views || []).forEach(function (view) {
count += (view.editable !== false) ? 1 : 0;
});
return count;
} }
/** /**
@@ -82,26 +63,31 @@ define(
*/ */
CreateAction.prototype.perform = function () { CreateAction.prototype.perform = function () {
var newModel = this.type.getInitialModel(), var newModel = this.type.getInitialModel(),
parentObject = this.navigationService.getNavigation(), newObject,
editorCapability, editAction,
newObject; editorCapability;
function onSave() {
return editorCapability.save();
}
function onCancel() {
return editorCapability.cancel();
}
newModel.type = this.type.getKey(); newModel.type = this.type.getKey();
newModel.location = parentObject.getId(); newModel.location = this.parent.getId();
newObject = parentObject.useCapability('instantiation', newModel); newObject = this.parent.useCapability('instantiation', newModel);
editorCapability = newObject.hasCapability('editor') && newObject.getCapability("editor");
editorCapability = newObject.getCapability("editor"); editAction = newObject.getCapability("action").getActions("edit")[0];
//If an edit action is available, perform it
if (countEditableViews(newObject) > 0 && newObject.hasCapability('composition')) { if (editAction) {
this.navigationService.setNavigation(newObject); return editAction.perform();
return newObject.getCapability("action").perform("edit"); } else if (editorCapability) {
} else { //otherwise, use the save action
editorCapability.edit(); editorCapability.edit();
return newObject.useCapability("action").perform("save").then(function () { return newObject.getCapability("action").perform("save").then(onSave, onCancel);
return editorCapability.save();
}, function () {
return editorCapability.cancel();
});
} }
}; };
@@ -118,7 +104,7 @@ define(
* @returns {CreateActionMetadata} metadata about this action * @returns {CreateActionMetadata} metadata about this action
*/ */
CreateAction.prototype.getMetadata = function () { CreateAction.prototype.getMetadata = function () {
return this.metadata; return this.metadata;
}; };
return CreateAction; return CreateAction;

View File

@@ -44,10 +44,8 @@ define(
* introduced in this bundle), responsible for handling actual * introduced in this bundle), responsible for handling actual
* object creation. * object creation.
*/ */
function CreateActionProvider($q, typeService, navigationService, policyService) { function CreateActionProvider(typeService, policyService) {
this.typeService = typeService; this.typeService = typeService;
this.navigationService = navigationService;
this.$q = $q;
this.policyService = policyService; this.policyService = policyService;
} }
@@ -72,9 +70,7 @@ define(
return new CreateAction( return new CreateAction(
type, type,
destination, destination,
context, context
self.$q,
self.navigationService
); );
}); });
}; };

View File

@@ -111,12 +111,12 @@ define(
* @param formValue * @param formValue
* @returns {DomainObject} * @returns {DomainObject}
*/ */
CreateWizard.prototype.populateObjectFromInput = function(formValue) { CreateWizard.prototype.populateObjectFromInput = function (formValue) {
var parent = this.getLocation(formValue), var parent = this.getLocation(formValue),
formModel = this.createModel(formValue); formModel = this.createModel(formValue);
formModel.location = parent.getId(); formModel.location = parent.getId();
this.domainObject.useCapability("mutation", function(){ this.domainObject.useCapability("mutation", function () {
return formModel; return formModel;
}); });
return this.domainObject; return this.domainObject;

View File

@@ -50,14 +50,14 @@ define(
$scope.rootObject = $scope.rootObject =
(context && context.getRoot()) || $scope.rootObject; (context && context.getRoot()) || $scope.rootObject;
}, 0); }, 0);
} else if (!contextRoot){ } else if (!contextRoot) {
//If no context root is available, default to the root //If no context root is available, default to the root
// object // object
$scope.rootObject = undefined; $scope.rootObject = undefined;
// Update the displayed tree on a timeout to avoid // Update the displayed tree on a timeout to avoid
// an infinite digest exception. // an infinite digest exception.
objectService.getObjects(['ROOT']) objectService.getObjects(['ROOT'])
.then(function(objects){ .then(function (objects) {
$timeout(function () { $timeout(function () {
$scope.rootObject = objects.ROOT; $scope.rootObject = objects.ROOT;
}, 0); }, 0);

View File

@@ -45,7 +45,7 @@ define(
count = 0, count = 0,
type, views; type, views;
if (!domainObject){ if (!domainObject) {
return count; return count;
} }
@@ -56,7 +56,10 @@ define(
// A view is editable unless explicitly flagged as not // A view is editable unless explicitly flagged as not
(views || []).forEach(function (view) { (views || []).forEach(function (view) {
if (view.editable === true || if (view.editable === true ||
(view.key === 'plot' && type.getKey() === 'telemetry.panel')) { (view.key === 'plot' && type.getKey() === 'telemetry.panel') ||
(view.key === 'table' && type.getKey() === 'table') ||
(view.key === 'rt-table' && type.getKey() === 'rttable')
) {
count++; count++;
} }
}); });
@@ -81,17 +84,14 @@ define(
var key = action.getMetadata().key, var key = action.getMetadata().key,
category = (context || {}).category; category = (context || {}).category;
// Only worry about actions in the view-control category // Restrict 'edit' to cases where there are editable
if (category === 'view-control') { // views (similarly, restrict 'properties' to when
// Restrict 'edit' to cases where there are editable // the converse is true), and where the domain object is not
// views (similarly, restrict 'properties' to when // already being edited.
// the converse is true), and where the domain object is not if (key === 'edit') {
// already being edited. return this.countEditableViews(context) > 0 && !isEditing(context);
if (key === 'edit') { } else if (key === 'properties' && category === 'view-control') {
return this.countEditableViews(context) > 0 && !isEditing(context); return this.countEditableViews(context) < 1 && !isEditing(context);
} else if (key === 'properties') {
return this.countEditableViews(context) < 1 && !isEditing(context);
}
} }
// Like all policies, allow by default. // Like all policies, allow by default.

View File

@@ -56,7 +56,7 @@ define(
actionMetadata = action.getMetadata ? action.getMetadata() : {}; actionMetadata = action.getMetadata ? action.getMetadata() : {};
if (navigatedObject.hasCapability("editor") && navigatedObject.getCapability("editor").isEditContextRoot()) { if (navigatedObject.hasCapability("editor") && navigatedObject.getCapability("editor").isEditContextRoot()) {
if (selectedObject.hasCapability("editor") && selectedObject.getCapability("editor").inEditContext()){ if (selectedObject.hasCapability("editor") && selectedObject.getCapability("editor").inEditContext()) {
return this.editModeBlacklist.indexOf(actionMetadata.key) === -1; return this.editModeBlacklist.indexOf(actionMetadata.key) === -1;
} else { } else {
//Target is in the context menu //Target is in the context menu

View File

@@ -38,7 +38,7 @@ define(
/** /**
* @private * @private
*/ */
EditNavigationPolicy.prototype.isDirty = function(domainObject) { EditNavigationPolicy.prototype.isDirty = function (domainObject) {
var navigatedObject = domainObject, var navigatedObject = domainObject,
editorCapability = navigatedObject && editorCapability = navigatedObject &&
navigatedObject.getCapability("editor"); navigatedObject.getCapability("editor");

View File

@@ -91,14 +91,8 @@ define(
} }
} }
function setEditable(editableDomainObject) {
self.domainObject = editableDomainObject;
scope.model = editableDomainObject.getModel();
}
// Place the "commit" method in the scope // Place the "commit" method in the scope
scope.commit = commit; scope.commit = commit;
scope.setEditable = setEditable;
// Clean up when the scope is destroyed // Clean up when the scope is destroyed
scope.$on("$destroy", function () { scope.$on("$destroy", function () {
@@ -119,7 +113,7 @@ define(
// Ensure existing watches are released // Ensure existing watches are released
this.destroy(); this.destroy();
function setEditing(){ function setEditing() {
scope.viewObjectTemplate = 'edit-object'; scope.viewObjectTemplate = 'edit-object';
} }
@@ -128,15 +122,15 @@ define(
* editable then change the view and inspector regions * editable then change the view and inspector regions
* object representation accordingly * object representation accordingly
*/ */
this.listenHandle = this.domainObject.getCapability('status').listen(function(statuses){ this.listenHandle = this.domainObject.getCapability('status').listen(function (statuses) {
if (statuses.indexOf('editing') !== -1){ if (statuses.indexOf('editing') !== -1) {
setEditing(); setEditing();
} else { } else {
delete scope.viewObjectTemplate; delete scope.viewObjectTemplate;
} }
}); });
if (representedObject.hasCapability('editor') && representedObject.getCapability('editor').isEditContextRoot()){ if (representedObject.hasCapability('editor') && representedObject.getCapability('editor').isEditContextRoot()) {
setEditing(); setEditing();
} }
}; };

View File

@@ -24,8 +24,12 @@ define(
function () { function () {
// Utility functions for reducing truth arrays // Utility functions for reducing truth arrays
function and(a, b) { return a && b; } function and(a, b) {
function or(a, b) { return a || b; } return a && b;
}
function or(a, b) {
return a || b;
}
/** /**
@@ -219,7 +223,7 @@ define(
// Update value for this property in all elements of the // Update value for this property in all elements of the
// selection which have this property. // selection which have this property.
function updateProperties(property, value) { function updateProperties(property, val) {
var changed = false; var changed = false;
// Update property in a selected element // Update property in a selected element
@@ -229,12 +233,12 @@ define(
// Check if this is a setter, or just assignable // Check if this is a setter, or just assignable
if (typeof selected[property] === 'function') { if (typeof selected[property] === 'function') {
changed = changed =
changed || (selected[property]() !== value); changed || (selected[property]() !== val);
selected[property](value); selected[property](val);
} else { } else {
changed = changed =
changed || (selected[property] !== value); changed || (selected[property] !== val);
selected[property] = value; selected[property] = val;
} }
} }
} }

View File

@@ -133,11 +133,11 @@ define(
self = this; self = this;
// Initialize toolbar (expose object to parent scope) // Initialize toolbar (expose object to parent scope)
function initialize(definition) { function initialize(def) {
// If we have been asked to expose toolbar state... // If we have been asked to expose toolbar state...
if (self.attrs.toolbar) { if (self.attrs.toolbar) {
// Initialize toolbar object // Initialize toolbar object
self.toolbar = new EditToolbar(definition, self.commit); self.toolbar = new EditToolbar(def, self.commit);
// Ensure toolbar state is exposed // Ensure toolbar state is exposed
self.exposeToolbar(); self.exposeToolbar();
} }

View File

@@ -22,7 +22,7 @@
/*global define*/ /*global define*/
define( define(
[], [],
function() { function () {
/** /**
* Implements an application-wide transaction state. Once a * Implements an application-wide transaction state. Once a
* transaction is started, calls to * transaction is started, calls to
@@ -103,7 +103,7 @@ define(
this.$log.error("Error committing transaction."); this.$log.error("Error committing transaction.");
} }
} }
return this.$q.all(promises).then( function () { return this.$q.all(promises).then(function () {
self.transaction = false; self.transaction = false;
self.onCommits = []; self.onCommits = [];
@@ -145,4 +145,4 @@ define(
}; };
return TransactionService; return TransactionService;
}); });

View File

@@ -44,15 +44,15 @@ define(
beforeEach(function () { beforeEach(function () {
mockLocation = jasmine.createSpyObj( mockLocation = jasmine.createSpyObj(
"$location", "$location",
[ "path" ] ["path"]
); );
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getCapability", "hasCapability" ] ["getCapability", "hasCapability"]
); );
mockEditorCapability = jasmine.createSpyObj( mockEditorCapability = jasmine.createSpyObj(
"editor", "editor",
[ "save", "cancel" ] ["save", "cancel"]
); );
mockUrlService = jasmine.createSpyObj( mockUrlService = jasmine.createSpyObj(
"urlService", "urlService",

View File

@@ -38,23 +38,23 @@ define(
beforeEach(function () { beforeEach(function () {
mockLocation = jasmine.createSpyObj( mockLocation = jasmine.createSpyObj(
"$location", "$location",
[ "path" ] ["path"]
); );
mockNavigationService = jasmine.createSpyObj( mockNavigationService = jasmine.createSpyObj(
"navigationService", "navigationService",
[ "setNavigation", "getNavigation", "addListener", "removeListener" ] ["setNavigation", "getNavigation", "addListener", "removeListener"]
); );
mockLog = jasmine.createSpyObj( mockLog = jasmine.createSpyObj(
"$log", "$log",
[ "error", "warn", "info", "debug" ] ["error", "warn", "info", "debug"]
); );
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getModel", "getCapability", "hasCapability", "useCapability" ] ["getId", "getModel", "getCapability", "hasCapability", "useCapability"]
); );
mockType = jasmine.createSpyObj( mockType = jasmine.createSpyObj(
"type", "type",
[ "hasFeature" ] ["hasFeature"]
); );
mockEditor = jasmine.createSpyObj( mockEditor = jasmine.createSpyObj(
"editorCapability", "editorCapability",
@@ -66,7 +66,7 @@ define(
editor: mockEditor editor: mockEditor
}; };
mockDomainObject.getCapability.andCallFake( function (name) { mockDomainObject.getCapability.andCallFake(function (name) {
return capabilities[name]; return capabilities[name];
}); });
mockDomainObject.hasCapability.andReturn(true); mockDomainObject.hasCapability.andReturn(true);

View File

@@ -21,8 +21,8 @@
*****************************************************************************/ *****************************************************************************/
define( define(
["../../src/actions/LinkAction"], ["../../src/actions/EditAndComposeAction"],
function (LinkAction) { function (EditAndComposeAction) {
describe("The Link action", function () { describe("The Link action", function () {
var mockQ, var mockQ,
@@ -31,6 +31,8 @@ define(
mockContext, mockContext,
mockComposition, mockComposition,
mockPersistence, mockPersistence,
mockActionCapability,
mockEditAction,
mockType, mockType,
actionContext, actionContext,
model, model,
@@ -50,7 +52,7 @@ define(
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability" ] ["getId", "getCapability"]
); );
mockQ = { when: mockPromise }; mockQ = { when: mockPromise };
mockParent = { mockParent = {
@@ -64,25 +66,30 @@ define(
return capabilities[k].invoke(v); return capabilities[k].invoke(v);
} }
}; };
mockContext = jasmine.createSpyObj("context", [ "getParent" ]); mockContext = jasmine.createSpyObj("context", ["getParent"]);
mockComposition = jasmine.createSpyObj("composition", [ "invoke", "add" ]); mockComposition = jasmine.createSpyObj("composition", ["invoke", "add"]);
mockPersistence = jasmine.createSpyObj("persistence", [ "persist" ]); mockPersistence = jasmine.createSpyObj("persistence", ["persist"]);
mockType = jasmine.createSpyObj("type", [ "hasFeature" ]); mockType = jasmine.createSpyObj("type", ["hasFeature", "getKey"]);
mockActionCapability = jasmine.createSpyObj("actionCapability", ["getActions"]);
mockEditAction = jasmine.createSpyObj("editAction", ["perform"]);
mockDomainObject.getId.andReturn("test"); mockDomainObject.getId.andReturn("test");
mockDomainObject.getCapability.andReturn(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
mockContext.getParent.andReturn(mockParent); mockContext.getParent.andReturn(mockParent);
mockType.hasFeature.andReturn(true); mockType.hasFeature.andReturn(true);
mockType.getKey.andReturn("layout");
mockComposition.invoke.andReturn(mockPromise(true)); mockComposition.invoke.andReturn(mockPromise(true));
mockComposition.add.andReturn(mockPromise(true)); mockComposition.add.andReturn(mockPromise(true));
mockActionCapability.getActions.andReturn([]);
capabilities = { capabilities = {
composition: mockComposition, composition: mockComposition,
persistence: mockPersistence, persistence: mockPersistence,
action: mockActionCapability,
type: mockType type: mockType
}; };
model = { model = {
composition: [ "a", "b", "c" ] composition: ["a", "b", "c"]
}; };
actionContext = { actionContext = {
@@ -90,7 +97,7 @@ define(
selectedObject: mockDomainObject selectedObject: mockDomainObject
}; };
action = new LinkAction(actionContext); action = new EditAndComposeAction(actionContext);
}); });
@@ -105,6 +112,21 @@ define(
expect(mockPersistence.persist).toHaveBeenCalled(); expect(mockPersistence.persist).toHaveBeenCalled();
}); });
it("enables edit mode for objects that have an edit action", function () {
mockActionCapability.getActions.andReturn([mockEditAction]);
action.perform();
expect(mockEditAction.perform).toHaveBeenCalled();
});
it("Does not enable edit mode for objects that do not have an" +
" edit action", function () {
mockActionCapability.getActions.andReturn([]);
action.perform();
expect(mockEditAction.perform).not.toHaveBeenCalled();
expect(mockComposition.add)
.toHaveBeenCalledWith(mockDomainObject);
});
}); });
} }
); );

View File

@@ -38,7 +38,9 @@ define(
beforeEach(function () { beforeEach(function () {
capabilities = { capabilities = {
type: { type: {
getProperties: function () { return []; }, getProperties: function () {
return [];
},
hasFeature: jasmine.createSpy('hasFeature') hasFeature: jasmine.createSpy('hasFeature')
}, },
persistence: jasmine.createSpyObj("persistence", ["persist"]), persistence: jasmine.createSpyObj("persistence", ["persist"]),
@@ -47,11 +49,21 @@ define(
model = {}; model = {};
input = {}; input = {};
object = { object = {
getId: function () { return 'test-id'; }, getId: function () {
getCapability: function (k) { return capabilities[k]; }, return 'test-id';
getModel: function () { return model; }, },
useCapability: function (k, v) { return capabilities[k](v); }, getCapability: function (k) {
hasCapability: function () { return true; } return capabilities[k];
},
getModel: function () {
return model;
},
useCapability: function (k, v) {
return capabilities[k](v);
},
hasCapability: function () {
return true;
}
}; };
context = { someKey: "some value", domainObject: object }; context = { someKey: "some value", domainObject: object };
dialogService = { dialogService = {

View File

@@ -30,14 +30,22 @@ define(
beforeEach(function () { beforeEach(function () {
type = { type = {
getProperties: function () { return properties; } getProperties: function () {
return properties;
}
}; };
model = { x: "initial value" }; model = { x: "initial value" };
properties = ["x", "y", "z"].map(function (k) { properties = ["x", "y", "z"].map(function (k) {
return { return {
getValue: function (model) { return model[k]; }, getValue: function (m) {
setValue: function (model, v) { model[k] = v; }, return m[k];
getDefinition: function () { return { control: 'textfield '}; } },
setValue: function (m, v) {
m[k] = v;
},
getDefinition: function () {
return { control: 'textfield '};
}
}; };
}); });

View File

@@ -57,19 +57,19 @@ define(
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability" ] ["getId", "getCapability"]
); );
mockChildObject = jasmine.createSpyObj( mockChildObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability" ] ["getId", "getCapability"]
); );
mockGrandchildObject = jasmine.createSpyObj( mockGrandchildObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability" ] ["getId", "getCapability"]
); );
mockRootObject = jasmine.createSpyObj( mockRootObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getCapability" ] ["getId", "getCapability"]
); );
mockQ = { when: mockPromise }; mockQ = { when: mockPromise };
mockParent = { mockParent = {
@@ -83,13 +83,13 @@ define(
return capabilities[k].invoke(v); return capabilities[k].invoke(v);
} }
}; };
mockContext = jasmine.createSpyObj("context", [ "getParent" ]); mockContext = jasmine.createSpyObj("context", ["getParent"]);
mockChildContext = jasmine.createSpyObj("context", [ "getParent" ]); mockChildContext = jasmine.createSpyObj("context", ["getParent"]);
mockGrandchildContext = jasmine.createSpyObj("context", [ "getParent" ]); mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
mockRootContext = jasmine.createSpyObj("context", [ "getParent" ]); mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
mockMutation = jasmine.createSpyObj("mutation", [ "invoke" ]); mockMutation = jasmine.createSpyObj("mutation", ["invoke"]);
mockPersistence = jasmine.createSpyObj("persistence", [ "persist" ]); mockPersistence = jasmine.createSpyObj("persistence", ["persist"]);
mockType = jasmine.createSpyObj("type", [ "hasFeature" ]); mockType = jasmine.createSpyObj("type", ["hasFeature"]);
mockNavigationService = jasmine.createSpyObj( mockNavigationService = jasmine.createSpyObj(
"navigationService", "navigationService",
[ [
@@ -113,7 +113,7 @@ define(
type: mockType type: mockType
}; };
model = { model = {
composition: [ "a", "test", "b" ] composition: ["a", "test", "b"]
}; };
actionContext = { domainObject: mockDomainObject }; actionContext = { domainObject: mockDomainObject };

View File

@@ -52,11 +52,11 @@ define(
); );
mockEditorCapability = jasmine.createSpyObj( mockEditorCapability = jasmine.createSpyObj(
"editor", "editor",
[ "save", "cancel", "isEditContextRoot" ] ["save", "cancel", "isEditContextRoot"]
); );
mockActionCapability = jasmine.createSpyObj( mockActionCapability = jasmine.createSpyObj(
"actionCapability", "actionCapability",
[ "perform"] ["perform"]
); );
capabilities.editor = mockEditorCapability; capabilities.editor = mockEditorCapability;
capabilities.action = mockActionCapability; capabilities.action = mockActionCapability;
@@ -90,7 +90,7 @@ define(
function () { function () {
mockDomainObject.getModel.andReturn({persisted: undefined}); mockDomainObject.getModel.andReturn({persisted: undefined});
expect(SaveAction.appliesTo(actionContext)).toBe(false); expect(SaveAction.appliesTo(actionContext)).toBe(false);
}); });
it("uses the editor capability to save the object", it("uses the editor capability to save the object",
function () { function () {

View File

@@ -38,7 +38,7 @@ define(
capabilities = {}, capabilities = {},
action; action;
function noop () {} function noop() {}
function mockPromise(value) { function mockPromise(value) {
return (value || {}).then ? value : return (value || {}).then ? value :
@@ -49,7 +49,7 @@ define(
catch: function (callback) { catch: function (callback) {
return mockPromise(callback(value)); return mockPromise(callback(value));
} }
} ; } ;
} }
beforeEach(function () { beforeEach(function () {
@@ -78,7 +78,7 @@ define(
mockEditorCapability = jasmine.createSpyObj( mockEditorCapability = jasmine.createSpyObj(
"editor", "editor",
[ "save", "cancel", "isEditContextRoot" ] ["save", "cancel", "isEditContextRoot"]
); );
mockEditorCapability.cancel.andReturn(mockPromise(undefined)); mockEditorCapability.cancel.andReturn(mockPromise(undefined));
mockEditorCapability.save.andReturn(mockPromise(true)); mockEditorCapability.save.andReturn(mockPromise(true));
@@ -130,7 +130,7 @@ define(
action.createWizard.andReturn({ action.createWizard.andReturn({
getFormStructure: noop, getFormStructure: noop,
getInitialFormValue: noop, getInitialFormValue: noop,
populateObjectFromInput: function() { populateObjectFromInput: function () {
return mockDomainObject; return mockDomainObject;
} }
}); });

View File

@@ -82,7 +82,7 @@ define(
status: mockStatusCapability status: mockStatusCapability
}; };
mockDomainObject.hasCapability.andCallFake(function(name) { mockDomainObject.hasCapability.andCallFake(function (name) {
return capabilities[name] !== undefined; return capabilities[name] !== undefined;
}); });
@@ -126,8 +126,8 @@ define(
expect(capability.inEditContext()).toBe(true); expect(capability.inEditContext()).toBe(true);
}); });
describe("save", function() { describe("save", function () {
beforeEach(function() { beforeEach(function () {
capability.edit(); capability.edit();
capability.save(); capability.save();
}); });
@@ -139,8 +139,8 @@ define(
}); });
}); });
describe("cancel", function() { describe("cancel", function () {
beforeEach(function() { beforeEach(function () {
capability.edit(); capability.edit();
capability.cancel(); capability.cancel();
}); });
@@ -152,10 +152,10 @@ define(
}); });
}); });
describe("dirty", function() { describe("dirty", function () {
var model = {}; var model = {};
beforeEach(function() { beforeEach(function () {
mockDomainObject.getModel.andReturn(model); mockDomainObject.getModel.andReturn(model);
capability.edit(); capability.edit();
capability.cancel(); capability.cancel();

View File

@@ -33,18 +33,18 @@ define(
mockCapabilityService, mockCapabilityService,
provider; provider;
beforeEach(function() { beforeEach(function () {
mockQ = {}; mockQ = {};
mockTransactionService = {}; mockTransactionService = {};
mockCapabilityService = jasmine.createSpyObj("capabilityService", ["getCapabilities"]); mockCapabilityService = jasmine.createSpyObj("capabilityService", ["getCapabilities"]);
mockCapabilityService.getCapabilities.andReturn({ mockCapabilityService.getCapabilities.andReturn({
persistence: function() {} persistence: function () {}
}); });
provider = new TransactionCapabilityDecorator(mockQ, mockTransactionService, mockCapabilityService); provider = new TransactionCapabilityDecorator(mockQ, mockTransactionService, mockCapabilityService);
}); });
it("decorates the persistence capability", function() { it("decorates the persistence capability", function () {
var capabilities = provider.getCapabilities(); var capabilities = provider.getCapabilities();
expect(capabilities.persistence({}) instanceof TransactionalPersistenceCapability).toBe(true); expect(capabilities.persistence({}) instanceof TransactionalPersistenceCapability).toBe(true);
}); });

View File

@@ -29,7 +29,7 @@ define(
function fastPromise(val) { function fastPromise(val) {
return { return {
then: function(callback) { then: function (callback) {
return callback(val); return callback(val);
} }
}; };
@@ -42,7 +42,7 @@ define(
mockDomainObject, mockDomainObject,
capability; capability;
beforeEach(function() { beforeEach(function () {
mockQ = jasmine.createSpyObj("$q", ["when"]); mockQ = jasmine.createSpyObj("$q", ["when"]);
mockQ.when.andCallFake(function (val) { mockQ.when.andCallFake(function (val) {
return fastPromise(val); return fastPromise(val);
@@ -61,14 +61,14 @@ define(
}); });
it("if no transaction is active, passes through to persistence" + it("if no transaction is active, passes through to persistence" +
" provider", function() { " provider", function () {
mockTransactionService.isActive.andReturn(false); mockTransactionService.isActive.andReturn(false);
capability.persist(); capability.persist();
expect(mockPersistence.persist).toHaveBeenCalled(); expect(mockPersistence.persist).toHaveBeenCalled();
}); });
it("if transaction is active, persist and cancel calls are" + it("if transaction is active, persist and cancel calls are" +
" queued", function() { " queued", function () {
mockTransactionService.isActive.andReturn(true); mockTransactionService.isActive.andReturn(true);
capability.persist(); capability.persist();
expect(mockTransactionService.addToTransaction).toHaveBeenCalled(); expect(mockTransactionService.addToTransaction).toHaveBeenCalled();
@@ -78,7 +78,7 @@ define(
expect(mockPersistence.refresh).toHaveBeenCalled(); expect(mockPersistence.refresh).toHaveBeenCalled();
}); });
it("persist call is only added to transaction once", function() { it("persist call is only added to transaction once", function () {
mockTransactionService.isActive.andReturn(true); mockTransactionService.isActive.andReturn(true);
capability.persist(); capability.persist();
expect(mockTransactionService.addToTransaction).toHaveBeenCalled(); expect(mockTransactionService.addToTransaction).toHaveBeenCalled();

View File

@@ -52,15 +52,15 @@ define(
); );
mockScope = jasmine.createSpyObj( mockScope = jasmine.createSpyObj(
"$scope", "$scope",
[ "$on", "$watch" ] ["$on", "$watch"]
); );
mockObject = jasmine.createSpyObj( mockObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getId", "getModel", "getCapability", "hasCapability", "useCapability" ] ["getId", "getModel", "getCapability", "hasCapability", "useCapability"]
); );
mockType = jasmine.createSpyObj( mockType = jasmine.createSpyObj(
"type", "type",
[ "hasFeature" ] ["hasFeature"]
); );
mockStatusCapability = jasmine.createSpyObj('statusCapability', mockStatusCapability = jasmine.createSpyObj('statusCapability',
["get"] ["get"]
@@ -99,8 +99,8 @@ define(
expect(controller.getUnloadWarning()).toBeUndefined(); expect(controller.getUnloadWarning()).toBeUndefined();
// Override the policy service to prevent navigation // Override the policy service to prevent navigation
mockPolicyService.allow.andCallFake(function(category, object, context, callback){ mockPolicyService.allow.andCallFake(function (category, object, context, callback) {
callback(errorMessage); callback(errorMessage);
}); });
// Should have some warning message here now // Should have some warning message here now

View File

@@ -34,11 +34,11 @@ define(
mockScope = jasmine.createSpyObj("$scope", ["$watch"]); mockScope = jasmine.createSpyObj("$scope", ["$watch"]);
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
'domainObject', 'domainObject',
[ 'getId', 'getCapability' ] ['getId', 'getCapability']
); );
mockContext = jasmine.createSpyObj( mockContext = jasmine.createSpyObj(
'context', 'context',
[ 'getTrueRoot' ] ['getTrueRoot']
); );
mockDomainObject.getId.andReturn('test-id'); mockDomainObject.getId.andReturn('test-id');

View File

@@ -34,8 +34,8 @@ define(
controller = new ElementsController(mockScope); controller = new ElementsController(mockScope);
}); });
function getModel (model) { function getModel(model) {
return function() { return function () {
return model; return model;
}; };
} }

View File

@@ -60,37 +60,37 @@ define(
beforeEach(function () { beforeEach(function () {
mockTypeService = jasmine.createSpyObj( mockTypeService = jasmine.createSpyObj(
"typeService", "typeService",
[ "listTypes" ] ["listTypes"]
); );
mockDialogService = jasmine.createSpyObj( mockDialogService = jasmine.createSpyObj(
"dialogService", "dialogService",
[ "getUserInput" ] ["getUserInput"]
); );
mockPolicyService = jasmine.createSpyObj( mockPolicyService = jasmine.createSpyObj(
"policyService", "policyService",
[ "allow" ] ["allow"]
); );
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getCapability" ] ["getCapability"]
); );
//Mocking getCapability because AddActionProvider uses the //Mocking getCapability because AddActionProvider uses the
// type capability of the destination object. // type capability of the destination object.
mockDomainObject.getCapability.andReturn({}); mockDomainObject.getCapability.andReturn({});
mockTypes = [ "A", "B", "C" ].map(createMockType); mockTypes = ["A", "B", "C"].map(createMockType);
mockTypes.forEach(function(type){ mockTypes.forEach(function (type) {
mockPolicyMap[type.getName()] = true; mockPolicyMap[type.getName()] = true;
}); });
mockCreationPolicy = function(type){ mockCreationPolicy = function (type) {
return mockPolicyMap[type.getName()]; return mockPolicyMap[type.getName()];
}; };
mockCompositionPolicy = function(){ mockCompositionPolicy = function () {
return true; return true;
}; };

View File

@@ -29,13 +29,10 @@ define(
describe("The create action provider", function () { describe("The create action provider", function () {
var mockTypeService, var mockTypeService,
mockDialogService,
mockNavigationService,
mockPolicyService, mockPolicyService,
mockCreationPolicy, mockCreationPolicy,
mockPolicyMap = {}, mockPolicyMap = {},
mockTypes, mockTypes,
mockQ,
provider; provider;
function createMockType(name) { function createMockType(name) {
@@ -59,41 +56,31 @@ define(
beforeEach(function () { beforeEach(function () {
mockTypeService = jasmine.createSpyObj( mockTypeService = jasmine.createSpyObj(
"typeService", "typeService",
[ "listTypes" ] ["listTypes"]
);
mockDialogService = jasmine.createSpyObj(
"dialogService",
[ "getUserInput" ]
);
mockNavigationService = jasmine.createSpyObj(
"navigationService",
[ "setNavigation" ]
); );
mockPolicyService = jasmine.createSpyObj( mockPolicyService = jasmine.createSpyObj(
"policyService", "policyService",
[ "allow" ] ["allow"]
); );
mockTypes = [ "A", "B", "C" ].map(createMockType); mockTypes = ["A", "B", "C"].map(createMockType);
mockTypes.forEach(function(type){ mockTypes.forEach(function (type) {
mockPolicyMap[type.getName()] = true; mockPolicyMap[type.getName()] = true;
}); });
mockCreationPolicy = function(type){ mockCreationPolicy = function (type) {
return mockPolicyMap[type.getName()]; return mockPolicyMap[type.getName()];
}; };
mockPolicyService.allow.andCallFake(function(category, type){ mockPolicyService.allow.andCallFake(function (category, type) {
return category === "creation" && mockCreationPolicy(type) ? true : false; return category === "creation" && mockCreationPolicy(type) ? true : false;
}); });
mockTypeService.listTypes.andReturn(mockTypes); mockTypeService.listTypes.andReturn(mockTypes);
provider = new CreateActionProvider( provider = new CreateActionProvider(
mockQ,
mockTypeService, mockTypeService,
mockNavigationService,
mockPolicyService mockPolicyService
); );
}); });

View File

@@ -0,0 +1,190 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/**
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
*/
define(
["../../src/creation/CreateAction"],
function (CreateAction) {
describe("The create action", function () {
var mockType,
mockParent,
mockContext,
mockDomainObject,
capabilities = {},
mockEditAction,
mockSaveAction,
action;
function mockPromise(value) {
return {
then: function (callback) {
return mockPromise(callback(value));
}
};
}
beforeEach(function () {
mockType = jasmine.createSpyObj(
"type",
[
"getKey",
"getGlyph",
"getName",
"getDescription",
"getProperties",
"getInitialModel"
]
);
mockParent = jasmine.createSpyObj(
"domainObject",
[
"getId",
"getModel",
"getCapability",
"useCapability"
]
);
mockDomainObject = jasmine.createSpyObj(
"domainObject",
[
"getId",
"getModel",
"getCapability",
"hasCapability",
"useCapability"
]
);
mockDomainObject.hasCapability.andCallFake(function (name) {
return !!capabilities[name];
});
mockDomainObject.getCapability.andCallFake(function (name) {
return capabilities[name];
});
mockSaveAction = jasmine.createSpyObj(
"saveAction",
[
"perform"
]
);
capabilities.action = jasmine.createSpyObj(
"actionCapability",
[
"getActions",
"perform"
]
);
capabilities.editor = jasmine.createSpyObj(
"editorCapability",
[
"edit",
"save",
"cancel"
]
);
mockEditAction = jasmine.createSpyObj(
"editAction",
[
"perform"
]
);
mockContext = {
domainObject: mockParent
};
mockParent.useCapability.andReturn(mockDomainObject);
mockType.getKey.andReturn("test");
mockType.getGlyph.andReturn("T");
mockType.getDescription.andReturn("a test type");
mockType.getName.andReturn("Test");
mockType.getProperties.andReturn([]);
mockType.getInitialModel.andReturn({});
action = new CreateAction(
mockType,
mockParent,
mockContext
);
});
it("exposes type-appropriate metadata", function () {
var metadata = action.getMetadata();
expect(metadata.name).toEqual("Test");
expect(metadata.description).toEqual("a test type");
expect(metadata.glyph).toEqual("T");
});
describe("the perform function", function () {
beforeEach(function () {
capabilities.action.getActions.andReturn([mockEditAction]);
});
it("uses the instantiation capability when performed", function () {
action.perform();
expect(mockParent.useCapability).toHaveBeenCalledWith("instantiation", jasmine.any(Object));
});
it("uses the edit action if available", function () {
action.perform();
expect(mockEditAction.perform).toHaveBeenCalled();
});
it("uses the save action if object does not have an edit action" +
" available", function () {
capabilities.action.getActions.andReturn([]);
capabilities.action.perform.andReturn(mockPromise(undefined));
action.perform();
expect(capabilities.action.perform).toHaveBeenCalledWith("save");
});
describe("uses to editor capability", function () {
var promise = jasmine.createSpyObj("promise", ["then"]);
beforeEach(function () {
capabilities.action.getActions.andReturn([]);
capabilities.action.perform.andReturn(promise);
});
it("to save the edit if user saves dialog", function () {
action.perform();
expect(promise.then).toHaveBeenCalled();
promise.then.mostRecentCall.args[0]();
expect(capabilities.editor.save).toHaveBeenCalled();
});
it("to cancel the edit if user cancels dialog", function () {
action.perform();
promise.then.mostRecentCall.args[1]();
expect(capabilities.editor.cancel).toHaveBeenCalled();
});
});
});
});
}
);

View File

@@ -39,7 +39,7 @@ define(
function createMockProperty(name) { function createMockProperty(name) {
var mockProperty = jasmine.createSpyObj( var mockProperty = jasmine.createSpyObj(
"property" + name, "property" + name,
[ "getDefinition", "getValue", "setValue" ] ["getDefinition", "getValue", "setValue"]
); );
mockProperty.getDefinition.andReturn({ mockProperty.getDefinition.andReturn({
control: "textfield" control: "textfield"
@@ -68,7 +68,7 @@ define(
"getCapability" "getCapability"
] ]
); );
mockProperties = [ "A", "B", "C" ].map(createMockProperty); mockProperties = ["A", "B", "C"].map(createMockProperty);
mockPolicyService = jasmine.createSpyObj('policyService', ['allow']); mockPolicyService = jasmine.createSpyObj('policyService', ['allow']);
testModel = { someKey: "some value" }; testModel = { someKey: "some value" };
@@ -144,15 +144,15 @@ define(
"A": "ValueA", "A": "ValueA",
"B": "ValueB", "B": "ValueB",
"C": "ValueC" "C": "ValueC"
}, },
compareModel = wizard.createModel(formValue); compareModel = wizard.createModel(formValue);
wizard.populateObjectFromInput(formValue); wizard.populateObjectFromInput(formValue);
expect(mockDomainObject.useCapability).toHaveBeenCalledWith('mutation', jasmine.any(Function)); expect(mockDomainObject.useCapability).toHaveBeenCalledWith('mutation', jasmine.any(Function));
expect(mockDomainObject.useCapability.mostRecentCall.args[1]()).toEqual(compareModel); expect(mockDomainObject.useCapability.mostRecentCall.args[1]()).toEqual(compareModel);
}); });
it("validates selection types using policy", function () { it("validates selection types using policy", function () {
var mockDomainObject = jasmine.createSpyObj( var mockDomainObj = jasmine.createSpyObj(
'domainObject', 'domainObject',
['getCapability'] ['getCapability']
), ),
@@ -166,8 +166,8 @@ define(
rows = structure.sections[sections.length - 1].rows, rows = structure.sections[sections.length - 1].rows,
locationRow = rows[rows.length - 1]; locationRow = rows[rows.length - 1];
mockDomainObject.getCapability.andReturn(mockOtherType); mockDomainObj.getCapability.andReturn(mockOtherType);
locationRow.validate(mockDomainObject); locationRow.validate(mockDomainObj);
// Should check policy to see if the user-selected location // Should check policy to see if the user-selected location
// can actually contain objects of this type // can actually contain objects of this type
@@ -179,7 +179,7 @@ define(
}); });
it("creates a form model without a location if not requested", function () { it("creates a form model without a location if not requested", function () {
expect(wizard.getFormStructure(false).sections.some(function(section){ expect(wizard.getFormStructure(false).sections.some(function (section) {
return section.name === 'Location'; return section.name === 'Location';
})).toEqual(false); })).toEqual(false);
}); });

View File

@@ -61,23 +61,23 @@ define(
mockQ = { when: mockPromise, reject: mockReject }; mockQ = { when: mockPromise, reject: mockReject };
mockLog = jasmine.createSpyObj( mockLog = jasmine.createSpyObj(
"$log", "$log",
[ "error", "warn", "info", "debug" ] ["error", "warn", "info", "debug"]
); );
mockParentObject = jasmine.createSpyObj( mockParentObject = jasmine.createSpyObj(
"parentObject", "parentObject",
[ "getId", "getCapability", "useCapability" ] ["getId", "getCapability", "useCapability"]
); );
mockNewObject = jasmine.createSpyObj( mockNewObject = jasmine.createSpyObj(
"newObject", "newObject",
[ "getId", "getCapability", "useCapability" ] ["getId", "getCapability", "useCapability"]
); );
mockMutationCapability = jasmine.createSpyObj( mockMutationCapability = jasmine.createSpyObj(
"mutation", "mutation",
[ "invoke" ] ["invoke"]
); );
mockPersistenceCapability = jasmine.createSpyObj( mockPersistenceCapability = jasmine.createSpyObj(
"persistence", "persistence",
[ "persist", "getSpace" ] ["persist", "getSpace"]
); );
mockCompositionCapability = jasmine.createSpyObj( mockCompositionCapability = jasmine.createSpyObj(
"composition", "composition",
@@ -100,7 +100,7 @@ define(
}; };
mockNewPersistenceCapability = jasmine.createSpyObj( mockNewPersistenceCapability = jasmine.createSpyObj(
"new-persistence", "new-persistence",
[ "persist", "getSpace" ] ["persist", "getSpace"]
); );
mockParentObject.getCapability.andCallFake(function (key) { mockParentObject.getCapability.andCallFake(function (key) {

View File

@@ -40,20 +40,20 @@ define(
beforeEach(function () { beforeEach(function () {
mockScope = jasmine.createSpyObj( mockScope = jasmine.createSpyObj(
"$scope", "$scope",
[ "$watch" ] ["$watch"]
); );
mockTimeout = jasmine.createSpy("$timeout"); mockTimeout = jasmine.createSpy("$timeout");
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
[ "getCapability" ] ["getCapability"]
); );
mockRootObject = jasmine.createSpyObj( mockRootObject = jasmine.createSpyObj(
"rootObject", "rootObject",
[ "getCapability" ] ["getCapability"]
); );
mockContext = jasmine.createSpyObj( mockContext = jasmine.createSpyObj(
"context", "context",
[ "getRoot" ] ["getRoot"]
); );
mockObjectService = jasmine.createSpyObj( mockObjectService = jasmine.createSpyObj(
"objectService", "objectService",
@@ -73,18 +73,18 @@ define(
controller = new LocatorController(mockScope, mockTimeout, mockObjectService); controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
}); });
describe("when context is available", function () { describe("when context is available", function () {
beforeEach(function () { beforeEach(function () {
mockContext.getRoot.andReturn(mockRootObject); mockContext.getRoot.andReturn(mockRootObject);
controller = new LocatorController(mockScope, mockTimeout, mockObjectService); controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
}); });
it("adds a treeModel to scope", function () { it("adds a treeModel to scope", function () {
expect(mockScope.treeModel).toBeDefined(); expect(mockScope.treeModel).toBeDefined();
}); });
it("watches for changes to treeModel", function () { it("watches for changes to treeModel", function () {
// This is what the embedded tree representation // This is what the embedded tree representation
// will be modifying. // will be modifying.
expect(mockScope.$watch).toHaveBeenCalledWith( expect(mockScope.$watch).toHaveBeenCalledWith(
@@ -93,7 +93,7 @@ define(
); );
}); });
it("changes its own model on embedded model updates", function () { it("changes its own model on embedded model updates", function () {
// Need to pass on selection changes as updates to // Need to pass on selection changes as updates to
// the control's value // the control's value
mockScope.$watch.mostRecentCall.args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
@@ -107,7 +107,7 @@ define(
.toHaveBeenCalledWith("context"); .toHaveBeenCalledWith("context");
}); });
it("rejects changes which fail validation", function () { it("rejects changes which fail validation", function () {
mockScope.structure = { validate: jasmine.createSpy('validate') }; mockScope.structure = { validate: jasmine.createSpy('validate') };
mockScope.structure.validate.andReturn(false); mockScope.structure.validate.andReturn(false);
@@ -120,10 +120,10 @@ define(
expect(mockScope.ngModel.someField).not.toEqual(mockDomainObject); expect(mockScope.ngModel.someField).not.toEqual(mockDomainObject);
}); });
it("treats a lack of a selection as invalid", function () { it("treats a lack of a selection as invalid", function () {
mockScope.ngModelController = jasmine.createSpyObj( mockScope.ngModelController = jasmine.createSpyObj(
'ngModelController', 'ngModelController',
[ '$setValidity' ] ['$setValidity']
); );
mockScope.$watch.mostRecentCall.args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
@@ -136,14 +136,14 @@ define(
expect(mockScope.ngModelController.$setValidity) expect(mockScope.ngModelController.$setValidity)
.toHaveBeenCalledWith(jasmine.any(String), false); .toHaveBeenCalledWith(jasmine.any(String), false);
}); });
}); });
describe("when no context is available", function () { describe("when no context is available", function () {
var defaultRoot = "DEFAULT_ROOT"; var defaultRoot = "DEFAULT_ROOT";
beforeEach(function () { beforeEach(function () {
mockContext.getRoot.andReturn(undefined); mockContext.getRoot.andReturn(undefined);
getObjectsPromise.then.andCallFake(function(callback){ getObjectsPromise.then.andCallFake(function (callback) {
callback({'ROOT':defaultRoot}); callback({'ROOT': defaultRoot});
}); });
controller = new LocatorController(mockScope, mockTimeout, mockObjectService); controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
}); });

View File

@@ -58,10 +58,10 @@ define(
mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']); mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']);
mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']); mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']);
mockDomainObject.getCapability.andCallFake(function(capability){ mockDomainObject.getCapability.andCallFake(function (capability) {
return capabilities[capability]; return capabilities[capability];
}); });
mockDomainObject.hasCapability.andCallFake(function(capability){ mockDomainObject.hasCapability.andCallFake(function (capability) {
return !!capabilities[capability]; return !!capabilities[capability];
}); });
@@ -88,42 +88,42 @@ define(
}); });
it("allows the edit action when there are editable views", function () { it("allows the edit action when there are editable views", function () {
testViews = [ editableView ]; testViews = [editableView];
expect(policy.allow(mockEditAction, testContext)).toBe(true); expect(policy.allow(mockEditAction, testContext)).toBe(true);
}); });
it("allows the edit properties action when there are no editable views", function () { it("allows the edit properties action when there are no editable views", function () {
testViews = [ nonEditableView, nonEditableView ]; testViews = [nonEditableView, nonEditableView];
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true); expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
}); });
it("disallows the edit action when there are no editable views", function () { it("disallows the edit action when there are no editable views", function () {
testViews = [ nonEditableView, nonEditableView ]; testViews = [nonEditableView, nonEditableView];
expect(policy.allow(mockEditAction, testContext)).toBe(false); expect(policy.allow(mockEditAction, testContext)).toBe(false);
}); });
it("disallows the edit properties action when there are" + it("disallows the edit properties action when there are" +
" editable views", function () { " editable views", function () {
testViews = [ editableView ]; testViews = [editableView];
expect(policy.allow(mockPropertiesAction, testContext)).toBe(false); expect(policy.allow(mockPropertiesAction, testContext)).toBe(false);
}); });
it("disallows the edit action when object is already being" + it("disallows the edit action when object is already being" +
" edited", function () { " edited", function () {
testViews = [ editableView ]; testViews = [editableView];
mockEditorCapability.isEditContextRoot.andReturn(true); mockEditorCapability.isEditContextRoot.andReturn(true);
expect(policy.allow(mockEditAction, testContext)).toBe(false); expect(policy.allow(mockEditAction, testContext)).toBe(false);
}); });
it("allows editing of panels in plot view", function () { it("allows editing of panels in plot view", function () {
testViews = [ plotView ]; testViews = [plotView];
mockTypeCapability.getKey.andReturn('telemetry.panel'); mockTypeCapability.getKey.andReturn('telemetry.panel');
expect(policy.allow(mockEditAction, testContext)).toBe(true); expect(policy.allow(mockEditAction, testContext)).toBe(true);
}); });
it("disallows editing of plot view when object not a panel type", function () { it("disallows editing of plot view when object not a panel type", function () {
testViews = [ plotView ]; testViews = [plotView];
mockTypeCapability.getKey.andReturn('something.else'); mockTypeCapability.getKey.andReturn('something.else');
expect(policy.allow(mockEditAction, testContext)).toBe(false); expect(policy.allow(mockEditAction, testContext)).toBe(false);
@@ -131,7 +131,7 @@ define(
it("allows the edit properties outside of the 'view-control' category", function () { it("allows the edit properties outside of the 'view-control' category", function () {
testViews = [ nonEditableView ]; testViews = [nonEditableView];
testContext.category = "something-else"; testContext.category = "something-else";
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true); expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
}); });

View File

@@ -61,12 +61,12 @@ define(
policy = new EditContextualActionPolicy(navigationService, editModeBlacklist, nonEditContextBlacklist); policy = new EditContextualActionPolicy(navigationService, editModeBlacklist, nonEditContextBlacklist);
}); });
it('Allows all actions when navigated object not in edit mode', function() { it('Allows all actions when navigated object not in edit mode', function () {
expect(policy.allow(mockAction, context)).toBe(true); expect(policy.allow(mockAction, context)).toBe(true);
}); });
it('Allows "window" action when navigated object in edit mode,' + it('Allows "window" action when navigated object in edit mode,' +
' but selected object not in edit mode ', function() { ' but selected object not in edit mode ', function () {
navigatedObject.hasCapability.andReturn(true); navigatedObject.hasCapability.andReturn(true);
mockEditorCapability.isEditContextRoot.andReturn(true); mockEditorCapability.isEditContextRoot.andReturn(true);
metadata.key = "window"; metadata.key = "window";
@@ -75,7 +75,7 @@ define(
it('Allows "remove" action when navigated object in edit mode,' + it('Allows "remove" action when navigated object in edit mode,' +
' and selected object not editable, but its parent is.', ' and selected object not editable, but its parent is.',
function() { function () {
var mockParent = jasmine.createSpyObj("parentObject", ["hasCapability"]), var mockParent = jasmine.createSpyObj("parentObject", ["hasCapability"]),
mockContextCapability = jasmine.createSpyObj("contextCapability", ["getParent"]); mockContextCapability = jasmine.createSpyObj("contextCapability", ["getParent"]);
@@ -93,10 +93,10 @@ define(
metadata.key = "remove"; metadata.key = "remove";
expect(policy.allow(mockAction, context)).toBe(true); expect(policy.allow(mockAction, context)).toBe(true);
}); });
it('Disallows "move" action when navigated object in edit mode,' + it('Disallows "move" action when navigated object in edit mode,' +
' but selected object not in edit mode ', function() { ' but selected object not in edit mode ', function () {
navigatedObject.hasCapability.andReturn(true); navigatedObject.hasCapability.andReturn(true);
mockEditorCapability.isEditContextRoot.andReturn(true); mockEditorCapability.isEditContextRoot.andReturn(true);
mockEditorCapability.inEditContext.andReturn(false); mockEditorCapability.inEditContext.andReturn(false);
@@ -105,7 +105,7 @@ define(
}); });
it('Disallows copy action when navigated object and' + it('Disallows copy action when navigated object and' +
' selected object in edit mode', function() { ' selected object in edit mode', function () {
navigatedObject.hasCapability.andReturn(true); navigatedObject.hasCapability.andReturn(true);
mockDomainObject.hasCapability.andReturn(true); mockDomainObject.hasCapability.andReturn(true);
mockEditorCapability.isEditContextRoot.andReturn(true); mockEditorCapability.isEditContextRoot.andReturn(true);

View File

@@ -36,7 +36,7 @@ define(
['hasCapability', 'getCapability'] ['hasCapability', 'getCapability']
); );
mockDomainObject.getCapability.andReturn({ mockDomainObject.getCapability.andReturn({
inEditContext: function () { inEditContext: function () {
return true; return true;
} }
}); });

View File

@@ -72,7 +72,7 @@ define(
mockDomainObject.getModel.andReturn({}); mockDomainObject.getModel.andReturn({});
mockDomainObject.hasCapability.andReturn(true); mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.useCapability.andReturn(true); mockDomainObject.useCapability.andReturn(true);
mockDomainObject.getCapability.andCallFake(function(capability){ mockDomainObject.getCapability.andCallFake(function (capability) {
return mockCapabilities[capability]; return mockCapabilities[capability];
}); });

View File

@@ -34,13 +34,13 @@ define(
beforeEach(function () { beforeEach(function () {
mockScope = jasmine.createSpyObj( mockScope = jasmine.createSpyObj(
'$scope', '$scope',
[ '$on', '$watch', '$watchCollection', "commit" ] ['$on', '$watch', '$watchCollection', "commit"]
); );
mockElement = {}; mockElement = {};
testAttrs = { toolbar: 'testToolbar' }; testAttrs = { toolbar: 'testToolbar' };
mockScope.$parent = jasmine.createSpyObj( mockScope.$parent = jasmine.createSpyObj(
'$parent', '$parent',
[ '$watch', '$watchCollection' ] ['$watch', '$watchCollection']
); );
mockUnwatch = jasmine.createSpy('unwatch'); mockUnwatch = jasmine.createSpy('unwatch');
@@ -92,7 +92,7 @@ define(
// Provide a view which has a toolbar // Provide a view which has a toolbar
representer.represent({ representer.represent({
toolbar: { sections: [ { items: [ { property: 'k' } ] } ] } toolbar: { sections: [{ items: [{ property: 'k' }] }] }
}); });
// Update the selection // Update the selection
@@ -120,7 +120,7 @@ define(
// Provide a view which has a toolbar // Provide a view which has a toolbar
representer.represent({ representer.represent({
toolbar: { sections: [ { items: [ { property: 'k' } ] } ] } toolbar: { sections: [{ items: [{ property: 'k' }] }] }
}); });
// Update the selection // Update the selection

View File

@@ -76,7 +76,7 @@ define(
it("provides properties from the original structure", function () { it("provides properties from the original structure", function () {
expect( expect(
new EditToolbar(testStructure, [ testABC ]) new EditToolbar(testStructure, [testABC])
.getStructure() .getStructure()
.sections[0] .sections[0]
.items[1] .items[1]
@@ -87,7 +87,7 @@ define(
// This is needed by mct-toolbar // This is needed by mct-toolbar
it("adds keys to form structure", function () { it("adds keys to form structure", function () {
expect( expect(
new EditToolbar(testStructure, [ testABC ]) new EditToolbar(testStructure, [testABC])
.getStructure() .getStructure()
.sections[0] .sections[0]
.items[1] .items[1]
@@ -97,20 +97,20 @@ define(
it("marks empty sections as hidden", function () { it("marks empty sections as hidden", function () {
// Verify that all sections are included when applicable... // Verify that all sections are included when applicable...
toolbar.setSelection([ testABCXYZ ]); toolbar.setSelection([testABCXYZ]);
expect(toolbar.getStructure().sections.map(getVisibility)) expect(toolbar.getStructure().sections.map(getVisibility))
.toEqual([ true, true, false ]); .toEqual([true, true, false]);
// ...but omitted when only some are applicable // ...but omitted when only some are applicable
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
expect(toolbar.getStructure().sections.map(getVisibility)) expect(toolbar.getStructure().sections.map(getVisibility))
.toEqual([ true, false, false ]); .toEqual([true, false, false]);
}); });
it("reads properties from selections", function () { it("reads properties from selections", function () {
var structure, state; var structure, state;
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
structure = toolbar.getStructure(); structure = toolbar.getStructure();
state = toolbar.getState(); state = toolbar.getState();
@@ -126,9 +126,11 @@ define(
it("reads properties from getters", function () { it("reads properties from getters", function () {
var structure, state; var structure, state;
testABC.a = function () { return "from a getter!"; }; testABC.a = function () {
return "from a getter!";
};
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
structure = toolbar.getStructure(); structure = toolbar.getStructure();
state = toolbar.getState(); state = toolbar.getState();
@@ -137,7 +139,7 @@ define(
}); });
it("sets properties on update", function () { it("sets properties on update", function () {
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
toolbar.updateState( toolbar.updateState(
toolbar.getStructure().sections[0].items[0].key, toolbar.getStructure().sections[0].items[0].key,
"new value" "new value"
@@ -151,7 +153,7 @@ define(
testABC.a = jasmine.createSpy('a'); testABC.a = jasmine.createSpy('a');
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
structure = toolbar.getStructure(); structure = toolbar.getStructure();
toolbar.updateState( toolbar.updateState(
@@ -165,7 +167,7 @@ define(
it("provides a return value describing update status", function () { it("provides a return value describing update status", function () {
// Should return true if actually updated, otherwise false // Should return true if actually updated, otherwise false
var key; var key;
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
key = toolbar.getStructure().sections[0].items[0].key; key = toolbar.getStructure().sections[0].items[0].key;
expect(toolbar.updateState(key, testABC.a)).toBeFalsy(); expect(toolbar.updateState(key, testABC.a)).toBeFalsy();
expect(toolbar.updateState(key, "new value")).toBeTruthy(); expect(toolbar.updateState(key, "new value")).toBeTruthy();
@@ -173,35 +175,35 @@ define(
it("removes inapplicable items", function () { it("removes inapplicable items", function () {
// First, verify with all items // First, verify with all items
toolbar.setSelection([ testABC ]); toolbar.setSelection([testABC]);
expect(toolbar.getStructure().sections[0].items.map(getVisibility)) expect(toolbar.getStructure().sections[0].items.map(getVisibility))
.toEqual([ true, true, true ]); .toEqual([true, true, true]);
// Then, try with some items omitted // Then, try with some items omitted
toolbar.setSelection([ testABC, testAB ]); toolbar.setSelection([testABC, testAB]);
expect(toolbar.getStructure().sections[0].items.map(getVisibility)) expect(toolbar.getStructure().sections[0].items.map(getVisibility))
.toEqual([ true, true, false ]); .toEqual([true, true, false]);
}); });
it("removes inconsistent states", function () { it("removes inconsistent states", function () {
// Only two of three values match among these selections // Only two of three values match among these selections
toolbar.setSelection([ testABC, testABC2 ]); toolbar.setSelection([testABC, testABC2]);
expect(toolbar.getStructure().sections[0].items.map(getVisibility)) expect(toolbar.getStructure().sections[0].items.map(getVisibility))
.toEqual([ false, true, true ]); .toEqual([false, true, true]);
}); });
it("allows inclusive items", function () { it("allows inclusive items", function () {
// One inclusive item is in the set, property 'x' of the // One inclusive item is in the set, property 'x' of the
// second section; make sure items are pruned down // second section; make sure items are pruned down
// when only some of the selection has x,y,z properties // when only some of the selection has x,y,z properties
toolbar.setSelection([ testABC, testABCXYZ ]); toolbar.setSelection([testABC, testABCXYZ]);
expect(toolbar.getStructure().sections[1].items.map(getVisibility)) expect(toolbar.getStructure().sections[1].items.map(getVisibility))
.toEqual([ true, false, false ]); .toEqual([true, false, false]);
}); });
it("removes inclusive items when there are no matches", function () { it("removes inclusive items when there are no matches", function () {
toolbar.setSelection([ testABCYZ ]); toolbar.setSelection([testABCYZ]);
expect(toolbar.getStructure().sections[1].items.map(getVisibility)) expect(toolbar.getStructure().sections[1].items.map(getVisibility))
.toEqual([ false, true, true ]); .toEqual([false, true, true]);
}); });
it("adds click functions when a method is specified", function () { it("adds click functions when a method is specified", function () {

View File

@@ -30,7 +30,7 @@ define(
mockLog, mockLog,
transactionService; transactionService;
function fastPromise (val) { function fastPromise(val) {
return { return {
then: function (callback) { then: function (callback) {
return fastPromise(callback(val)); return fastPromise(callback(val));
@@ -75,8 +75,8 @@ define(
describe("commit", function () { describe("commit", function () {
var onCommits; var onCommits;
beforeEach(function() { beforeEach(function () {
onCommits = [0, 1, 2].map(function(val) { onCommits = [0, 1, 2].map(function (val) {
return jasmine.createSpy("onCommit" + val); return jasmine.createSpy("onCommit" + val);
}); });
@@ -87,7 +87,7 @@ define(
it("commit calls all queued commit functions", function () { it("commit calls all queued commit functions", function () {
expect(transactionService.onCommits.length).toBe(3); expect(transactionService.onCommits.length).toBe(3);
transactionService.commit(); transactionService.commit();
onCommits.forEach( function (spy) { onCommits.forEach(function (spy) {
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}); });
}); });
@@ -104,8 +104,8 @@ define(
describe("cancel", function () { describe("cancel", function () {
var onCancels; var onCancels;
beforeEach(function() { beforeEach(function () {
onCancels = [0, 1, 2].map(function(val) { onCancels = [0, 1, 2].map(function (val) {
return jasmine.createSpy("onCancel" + val); return jasmine.createSpy("onCancel" + val);
}); });
@@ -118,7 +118,7 @@ define(
it("cancel calls all queued cancel functions", function () { it("cancel calls all queued cancel functions", function () {
expect(transactionService.onCancels.length).toBe(3); expect(transactionService.onCancels.length).toBe(3);
transactionService.cancel(); transactionService.cancel();
onCancels.forEach( function (spy) { onCancels.forEach(function (spy) {
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}); });
}); });

View File

@@ -24,7 +24,7 @@ define(
['../src/FormatProvider'], ['../src/FormatProvider'],
function (FormatProvider) { function (FormatProvider) {
var KEYS = [ 'a', 'b', 'c' ]; var KEYS = ['a', 'b', 'c'];
describe("The FormatProvider", function () { describe("The FormatProvider", function () {
var mockFormats, var mockFormats,
@@ -35,12 +35,14 @@ define(
mockFormatInstances = KEYS.map(function (k) { mockFormatInstances = KEYS.map(function (k) {
return jasmine.createSpyObj( return jasmine.createSpyObj(
'format-' + k, 'format-' + k,
[ 'parse', 'validate', 'format' ] ['parse', 'validate', 'format']
); );
}); });
// Return constructors // Return constructors
mockFormats = KEYS.map(function (k, i) { mockFormats = KEYS.map(function (k, i) {
function MockFormat() { return mockFormatInstances[i]; } function MockFormat() {
return mockFormatInstances[i];
}
MockFormat.key = k; MockFormat.key = k;
return MockFormat; return MockFormat;
}); });

View File

@@ -380,7 +380,7 @@ define([
{ {
"key": "mctTree", "key": "mctTree",
"implementation": MCTTree, "implementation": MCTTree,
"depends": [ '$parse', 'gestureService' ] "depends": ['$parse', 'gestureService']
} }
], ],
"constants": [ "constants": [

View File

@@ -145,3 +145,8 @@
.flex-justify-end { .flex-justify-end {
@include justify-content(flex-end); @include justify-content(flex-end);
} }
/********************************************* POPUPS */
.t-popup {
z-index: 75;
}

View File

@@ -48,7 +48,7 @@ $uePaneMiniTabW: 10px;
$uePaneMiniTabCollapsedW: 11px; $uePaneMiniTabCollapsedW: 11px;
$ueEditLeftPaneW: 75%; $ueEditLeftPaneW: 75%;
$treeSearchInputBarH: 25px; $treeSearchInputBarH: 25px;
$ueTimeControlH: (33px, 20px, 20px); $ueTimeControlH: (33px, 18px, 20px);
// Panes // Panes
$ueBrowseLeftPaneTreeMinW: 150px; $ueBrowseLeftPaneTreeMinW: 150px;
$ueBrowseLeftPaneTreeMaxW: 35%; $ueBrowseLeftPaneTreeMaxW: 35%;

View File

@@ -63,9 +63,10 @@ input, textarea {
font-family: Helvetica, Arial, sans-serif; font-family: Helvetica, Arial, sans-serif;
} }
input[type="text"] { input[type="text"],
input[type="search"] {
vertical-align: baseline; vertical-align: baseline;
padding: 3px 5px !important; padding: 3px 5px;
} }
h1, h2, h3 { h1, h2, h3 {

View File

@@ -139,6 +139,17 @@
background-size: $d $d; background-size: $d $d;
} }
@mixin bgStripes($c: yellow, $a: 0.1, $bgsize: 5px, $angle: 90deg) {
@include background-image(linear-gradient($angle,
rgba($c, $a) 25%, transparent 25%,
transparent 50%, rgba($c, $a) 50%,
rgba($c, $a) 75%, transparent 75%,
transparent 100%
));
background-repeat: repeat;
background-size: $bgsize $bgsize;
}
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) { @mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
@include background-image(linear-gradient(-90deg, @include background-image(linear-gradient(-90deg,
rgba($c, $a) 0%, rgba($c, $a) 50%, rgba($c, $a) 0%, rgba($c, $a) 50%,
@@ -322,13 +333,13 @@
color: $fg; color: $fg;
outline: none; outline: none;
&.error { &.error {
background: rgba(red, 0.5); background-color: $colorFormFieldErrorBg;
color: $colorFormFieldErrorFg;
} }
} }
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg) { @mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg) {
@include input-base($bg, $fg); @include input-base($bg, $fg);
padding: 0 $interiorMarginSm;
} }
@mixin contextArrow() { @mixin contextArrow() {

View File

@@ -29,7 +29,7 @@
.accordion-head { .accordion-head {
$op: 0.2; $op: 0.2;
border-radius: $basicCr * 0.75; border-radius: $basicCr * 0.75;
box-sizing: "border-box"; box-sizing: border-box;
background: rgba($colorBodyFg, $op); background: rgba($colorBodyFg, $op);
cursor: pointer; cursor: pointer;
font-size: 0.75em; font-size: 0.75em;
@@ -396,11 +396,11 @@ input[type="search"] {
left: auto; left: auto;
} }
.knob-l { .knob-l {
@include border-left-radius($sliderKnobW); @include border-left-radius($sliderKnobR);
cursor: w-resize; cursor: w-resize;
} }
.knob-r { .knob-r {
@include border-right-radius($sliderKnobW); @include border-right-radius($sliderKnobR);
cursor: e-resize; cursor: e-resize;
} }
.range { .range {
@@ -426,7 +426,6 @@ input[type="search"] {
@include user-select(none); @include user-select(none);
font-size: 0.8rem; font-size: 0.8rem;
padding: $interiorMarginLg !important; padding: $interiorMarginLg !important;
width: 230px;
.l-month-year-pager { .l-month-year-pager {
$pagerW: 20px; $pagerW: 20px;
height: $r1H; height: $r1H;
@@ -518,6 +517,19 @@ input[type="search"] {
} }
} }
@include phone {
.l-datetime-picker {
padding: $interiorMargin !important;
}
.l-calendar {
ul.l-cal-row {
li {
padding: 2px $interiorMargin;
}
}
}
}
/******************************************************** TEXTAREA */ /******************************************************** TEXTAREA */
textarea { textarea {
@include nice-textarea($colorInputBg, $colorInputFg); @include nice-textarea($colorInputBg, $colorInputFg);

View File

@@ -10,25 +10,24 @@
$knobHOffset: 0px; $knobHOffset: 0px;
$knobM: ($sliderKnobW + $knobHOffset) * -1; $knobM: ($sliderKnobW + $knobHOffset) * -1;
$rangeValPad: $interiorMargin; $rangeValPad: $interiorMargin;
$rangeValOffset: $sliderKnobW; $rangeValOffset: $sliderKnobW + $interiorMargin;
$timeRangeSliderLROffset: 130px + $sliderKnobW + $rangeValOffset; $timeRangeSliderLROffset: 150px + ($sliderKnobW * 2);
$r1H: nth($ueTimeControlH,1); $r1H: nth($ueTimeControlH,1); // Not currently used
$r2H: nth($ueTimeControlH,2); $r2H: nth($ueTimeControlH,2);
$r3H: nth($ueTimeControlH,3); $r3H: nth($ueTimeControlH,3);
display: block;
height: $r1H + $r2H + $r3H + ($interiorMargin * 2);
min-width: $minW; min-width: $minW;
font-size: 0.8rem; font-size: 0.8rem;
.l-time-range-inputs-holder, .l-time-range-inputs-holder,
.l-time-range-slider-holder, .l-time-range-slider-holder,
.l-time-range-ticks-holder .l-time-range-ticks-holder
{ {
@include absPosDefault(0, visible);
box-sizing: border-box; box-sizing: border-box;
top: auto; position: relative;
&:not(:first-child) {
margin-top: $interiorMargin;
}
} }
.l-time-range-slider, .l-time-range-slider,
.l-time-range-ticks { .l-time-range-ticks {
@@ -37,14 +36,21 @@
} }
.l-time-range-inputs-holder { .l-time-range-inputs-holder {
height: $r1H; bottom: $r2H + $r3H + ($interiorMarginSm * 2);
padding-top: $interiorMargin;
border-top: 1px solid $colorInteriorBorder; border-top: 1px solid $colorInteriorBorder;
padding-top: $interiorMargin;
&.l-flex-row,
.l-flex-row {
@include align-items(center);
.flex-elem {
height: auto;
line-height: normal;
}
}
.type-icon { .type-icon {
font-size: 120%; font-size: 120%;
vertical-align: middle; vertical-align: middle;
} }
.l-time-range-input, .l-time-range-input-w,
.l-time-range-inputs-elem { .l-time-range-inputs-elem {
margin-right: $interiorMargin; margin-right: $interiorMargin;
.lbl { .lbl {
@@ -52,13 +58,27 @@
} }
.ui-symbol.icon { .ui-symbol.icon {
font-size: 11px; font-size: 11px;
width: 11px;
} }
} }
.l-time-range-input-w {
// Wraps a datetime text input field
position: relative;
input[type="text"] {
width: 200px;
&.picker-icon {
padding-right: 20px;
}
}
.icon-calendar {
position: absolute;
right: 5px;
top: 5px;
}
}
} }
.l-time-range-slider-holder { .l-time-range-slider-holder {
height: $r2H; bottom: $r3H + ($interiorMarginSm * 1); height: $r2H;
.range-holder { .range-holder {
box-shadow: none; box-shadow: none;
background: none; background: none;
@@ -73,24 +93,13 @@
width: $myW; width: $myW;
height: auto; height: auto;
z-index: 2; z-index: 2;
&:before,
&:after {
background-color: $myC;
content: "";
position: absolute;
}
&:before { &:before {
// Vert line // Vert line
background-color: $myC;
position: absolute;
content: "";
top: 0; right: auto; bottom: -10px; left: floor($myW/2) - 1; top: 0; right: auto; bottom: -10px; left: floor($myW/2) - 1;
width: 2px; width: 1px;
}
&:after {
// Circle element
border-radius: $myW;
@include transform(translateY(-50%));
top: 50%; right: 0; bottom: auto; left: 0;
width: auto;
height: $myW;
} }
} }
&:hover .toi-line { &:hover .toi-line {
@@ -126,9 +135,9 @@
@include webkitProp(transform, translateX(-50%)); @include webkitProp(transform, translateX(-50%));
color: $colorPlotLabelFg; color: $colorPlotLabelFg;
display: inline-block; display: inline-block;
font-size: 0.9em; font-size: 0.7rem;
position: absolute; position: absolute;
top: 8px; top: 5px;
white-space: nowrap; white-space: nowrap;
z-index: 2; z-index: 2;
} }
@@ -138,16 +147,29 @@
.knob { .knob {
z-index: 2; z-index: 2;
&:before {
$mTB: 2px;
$grippyW: 3px;
$mLR: ($sliderKnobW - $grippyW)/2;
@include bgStripes($c: pullForward($sliderColorKnob, 20%), $a: 1, $bgsize: 4px, $angle: 0deg);
content: '';
display: block;
position: absolute;
top: $mTB; right: $mLR; bottom: $mTB; left: $mLR;
}
.range-value { .range-value {
@include trans-prop-nice-fade(.25s); @include trans-prop-nice-fade(.25s);
padding: 0 $rangeValOffset; font-size: 0.7rem;
position: absolute; position: absolute;
height: $r2H; height: $r2H;
line-height: $r2H; line-height: $r2H;
white-space: nowrap; white-space: nowrap;
z-index: 1;
} }
&:hover .range-value { &:hover {
color: $sliderColorKnobHov; .range-value {
color: $sliderColorKnobHov;
}
} }
&.knob-l { &.knob-l {
margin-left: $knobM; margin-left: $knobM;
@@ -170,7 +192,7 @@
.l-time-domain-selector { .l-time-domain-selector {
position: absolute; position: absolute;
right: 0px; right: 0px;
bottom: 46px; top: $interiorMargin;
} }
} }
@@ -181,174 +203,64 @@
padding: 1px 1px 0 $interiorMargin; padding: 1px 1px 0 $interiorMargin;
} }
/******************************************************************** MOBILE */
@include phoneandtablet { @include phoneandtablet {
.l-time-controller, .l-time-range-inputs-holder { .l-time-controller {
min-width: 0px; min-width: 0;
} .l-time-range-slider-holder,
.l-time-range-ticks-holder {
.l-time-controller { display: none;
}
.l-time-domain-selector { }
select {
height: 25px;
margin-bottom: 0px;
}
}
.l-time-range-slider-holder, .l-time-range-ticks-holder {
display: none;
}
.time-range-start, .time-range-end, {
width: 100%;
}
.l-time-range-inputs-holder {
.l-time-range-input {
display: block;
.s-btn {
padding-right: 18px;
white-space: nowrap;
input {
width: 100%;
}
}
}
.l-time-range-inputs-elem {
}
}
}
} }
@include phone { @include phone {
.l-time-controller { .l-time-controller {
height: 48px; .l-time-range-inputs-holder {
&.l-flex-row,
.l-time-range-inputs-holder { .l-flex-row {
bottom: 24px; @include align-items(flex-start);
} }
.l-time-range-inputs-elem {
.l-time-domain-selector { &.type-icon {
width: 33%; margin-top: 3px;
bottom: -9px; }
} }
.t-inputs-w {
.l-time-range-inputs-holder { @include flex-direction(column);
.l-time-range-input { .l-time-range-input-w:not(:first-child) {
margin-bottom: 5px; &:not(:first-child) {
.s-btn { margin-top: $interiorMargin;
width: 66%; }
} margin-right: 0;
} }
.l-time-range-inputs-elem { .l-time-range-inputs-elem {
&.ui-symbol { &.lbl { display: none; }
display: none; }
} }
}
&.lbl { }
width: 33%;
right: 0px;
top: 5px;
display: block;
height: 25px;
margin: 0;
line-height: 25px;
position: absolute;
}
}
}
}
} }
@include phonePortrait {
@include tablet { .l-time-controller {
.l-time-controller { .l-time-range-inputs-holder {
height: 17px; .t-inputs-w {
@include flex(1 1 auto);
.l-time-range-inputs-holder { padding-top: 25px; // Make room for the ever lovin' Time Domain Selector
bottom: -7px; .flex-elem {
left: -5px; @include flex(1 1 auto);
} width: 100%;
}
.l-time-domain-selector { input[type="text"] {
width: 23%; width: 100%;
right: -4px; }
bottom: -10px; }
} }
}
.l-time-range-inputs-holder { .l-time-domain-selector {
.l-time-range-input { right: auto;
float: left; left: 20px;
.s-btn { }
width: 100%;
padding-left: 4px;
}
}
}
}
}
@include tabletLandscape {
.l-time-controller {
height: 17px;
.l-time-range-inputs-holder {
bottom: -7px;
}
.l-time-domain-selector {
width: 23%;
right: auto;
bottom: -10px;
left: 391px;
}
.l-time-range-inputs-holder {
.l-time-range-inputs-elem {
&.ui-symbol, &.lbl {
display: block;
float: left;
line-height: 25px;
}
}
}
}
.pane-tree-hidden .l-time-controller {
.l-time-domain-selector {
left: 667px;
}
.l-time-range-inputs-holder {
padding-left: 277px;
}
}
}
@include tabletPortrait {
.l-time-controller {
height: 17px;
.l-time-range-inputs-holder {
bottom: -7px;
left: -5px;
}
.l-time-domain-selector {
width: 23%;
right: -4px;
bottom: -10px;
}
.l-time-range-inputs-holder {
.l-time-range-input {
width: 38%;
float: left;
}
.l-time-range-inputs-elem {
&.ui-symbol, &.lbl {
display: none;
}
}
}
}
} }

View File

@@ -194,7 +194,7 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
.holder.holder-treeview-elements { .holder.holder-treeview-elements {
top: $bodyMargin; top: $bodyMargin;
right: 0; right: 0;
bottom: $bodyMargin; bottom: $interiorMargin;
left: $bodyMargin; left: $bodyMargin;
.create-btn-holder { .create-btn-holder {
&.s-status-editing { &.s-status-editing {
@@ -215,17 +215,17 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
left: 0; left: 0;
.holder-object { .holder-object {
top: $bodyMargin; top: $bodyMargin;
bottom: $bodyMargin; bottom: $interiorMargin;
} }
.holder-inspector { .holder-inspector {
top: $bodyMargin; top: $bodyMargin;
bottom: $bodyMargin; bottom: $interiorMargin;
left: $bodyMargin; left: $bodyMargin;
right: $bodyMargin; right: $bodyMargin;
} }
.holder-elements { .holder-elements {
top: 0; top: 0;
bottom: $bodyMargin; bottom: $interiorMargin;
left: $bodyMargin; left: $bodyMargin;
right: $bodyMargin; right: $bodyMargin;
} }

View File

@@ -19,18 +19,17 @@
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 class="s-btn" <span ng-controller="DateTimeFieldController">
ng-controller="DateTimeFieldController">
<input type="text" <input type="text"
ng-model="textValue" ng-model="textValue"
ng-blur="restoreTextValue(); ngBlur()" ng-blur="restoreTextValue(); ngBlur()"
ng-class="{ ng-class="{
error: textInvalid || error: textInvalid ||
(structure.validate && (structure.validate &&
!structure.validate(ngModel[field])) !structure.validate(ngModel[field])),
'picker-icon': structure.format === 'utc' || !structure.format
}"> }">
</input> </input><a class="ui-symbol icon icon-calendar"
<a class="ui-symbol icon icon-calendar"
ng-if="structure.format === 'utc' || !structure.format" ng-if="structure.format === 'utc' || !structure.format"
ng-click="picker.active = !picker.active"> ng-click="picker.active = !picker.active">
</a> </a>
@@ -38,8 +37,7 @@
<div mct-click-elsewhere="picker.active = false"> <div mct-click-elsewhere="picker.active = false">
<mct-control key="'datetime-picker'" <mct-control key="'datetime-picker'"
ng-model="pickerModel" ng-model="pickerModel"
field="'value'" field="'value'">
options="{ hours: true }">
</mct-control> </mct-control>
</div> </div>
</mct-popup> </mct-popup>

View File

@@ -19,42 +19,43 @@
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.
--> -->
<div ng-controller="TimeRangeController as trCtrl"> <div ng-controller="TimeRangeController as trCtrl" class="l-flex-col">
<form class="l-time-range-inputs-holder" <form class="l-time-range-inputs-holder l-flex-row flex-elem"
ng-submit="trCtrl.updateBoundsFromForm()"> ng-submit="trCtrl.updateBoundsFromForm()">
<span class="l-time-range-inputs-elem ui-symbol type-icon">&#x43;</span> <span class="l-time-range-inputs-elem ui-symbol type-icon flex-elem">&#x43;</span>
<span class="l-time-range-input"> <span class="l-time-range-inputs-elem t-inputs-w l-flex-row flex-elem">
<mct-control key="'datetime-field'" <span class="l-time-range-input-w flex-elem">
structure="{ <mct-control key="'datetime-field'"
format: parameters.format, structure="{
validate: trCtrl.validateStart format: parameters.format,
}" validate: trCtrl.validateStart
ng-model="formModel" }"
ng-blur="trCtrl.updateBoundsFromForm()" ng-model="formModel"
field="'start'" ng-blur="trCtrl.updateBoundsFromForm()"
class="time-range-start"> field="'start'"
</mct-control> class="time-range-start">
</mct-control>
</span>
<span class="l-time-range-inputs-elem lbl flex-elem">to</span>
<span class="l-time-range-input-w flex-elem" ng-controller="ToggleController as t2">
<mct-control key="'datetime-field'"
structure="{
format: parameters.format,
validate: trCtrl.validateEnd
}"
ng-model="formModel"
ng-blur="trCtrl.updateBoundsFromForm()"
field="'end'"
class="time-range-end">
</mct-control>
</span>
</span> </span>
<span class="l-time-range-inputs-elem lbl">to</span>
<span class="l-time-range-input" ng-controller="ToggleController as t2">
<mct-control key="'datetime-field'"
structure="{
format: parameters.format,
validate: trCtrl.validateEnd
}"
ng-model="formModel"
ng-blur="trCtrl.updateBoundsFromForm()"
field="'end'"
class="time-range-end">
</mct-control>&nbsp;
</span>
<input type="submit" class="hidden"> <input type="submit" class="hidden">
</form> </form>
<div class="l-time-range-slider-holder"> <div class="l-time-range-slider-holder flex-elem">
<div class="l-time-range-slider"> <div class="l-time-range-slider">
<div class="slider" <div class="slider"
mct-resize="spanWidth = bounds.width"> mct-resize="spanWidth = bounds.width">
@@ -85,7 +86,7 @@
</div> </div>
</div> </div>
<div class="l-time-range-ticks-holder"> <div class="l-time-range-ticks-holder flex-elem">
<div class="l-time-range-ticks"> <div class="l-time-range-ticks">
<div <div
ng-repeat="tick in ticks track by $index" ng-repeat="tick in ticks track by $index"

View File

@@ -40,7 +40,7 @@ define(
function BannerController($scope, notificationService, dialogService) { function BannerController($scope, notificationService, dialogService) {
$scope.active = notificationService.active; $scope.active = notificationService.active;
$scope.action = function (action, $event){ $scope.action = function (action, $event) {
/* /*
Prevents default 'maximize' behaviour when clicking on Prevents default 'maximize' behaviour when clicking on
notification button notification button
@@ -48,19 +48,19 @@ define(
$event.stopPropagation(); $event.stopPropagation();
return action(); return action();
}; };
$scope.dismiss = function(notification, $event) { $scope.dismiss = function (notification, $event) {
$event.stopPropagation(); $event.stopPropagation();
notification.dismissOrMinimize(); notification.dismissOrMinimize();
}; };
$scope.maximize = function(notification) { $scope.maximize = function (notification) {
if (notification.model.severity !== "info"){ if (notification.model.severity !== "info") {
notification.model.cancel = function(){ notification.model.cancel = function () {
dialogService.dismiss(); dialogService.dismiss();
}; };
//If the notification is dismissed by the user, close //If the notification is dismissed by the user, close
// the dialog. // the dialog.
notification.onDismiss(function(){ notification.onDismiss(function () {
dialogService.dismiss(); dialogService.dismiss();
}); });

View File

@@ -65,7 +65,7 @@ define(
* Get the current state of the toggle. * Get the current state of the toggle.
* @return {boolean} true if active * @return {boolean} true if active
*/ */
ClickAwayController.prototype.isActive =function () { ClickAwayController.prototype.isActive = function () {
return this.state; return this.state;
}; };

View File

@@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
define( define(
[ 'moment' ], ['moment'],
function (moment) { function (moment) {
var TIME_NAMES = { var TIME_NAMES = {

View File

@@ -69,7 +69,9 @@ define(
function updateList(ids) { function updateList(ids) {
function updateSelectedObjects(objects) { function updateSelectedObjects(objects) {
// Look up from the // Look up from the
function getObject(id) { return objects[id]; } function getObject(id) {
return objects[id];
}
self.selectedObjects = self.selectedObjects =
ids.filter(getObject).map(getObject); ids.filter(getObject).map(getObject);
} }

View File

@@ -76,7 +76,7 @@ define(
// based on a new mouse event object. // based on a new mouse event object.
function updatePosition(event) { function updatePosition(event) {
// Get the current position, as an array // Get the current position, as an array
var currentPosition = [ event.pageX, event.pageY ]; var currentPosition = [event.pageX, event.pageY];
// Track the initial position, if one hasn't been observed // Track the initial position, if one hasn't been observed
initialPosition = initialPosition || currentPosition; initialPosition = initialPosition || currentPosition;

View File

@@ -46,13 +46,10 @@ define(
function link(scope, element, attrs, ctrl, transclude) { function link(scope, element, attrs, ctrl, transclude) {
var div = $compile(TEMPLATE)(scope), var div = $compile(TEMPLATE)(scope),
rect = element.parent()[0].getBoundingClientRect(), rect = element.parent()[0].getBoundingClientRect(),
position = [ rect.left, rect.top ], position = [rect.left, rect.top],
popup = popupService.display(div, position); popup = popupService.display(div, position);
// TODO: Handle in CSS; div.addClass('t-popup');
// https://github.com/nasa/openmctweb/issues/298
div.css('z-index', 75);
transclude(function (clone) { transclude(function (clone) {
div.append(clone); div.append(clone);
}); });

View File

@@ -59,7 +59,7 @@ define(
}, },
// Grab the event when the user is done moving // Grab the event when the user is done moving
// the splitter and pass it on // the splitter and pass it on
endMove: function() { endMove: function () {
mctSplitPane.toggleClass('resizing'); mctSplitPane.toggleClass('resizing');
} }
}; };

Some files were not shown because too many files have changed in this diff Show More