mirror of
https://github.com/nasa/openmct.git
synced 2024-12-22 06:27:48 +00:00
Merge branch 'master' into jscs-rebase-142
Conflicts: platform/commonUI/edit/test/actions/EditAndComposeActionSpec.js platform/representation/src/MCTRepresentation.js
This commit is contained in:
commit
bce5643994
@ -22,17 +22,19 @@
|
||||
#* 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"
|
||||
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.
|
||||
# Don't worry, as this entire directory will get trashed inbetween builds.
|
||||
REMOTE_NAME="documentation"
|
||||
WEBSITE_BRANCH="gh-pages"
|
||||
WEBSITE_BRANCH="master"
|
||||
|
||||
# Clean output directory, JSDOC will recreate
|
||||
if [ -d $OUTPUT_DIRECTORY ]; then
|
||||
@ -40,23 +42,21 @@ if [ -d $OUTPUT_DIRECTORY ]; then
|
||||
fi
|
||||
|
||||
npm run docs
|
||||
cd $OUTPUT_DIRECTORY || exit 1
|
||||
|
||||
echo "git init"
|
||||
git init
|
||||
echo "git clone $REPOSITORY_URL website"
|
||||
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.
|
||||
git config user.email "buildbot@circleci.com"
|
||||
git config user.name "BuildBot"
|
||||
|
||||
echo "git remote add $REMOTE_NAME $REPOSITORY_URL"
|
||||
git remote add $REMOTE_NAME $REPOSITORY_URL
|
||||
echo "git add ."
|
||||
git add .
|
||||
echo "git commit -m \"Generate docs from build $BUILD_SHA\""
|
||||
git commit -m "Generate docs from build $BUILD_SHA"
|
||||
|
||||
echo "git push $REMOTE_NAME HEAD:$WEBSITE_BRANCH -f"
|
||||
git push $REMOTE_NAME HEAD:$WEBSITE_BRANCH -f
|
||||
|
||||
echo "Documentation pushed to gh-pages branch."
|
||||
echo "git commit -m \"Docs updated from build $BUILD_SHA\""
|
||||
git commit -m "Docs updated from build $BUILD_SHA"
|
||||
# Push to the website repo
|
||||
git push
|
||||
|
12
circle.yml
12
circle.yml
@ -1,8 +1,11 @@
|
||||
deployment:
|
||||
production:
|
||||
branch: master
|
||||
heroku:
|
||||
appname: openmctweb-demo
|
||||
commands:
|
||||
- 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:
|
||||
branch: live_demo
|
||||
heroku:
|
||||
@ -14,3 +17,8 @@ deployment:
|
||||
test:
|
||||
post:
|
||||
- gulp lint
|
||||
|
||||
general:
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages
|
||||
|
@ -26,7 +26,7 @@ define([
|
||||
"./src/controllers/ElementsController",
|
||||
"./src/controllers/EditObjectController",
|
||||
"./src/directives/MCTBeforeUnload",
|
||||
"./src/actions/LinkAction",
|
||||
"./src/actions/EditAndComposeAction",
|
||||
"./src/actions/EditAction",
|
||||
"./src/actions/PropertiesAction",
|
||||
"./src/actions/RemoveAction",
|
||||
@ -55,7 +55,7 @@ define([
|
||||
ElementsController,
|
||||
EditObjectController,
|
||||
MCTBeforeUnload,
|
||||
LinkAction,
|
||||
EditAndComposeAction,
|
||||
EditAction,
|
||||
PropertiesAction,
|
||||
RemoveAction,
|
||||
@ -126,7 +126,7 @@ define([
|
||||
"actions": [
|
||||
{
|
||||
"key": "compose",
|
||||
"implementation": LinkAction
|
||||
"implementation": EditAndComposeAction
|
||||
},
|
||||
{
|
||||
"key": "edit",
|
||||
|
@ -31,13 +31,14 @@ define(
|
||||
* @memberof platform/commonUI/edit
|
||||
* @implements {Action}
|
||||
*/
|
||||
function LinkAction(context) {
|
||||
function EditAndComposeAction(context) {
|
||||
this.domainObject = (context || {}).domainObject;
|
||||
this.selectedObject = (context || {}).selectedObject;
|
||||
}
|
||||
|
||||
LinkAction.prototype.perform = function () {
|
||||
var self = this;
|
||||
EditAndComposeAction.prototype.perform = function () {
|
||||
var self = this,
|
||||
editAction = this.domainObject.getCapability('action').getActions("edit")[0];
|
||||
|
||||
// Persist changes to the domain object
|
||||
function doPersist() {
|
||||
@ -54,9 +55,13 @@ define(
|
||||
.then(doPersist);
|
||||
}
|
||||
|
||||
if (editAction) {
|
||||
editAction.perform();
|
||||
}
|
||||
|
||||
return this.selectedObject && doLink();
|
||||
};
|
||||
|
||||
return LinkAction;
|
||||
return EditAndComposeAction;
|
||||
}
|
||||
);
|
@ -81,17 +81,14 @@ define(
|
||||
var key = action.getMetadata().key,
|
||||
category = (context || {}).category;
|
||||
|
||||
// Only worry about actions in the view-control category
|
||||
if (category === 'view-control') {
|
||||
// Restrict 'edit' to cases where there are editable
|
||||
// views (similarly, restrict 'properties' to when
|
||||
// the converse is true), and where the domain object is not
|
||||
// already being edited.
|
||||
if (key === 'edit') {
|
||||
return this.countEditableViews(context) > 0 && !isEditing(context);
|
||||
} else if (key === 'properties') {
|
||||
return this.countEditableViews(context) < 1 && !isEditing(context);
|
||||
}
|
||||
// Restrict 'edit' to cases where there are editable
|
||||
// views (similarly, restrict 'properties' to when
|
||||
// the converse is true), and where the domain object is not
|
||||
// already being edited.
|
||||
if (key === 'edit') {
|
||||
return this.countEditableViews(context) > 0 && !isEditing(context);
|
||||
} else if (key === 'properties' && category === 'view-control') {
|
||||
return this.countEditableViews(context) < 1 && !isEditing(context);
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
|
@ -21,8 +21,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/actions/LinkAction"],
|
||||
function (LinkAction) {
|
||||
["../../src/actions/EditAndComposeAction"],
|
||||
function (EditAndComposeAction) {
|
||||
|
||||
describe("The Link action", function () {
|
||||
var mockQ,
|
||||
@ -31,6 +31,8 @@ define(
|
||||
mockContext,
|
||||
mockComposition,
|
||||
mockPersistence,
|
||||
mockActionCapability,
|
||||
mockEditAction,
|
||||
mockType,
|
||||
actionContext,
|
||||
model,
|
||||
@ -64,21 +66,26 @@ define(
|
||||
return capabilities[k].invoke(v);
|
||||
}
|
||||
};
|
||||
mockContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockComposition = jasmine.createSpyObj("composition", ["invoke", "add"]);
|
||||
mockPersistence = jasmine.createSpyObj("persistence", ["persist"]);
|
||||
mockType = jasmine.createSpyObj("type", ["hasFeature"]);
|
||||
mockContext = jasmine.createSpyObj("context", [ "getParent" ]);
|
||||
mockComposition = jasmine.createSpyObj("composition", [ "invoke", "add" ]);
|
||||
mockPersistence = jasmine.createSpyObj("persistence", [ "persist" ]);
|
||||
mockType = jasmine.createSpyObj("type", [ "hasFeature", "getKey" ]);
|
||||
mockActionCapability = jasmine.createSpyObj("actionCapability", [ "getActions"]);
|
||||
mockEditAction = jasmine.createSpyObj("editAction", ["perform"]);
|
||||
|
||||
mockDomainObject.getId.andReturn("test");
|
||||
mockDomainObject.getCapability.andReturn(mockContext);
|
||||
mockContext.getParent.andReturn(mockParent);
|
||||
mockType.hasFeature.andReturn(true);
|
||||
mockType.getKey.andReturn("layout");
|
||||
mockComposition.invoke.andReturn(mockPromise(true));
|
||||
mockComposition.add.andReturn(mockPromise(true));
|
||||
mockActionCapability.getActions.andReturn([]);
|
||||
|
||||
capabilities = {
|
||||
composition: mockComposition,
|
||||
persistence: mockPersistence,
|
||||
action: mockActionCapability,
|
||||
type: mockType
|
||||
};
|
||||
model = {
|
||||
@ -90,7 +97,7 @@ define(
|
||||
selectedObject: mockDomainObject
|
||||
};
|
||||
|
||||
action = new LinkAction(actionContext);
|
||||
action = new EditAndComposeAction(actionContext);
|
||||
});
|
||||
|
||||
|
||||
@ -105,6 +112,21 @@ define(
|
||||
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);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -32,7 +32,8 @@ define(
|
||||
*/
|
||||
function InspectorController($scope, policyService) {
|
||||
var domainObject = $scope.domainObject,
|
||||
typeCapability = domainObject.getCapability('type');
|
||||
typeCapability = domainObject.getCapability('type'),
|
||||
statusListener;
|
||||
|
||||
/**
|
||||
* Filters region parts to only those allowed by region policies
|
||||
@ -50,6 +51,11 @@ define(
|
||||
$scope.regions = filterRegions(typeCapability.getDefinition().inspector || new InspectorRegion());
|
||||
}
|
||||
|
||||
statusListener = domainObject.getCapability("status").listen(setRegions);
|
||||
$scope.$on("$destroy", function () {
|
||||
statusListener();
|
||||
});
|
||||
|
||||
setRegions();
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,8 @@ define(
|
||||
mockTypeCapability,
|
||||
mockTypeDefinition,
|
||||
mockPolicyService,
|
||||
mockStatusCapability,
|
||||
capabilities = {},
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
@ -47,19 +49,29 @@ define(
|
||||
'getDefinition'
|
||||
]);
|
||||
mockTypeCapability.getDefinition.andReturn(mockTypeDefinition);
|
||||
capabilities.type = mockTypeCapability;
|
||||
|
||||
mockStatusCapability = jasmine.createSpyObj('statusCapability', [
|
||||
'listen'
|
||||
]);
|
||||
capabilities.status = mockStatusCapability;
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj('domainObject', [
|
||||
'getCapability'
|
||||
]);
|
||||
mockDomainObject.getCapability.andReturn(mockTypeCapability);
|
||||
mockDomainObject.getCapability.andCallFake(function (name) {
|
||||
return capabilities[name];
|
||||
});
|
||||
|
||||
mockPolicyService = jasmine.createSpyObj('policyService', [
|
||||
'allow'
|
||||
]);
|
||||
|
||||
mockScope = {
|
||||
domainObject: mockDomainObject
|
||||
};
|
||||
mockScope = jasmine.createSpyObj('$scope',
|
||||
['$on']
|
||||
);
|
||||
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
});
|
||||
|
||||
it("filters out regions disallowed by region policy", function () {
|
||||
@ -73,6 +85,25 @@ define(
|
||||
controller = new InspectorController(mockScope, mockPolicyService);
|
||||
expect(mockScope.regions.length).toBe(2);
|
||||
});
|
||||
|
||||
it("Responds to status changes", function() {
|
||||
mockPolicyService.allow.andReturn(true);
|
||||
controller = new InspectorController(mockScope, mockPolicyService);
|
||||
expect(mockScope.regions.length).toBe(2);
|
||||
expect(mockStatusCapability.listen).toHaveBeenCalled();
|
||||
mockPolicyService.allow.andReturn(false);
|
||||
mockStatusCapability.listen.mostRecentCall.args[0]();
|
||||
expect(mockScope.regions.length).toBe(0);
|
||||
});
|
||||
|
||||
it("Unregisters status listener", function() {
|
||||
var mockListener = jasmine.createSpy('listener');
|
||||
mockStatusCapability.listen.andReturn(mockListener);
|
||||
controller = new InspectorController(mockScope, mockPolicyService);
|
||||
expect(mockScope.$on).toHaveBeenCalledWith("$destroy", jasmine.any(Function));
|
||||
mockScope.$on.mostRecentCall.args[1]();
|
||||
expect(mockListener).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -88,7 +88,6 @@ define(
|
||||
toClear = [], // Properties to clear out of scope on change
|
||||
counter = 0,
|
||||
couldRepresent = false,
|
||||
couldEdit = false,
|
||||
lastIdPath = [],
|
||||
lastKey,
|
||||
statusListener,
|
||||
@ -137,14 +136,13 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
function unchanged(canRepresent, canEdit, idPath, key) {
|
||||
function unchanged(canRepresent, idPath, key) {
|
||||
return (canRepresent === couldRepresent) &&
|
||||
(key === lastKey) &&
|
||||
(idPath.length === lastIdPath.length) &&
|
||||
idPath.every(function (id, i) {
|
||||
return id === lastIdPath[i];
|
||||
}) &&
|
||||
(canEdit === couldEdit);
|
||||
});
|
||||
}
|
||||
|
||||
function getIdPath(domainObject) {
|
||||
@ -168,11 +166,10 @@ define(
|
||||
representation = lookup($scope.key, domainObject),
|
||||
uses = ((representation || {}).uses || []),
|
||||
canRepresent = !!(representation && domainObject),
|
||||
canEdit = !!(domainObject && domainObject.hasCapability('editor') && domainObject.getCapability('editor').inEditContext()),
|
||||
idPath = getIdPath(domainObject),
|
||||
key = $scope.key;
|
||||
|
||||
if (unchanged(canRepresent, canEdit, idPath, key)) {
|
||||
if (unchanged(canRepresent, idPath, key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -201,7 +198,6 @@ define(
|
||||
// To allow simplified change detection next time around
|
||||
couldRepresent = canRepresent;
|
||||
lastIdPath = idPath;
|
||||
couldEdit = canEdit;
|
||||
lastKey = key;
|
||||
|
||||
// Populate scope with fields associated with the current
|
||||
@ -239,26 +235,7 @@ define(
|
||||
// Also update when the represented domain object changes
|
||||
// (to a different object)
|
||||
$scope.$watch("domainObject", refresh);
|
||||
|
||||
function listenForStatusChange(object) {
|
||||
if (statusListener) {
|
||||
statusListener();
|
||||
}
|
||||
statusListener = object.getCapability("status").listen(refresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener to the object for status changes.
|
||||
*/
|
||||
$scope.$watch("domainObject", function (domainObject, oldDomainObject) {
|
||||
if (domainObject !== oldDomainObject) {
|
||||
listenForStatusChange(domainObject);
|
||||
}
|
||||
});
|
||||
if ($scope.domainObject) {
|
||||
listenForStatusChange($scope.domainObject);
|
||||
}
|
||||
|
||||
|
||||
// Finally, also update when there is a new version of that
|
||||
// same domain object; these changes should be tracked in the
|
||||
// model's "modified" field, by the mutation capability.
|
||||
|
@ -54,9 +54,6 @@ define(
|
||||
// ...and broadcast the event. This allows specific
|
||||
// views to have post-drop behavior which depends on
|
||||
// drop position.
|
||||
// Also broadcast the editableDomainObject to
|
||||
// avoid race condition against non-editable
|
||||
// version in EditRepresenter
|
||||
scope.$broadcast(
|
||||
GestureConstants.MCT_DROP_EVENT,
|
||||
id,
|
||||
@ -93,21 +90,13 @@ define(
|
||||
|
||||
function drop(e) {
|
||||
var event = (e || {}).originalEvent || e,
|
||||
id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE),
|
||||
domainObjectType = domainObject.getModel().type;
|
||||
id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE);
|
||||
|
||||
// Handle the drop; add the dropped identifier to the
|
||||
// destination domain object's composition, and persist
|
||||
// the change.
|
||||
if (id) {
|
||||
e.preventDefault();
|
||||
|
||||
//Use scope.apply, drop event is outside digest cycle
|
||||
scope.$apply(function () {
|
||||
if (domainObjectType !== 'folder') {
|
||||
domainObject.getCapability('action').perform('edit');
|
||||
}
|
||||
});
|
||||
$q.when(action && action.perform()).then(function () {
|
||||
broadcastDrop(id, event);
|
||||
});
|
||||
|
@ -253,21 +253,6 @@ define(
|
||||
expect(mockScope.testCapability).toBeUndefined();
|
||||
});
|
||||
|
||||
it("registers a status change listener", function () {
|
||||
mockScope.$watch.calls[2].args[1](mockDomainObject);
|
||||
expect(mockStatusCapability.listen).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("unlistens for status change on scope destruction", function () {
|
||||
var mockUnlistener = jasmine.createSpy("unlisten");
|
||||
mockStatusCapability.listen.andReturn(mockUnlistener);
|
||||
mockScope.$watch.calls[2].args[1](mockDomainObject);
|
||||
expect(mockStatusCapability.listen).toHaveBeenCalled();
|
||||
|
||||
mockScope.$on.calls[1].args[1]();
|
||||
expect(mockUnlistener).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("when a domain object has been observed", function () {
|
||||
var mockContext,
|
||||
mockContext2,
|
||||
|
Loading…
Reference in New Issue
Block a user