Elements pool and drag drop (#2196)

* Implemented drag-and-drop composition

* Added composition policy for tables

* Reimplemented elements pool in Vue

* No need to resolve all objects on the navigated path

* Only show elements pool in edit mode

* Remove old elements pool

* Updated legacy code to use composition policy API

* Keep object in sync when mutated
This commit is contained in:
Andrew Henry
2018-10-23 10:52:37 -07:00
committed by Pete Richards
parent a296bc2b81
commit cbcfd44016
35 changed files with 334 additions and 1084 deletions

View File

@@ -23,7 +23,6 @@
define([
"./src/controllers/EditActionController",
"./src/controllers/EditPanesController",
"./src/controllers/ElementsController",
"./src/controllers/EditObjectController",
"./src/actions/EditAndComposeAction",
"./src/actions/EditAction",
@@ -47,7 +46,6 @@ define([
"./src/creation/LocatorController",
"./src/creation/CreationPolicy",
"./src/creation/CreateActionProvider",
"./src/creation/AddActionProvider",
"./src/creation/CreationService",
"./res/templates/create/locator.html",
"./res/templates/create/create-button.html",
@@ -55,13 +53,11 @@ define([
"./res/templates/library.html",
"./res/templates/edit-object.html",
"./res/templates/edit-action-buttons.html",
"./res/templates/elements.html",
"./res/templates/topbar-edit.html",
'legacyRegistry'
], function (
EditActionController,
EditPanesController,
ElementsController,
EditObjectController,
EditAndComposeAction,
EditAction,
@@ -85,7 +81,6 @@ define([
LocatorController,
CreationPolicy,
CreateActionProvider,
AddActionProvider,
CreationService,
locatorTemplate,
createButtonTemplate,
@@ -93,7 +88,6 @@ define([
libraryTemplate,
editObjectTemplate,
editActionButtonsTemplate,
elementsTemplate,
topbarEditTemplate,
legacyRegistry
) {
@@ -115,14 +109,6 @@ define([
"$scope"
]
},
{
"key": "ElementsController",
"implementation": ElementsController,
"depends": [
"$scope",
"openmct"
]
},
{
"key": "EditObjectController",
"implementation": EditObjectController,
@@ -225,10 +211,10 @@ define([
"description": "Save changes made to these objects.",
"depends": [
"$injector",
"policyService",
"dialogService",
"copyService",
"notificationService"
"notificationService",
"openmct"
],
"priority": "mandatory"
},
@@ -296,13 +282,6 @@ define([
"action"
]
},
{
"key": "edit-elements",
"template": elementsTemplate,
"gestures": [
"drop"
]
},
{
"key": "topbar-edit",
"template": topbarEditTemplate
@@ -319,12 +298,6 @@ define([
]
}
],
"templates": [
{
key: "elementsPool",
template: elementsTemplate
}
],
"components": [
{
"type": "decorator",
@@ -356,18 +329,6 @@ define([
"policyService"
]
},
{
"key": "AddActionProvider",
"provides": "actionService",
"type": "provider",
"implementation": AddActionProvider,
"depends": [
"$q",
"typeService",
"dialogService",
"policyService"
]
},
{
"key": "CreationService",
"provides": "creationService",

View File

@@ -1,49 +0,0 @@
<!--
Open MCT, Copyright (c) 2014-2018, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT 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 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.
-->
<div ng-controller="ElementsController" class="flex-elem l-flex-col holder grows">
<mct-include key="'input-filter'"
class="flex-elem holder"
ng-model="filterBy">
</mct-include>
<div class="flex-elem grows vscroll scroll-pad">
<ul class="tree" id="inspector-elements-tree"
ng-if="composition.length > 0">
<li ng-repeat="containedObject in composition | filter:searchElements">
<span class="tree-item">
<span class="grippy-sm"
ng-if="composition.length > 1"
data-id="{{ containedObject.id }}"
mct-drag-down="dragDown($event)"
mct-drag="drag($event)"
mct-drag-up="dragUp($event)">
</span>
<mct-representation
class="rep-object-label"
key="'label'"
mct-object="containedObject">
</mct-representation>
</span>
</li>
</ul>
<div ng-if="composition.length === 0">No contained elements</div>
</div>
</div>

View File

@@ -40,20 +40,20 @@ function (
*/
function SaveAsAction(
$injector,
policyService,
dialogService,
copyService,
notificationService,
openmct,
context
) {
this.domainObject = (context || {}).domainObject;
this.injectObjectService = function () {
this.objectService = $injector.get("objectService");
};
this.policyService = policyService;
this.dialogService = dialogService;
this.copyService = copyService;
this.notificationService = notificationService;
this.openmct = openmct;
}
/**
@@ -63,7 +63,7 @@ function (
return new CreateWizard(
this.domainObject,
parent,
this.policyService
this.openmct
);
};

View File

@@ -51,8 +51,11 @@ define(
*/
EditorCapability.prototype.edit = function () {
console.warn('DEPRECATED: cannot edit via edit capability, use openmct.editor instead.');
this.openmct.editor.edit();
this.domainObject.getCapability('status').set('editing', true);
if (!this.openmct.editor.isEditing()) {
this.openmct.editor.edit();
this.domainObject.getCapability('status').set('editing', true);
}
};
/**

View File

@@ -1,197 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT 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 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.
*****************************************************************************/
define(
['zepto'],
function ($) {
/**
* The ElementsController prepares the elements view for display
*
* @constructor
*/
function ElementsController($scope, openmct) {
this.scope = $scope;
this.scope.composition = [];
this.openmct = openmct;
this.dragDown = this.dragDown.bind(this);
this.dragUp = this.dragUp.bind(this);
var self = this;
function filterBy(text) {
if (typeof text === 'undefined') {
return $scope.searchText;
} else {
$scope.searchText = text;
}
}
function searchElements(value) {
if ($scope.searchText) {
return value.getModel().name.toLowerCase().search(
$scope.searchText.toLowerCase()) !== -1;
} else {
return true;
}
}
function setSelection(selection) {
if (!selection[0]) {
return;
}
if (self.mutationListener) {
self.mutationListener();
delete self.mutationListener;
}
var domainObject = selection[0].context.oldItem;
self.refreshComposition(domainObject);
if (domainObject) {
self.mutationListener = domainObject.getCapability('mutation')
.listen(self.refreshComposition.bind(self, domainObject));
}
}
$scope.filterBy = filterBy;
$scope.searchElements = searchElements;
openmct.selection.on('change', setSelection);
setSelection(openmct.selection.get());
$scope.dragDown = this.dragDown;
$scope.drag = this.drag;
$scope.dragUp = this.dragUp;
$scope.$on("$destroy", function () {
openmct.selection.off("change", setSelection);
});
}
/**
* Invoked on DragStart - Adds reordering class to parent UL element
* Sets selected object ID, to be used on Drag End
*
* @param {object} event | Mouse Event
*/
ElementsController.prototype.dragDown = function (event) {
if (!this.parentUL) {
this.parentUL = $(document).find('#inspector-elements-tree');
}
this.selectedTreeItem = $(event.target).parent();
this.selectedObjectId = event.target.getAttribute('data-id');
this.parentUL.addClass('reordering');
this.selectedTreeItem.addClass('reorder-actor');
};
/**
* Invoked on dragEnd - Removes selected object from position in composition
* and replaces it at the target position. Composition is then updated with current
* scope
*
* @param {object} event - Mouse Event
*/
ElementsController.prototype.dragUp = function (event) {
this.targetObjectId = event.target.getAttribute('data-id');
if (this.targetObjectId && this.selectedObjectId) {
var selectedObjectPosition,
targetObjectPosition;
selectedObjectPosition = findObjectInCompositionFromId(this.selectedObjectId, this.scope.composition);
targetObjectPosition = findObjectInCompositionFromId(this.targetObjectId, this.scope.composition);
if ((selectedObjectPosition !== -1) && (targetObjectPosition !== -1)) {
var selectedObject = this.scope.composition.splice(selectedObjectPosition, 1),
selection = this.openmct.selection.get(),
domainObject = selection ? selection[0].context.oldItem : undefined;
this.scope.composition.splice(targetObjectPosition, 0, selectedObject[0]);
if (domainObject) {
domainObject.getCapability('mutation').mutate(function (model) {
model.composition = this.scope.composition.map(function (dObject) {
return dObject.id;
});
}.bind(this));
}
}
}
if (this.parentUL) {
this.parentUL.removeClass('reordering');
}
if (this.selectedTreeItem) {
this.selectedTreeItem.removeClass('reorder-actor');
}
};
ElementsController.prototype.drag = function (event) {
};
/**
* Gets the composition for the selected object and populates the scope with it.
*
* @param domainObject the selected object
* @private
*/
ElementsController.prototype.refreshComposition = function (domainObject) {
var refreshTracker = {};
this.currentRefresh = refreshTracker;
var selectedObjectComposition = domainObject && domainObject.useCapability('composition');
if (selectedObjectComposition) {
selectedObjectComposition.then(function (composition) {
if (this.currentRefresh === refreshTracker) {
this.scope.composition = composition;
}
}.bind(this));
} else {
this.scope.composition = [];
}
};
/**
* Finds position of object with given ID in Composition
*
* @param {String} id
* @param {Array} composition
* @private
*/
function findObjectInCompositionFromId(id, composition) {
var mapped = composition.map(function (element) {
return element.id;
});
return mapped.indexOf(id);
}
return ElementsController;
}
);

View File

@@ -1,133 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT 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 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.
*****************************************************************************/
/**
* Module defining AddAction. Created by ahenry on 01/21/16.
*/
define(
[
'./CreateWizard'
],
function (CreateWizard) {
/**
* The Add Action is performed to create new instances of
* domain objects of a specific type that are subobjects of an
* object being edited. This is the action that is performed when a
* user uses the Add menu option.
*
* @memberof platform/commonUI/browse
* @implements {Action}
* @constructor
*
* @param {Type} type the type of domain object to create
* @param {DomainObject} parent the domain object that should
* act as a container for the newly-created object
* (note that the user will have an opportunity to
* override this)
* @param {ActionContext} context the context in which the
* action is being performed
* @param {DialogService} dialogService
*/
function AddAction(type, parent, context, $q, dialogService, policyService) {
this.metadata = {
key: 'add',
cssClass: type.getCssClass(),
name: type.getName(),
type: type.getKey(),
description: type.getDescription(),
context: context
};
this.type = type;
this.parent = parent;
this.$q = $q;
this.dialogService = dialogService;
this.policyService = policyService;
}
/**
*
* Create a new object of the given type.
* This will prompt for user input first.
*
* @returns {Promise} that will be resolved with the object that the
* action was originally invoked on (ie. the 'parent')
*/
AddAction.prototype.perform = function () {
var newModel = this.type.getInitialModel(),
newObject,
parentObject = this.parent,
wizard;
newModel.type = this.type.getKey();
newObject = parentObject.getCapability('instantiation').instantiate(newModel);
newObject.useCapability('mutation', function (model) {
model.location = parentObject.getId();
});
wizard = new CreateWizard(newObject, this.parent, this.policyService);
function populateObjectFromInput(formValue) {
return wizard.populateObjectFromInput(formValue, newObject);
}
function persistAndReturn(domainObject) {
return domainObject.getCapability('persistence')
.persist()
.then(function () {
return domainObject;
});
}
function addToParent(populatedObject) {
parentObject.getCapability('composition').add(populatedObject);
return persistAndReturn(parentObject);
}
return this.dialogService
.getUserInput(wizard.getFormStructure(false), wizard.getInitialFormValue())
.then(populateObjectFromInput)
.then(persistAndReturn)
.then(addToParent);
};
/**
* Metadata associated with a Add action.
* @typedef {ActionMetadata} AddActionMetadata
* @property {string} type the key for the type of domain object
* to be created
*/
/**
* Get metadata about this action.
* @returns {AddActionMetadata} metadata about this action
*/
AddAction.prototype.getMetadata = function () {
return this.metadata;
};
return AddAction;
}
);

View File

@@ -1,82 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT 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 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.
*****************************************************************************/
/**
* Module defining AddActionProvider.js. Created by ahenry on 01/21/16.
*/
define(
["./AddAction"],
function (AddAction) {
/**
* The AddActionProvider is an ActionProvider which introduces
* an Add action for creating sub objects.
*
* @memberof platform/commonUI/browse
* @constructor
* @implements {ActionService}
*
* @param {TypeService} typeService the type service, used to discover
* available types
* @param {DialogService} dialogService the dialog service, used by
* specific Create actions to get user input to populate the
* model of the newly-created domain object.
* @param {CreationService} creationService the creation service (also
* introduced in this bundle), responsible for handling actual
* object creation.
*/
function AddActionProvider($q, typeService, dialogService, policyService) {
this.typeService = typeService;
this.dialogService = dialogService;
this.$q = $q;
this.policyService = policyService;
}
AddActionProvider.prototype.getActions = function (actionContext) {
var context = actionContext || {},
key = context.key,
destination = context.domainObject;
// We only provide Add actions, and we need a
// domain object to serve as the container for the
// newly-created object (although the user may later
// make a different selection)
if (key !== 'add' || !destination) {
return [];
}
// Introduce one create action per type
return ['timeline', 'activity'].map(function (type) {
return new AddAction(
this.typeService.getType(type),
destination,
context,
this.$q,
this.dialogService,
this.policyService
);
}, this);
};
return AddActionProvider;
}
);

View File

@@ -34,13 +34,13 @@ define(
* @memberof platform/commonUI/browse
* @constructor
*/
function CreateWizard(domainObject, parent, policyService) {
function CreateWizard(domainObject, parent, openmct) {
this.type = domainObject.getCapability('type');
this.model = domainObject.getModel();
this.domainObject = domainObject;
this.properties = this.type.getProperties();
this.parent = parent;
this.policyService = policyService;
this.openmct = openmct;
}
/**
@@ -56,15 +56,10 @@ define(
*/
CreateWizard.prototype.getFormStructure = function (includeLocation) {
var sections = [],
domainObject = this.domainObject,
policyService = this.policyService;
domainObject = this.domainObject;
function validateLocation(parent) {
return parent && policyService.allow(
"composition",
parent,
domainObject
);
return parent && this.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
}
sections.push({
@@ -93,7 +88,7 @@ define(
rows: [{
name: "Save In",
control: "locator",
validate: validateLocation,
validate: validateLocation.bind(this),
key: "createParent"
}]
});

View File

@@ -1,184 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT 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 includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine*/
define(
["../../src/controllers/ElementsController"],
function (ElementsController) {
describe("The Elements Pane controller", function () {
var mockScope,
mockOpenMCT,
mockSelection,
mockDomainObject,
mockMutationCapability,
mockCompositionCapability,
mockCompositionObjects,
mockComposition,
mockUnlisten,
selectable = [],
controller;
function mockPromise(value) {
return {
then: function (thenFunc) {
return mockPromise(thenFunc(value));
}
};
}
function createDomainObject() {
return {
useCapability: function () {
return mockCompositionCapability;
}
};
}
beforeEach(function () {
mockComposition = ["a", "b"];
mockCompositionObjects = mockComposition.map(createDomainObject);
mockCompositionCapability = mockPromise(mockCompositionObjects);
mockUnlisten = jasmine.createSpy('unlisten');
mockMutationCapability = jasmine.createSpyObj("mutationCapability", [
"listen"
]);
mockMutationCapability.listen.and.returnValue(mockUnlisten);
mockDomainObject = jasmine.createSpyObj("domainObject", [
"getCapability",
"useCapability"
]);
mockDomainObject.useCapability.and.returnValue(mockCompositionCapability);
mockDomainObject.getCapability.and.returnValue(mockMutationCapability);
mockScope = jasmine.createSpyObj("$scope", ['$on']);
mockSelection = jasmine.createSpyObj("selection", [
'on',
'off',
'get'
]);
mockSelection.get.and.returnValue([]);
mockOpenMCT = {
selection: mockSelection
};
selectable[0] = {
context: {
oldItem: mockDomainObject
}
};
spyOn(ElementsController.prototype, 'refreshComposition').and.callThrough();
controller = new ElementsController(mockScope, mockOpenMCT);
});
function getModel(model) {
return function () {
return model;
};
}
it("filters objects in elements pool based on input text and" +
" object name", function () {
var objects = [
{
getModel: getModel({name: "first element"})
},
{
getModel: getModel({name: "second element"})
},
{
getModel: getModel({name: "third element"})
},
{
getModel: getModel({name: "THIRD Element 1"})
}
];
mockScope.filterBy("third element");
expect(objects.filter(mockScope.searchElements).length).toBe(2);
mockScope.filterBy("element");
expect(objects.filter(mockScope.searchElements).length).toBe(4);
});
it("refreshes composition on selection", function () {
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
expect(ElementsController.prototype.refreshComposition).toHaveBeenCalledWith(mockDomainObject);
});
it("listens on mutation and refreshes composition", function () {
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
expect(mockDomainObject.getCapability).toHaveBeenCalledWith('mutation');
expect(mockMutationCapability.listen).toHaveBeenCalled();
expect(ElementsController.prototype.refreshComposition.calls.count()).toBe(1);
mockMutationCapability.listen.calls.mostRecent().args[0](mockDomainObject);
expect(ElementsController.prototype.refreshComposition.calls.count()).toBe(2);
});
it("cleans up mutation listener when selection changes", function () {
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
expect(mockMutationCapability.listen).toHaveBeenCalled();
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
expect(mockUnlisten).toHaveBeenCalled();
});
it("does not listen on mutation for element proxy selectable", function () {
selectable[0] = {
context: {
elementProxy: {}
}
};
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
expect(mockDomainObject.getCapability).not.toHaveBeenCalledWith('mutation');
});
it("checks concurrent changes to composition", function () {
var secondMockComposition = ["a", "b", "c"],
secondMockCompositionObjects = secondMockComposition.map(createDomainObject),
firstCompositionCallback,
secondCompositionCallback;
spyOn(mockCompositionCapability, "then").and.callThrough();
controller.refreshComposition(mockDomainObject);
controller.refreshComposition(mockDomainObject);
firstCompositionCallback = mockCompositionCapability.then.calls.all()[0].args[0];
secondCompositionCallback = mockCompositionCapability.then.calls.all()[1].args[0];
secondCompositionCallback(secondMockCompositionObjects);
firstCompositionCallback(mockCompositionObjects);
expect(mockScope.composition).toBe(secondMockCompositionObjects);
});
});
}
);

View File

@@ -1,105 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT 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 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 ahenry on 01/21/14.
*/
define(
["../../src/creation/AddActionProvider"],
function (AddActionProvider) {
describe("The add action provider", function () {
var mockTypeService,
mockDialogService,
mockPolicyService,
mockTypeMap,
mockTypes,
mockDomainObject,
mockQ,
provider;
function createMockType(name) {
var mockType = jasmine.createSpyObj(
"type" + name,
[
"getKey",
"getGlyph",
"getCssClass",
"getName",
"getDescription",
"getProperties",
"getInitialModel",
"hasFeature"
]
);
mockType.hasFeature.and.returnValue(true);
mockType.getName.and.returnValue(name);
mockType.getKey.and.returnValue(name);
return mockType;
}
beforeEach(function () {
mockTypeService = jasmine.createSpyObj(
"typeService",
["getType"]
);
mockDialogService = {};
mockPolicyService = {};
mockDomainObject = {};
mockTypes = [
"timeline",
"activity",
"other"
].map(createMockType);
mockTypeMap = {};
mockTypes.forEach(function (type) {
mockTypeMap[type.getKey()] = type;
});
mockTypeService.getType.and.callFake(function (key) {
return mockTypeMap[key];
});
provider = new AddActionProvider(
mockQ,
mockTypeService,
mockDialogService,
mockPolicyService
);
});
it("provides actions for timeline and activity", function () {
var actions = provider.getActions({
key: "add",
domainObject: mockDomainObject
});
expect(actions.length).toBe(2);
expect(actions[0].metadata.type).toBe('timeline');
expect(actions[1].metadata.type).toBe('activity');
// Make sure it was creation which was used to check
});
});
}
);