From 3e7264d6b8b9b91abf089b9649eeb5eeb6551e09 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 27 Oct 2015 17:38:31 -0700 Subject: [PATCH] Initial implementation of virtual panel --- platform/commonUI/edit/bundle.json | 4 +- .../commonUI/edit/src/actions/SaveAction.js | 75 +++++++++++++++++-- .../core/src/objects/DomainObjectProvider.js | 48 +++++++----- .../test/objects/DomainObjectProviderSpec.js | 9 +++ platform/representation/bundle.json | 3 +- .../src/gestures/DropGesture.js | 49 +++++++++--- 6 files changed, 150 insertions(+), 38 deletions(-) diff --git a/platform/commonUI/edit/bundle.json b/platform/commonUI/edit/bundle.json index d577013ffd..37c6175d6b 100644 --- a/platform/commonUI/edit/bundle.json +++ b/platform/commonUI/edit/bundle.json @@ -67,7 +67,9 @@ "implementation": "actions/SaveAction.js", "name": "Save", "description": "Save changes made to these objects.", - "depends": [ "$location", "urlService", "navigationService" ], + "depends": [ "$q", "$location", "$injector", "urlService", + "navigationService", "policyService", "dialogService", + "creationService" ], "priority": "mandatory" }, { diff --git a/platform/commonUI/edit/src/actions/SaveAction.js b/platform/commonUI/edit/src/actions/SaveAction.js index 2f7044660e..f9f545ed79 100644 --- a/platform/commonUI/edit/src/actions/SaveAction.js +++ b/platform/commonUI/edit/src/actions/SaveAction.js @@ -23,7 +23,8 @@ define( - function () { + ['../../../browse/src/creation/createWizard'], + function (CreateWizard) { 'use strict'; /** @@ -34,11 +35,26 @@ define( * @implements {Action} * @memberof platform/commonUI/edit */ - function SaveAction($location, urlService, navigationService, context) { + function SaveAction($q, $location, $injector, urlService, navigationService, policyService, dialogService, creationService, context) { this.domainObject = (context || {}).domainObject; this.$location = $location; + this.injectObjectService = function(){ + this.objectService = $injector.get("objectService"); + } this.urlService = urlService; this.navigationService = navigationService; + this.policyService = policyService; + this.dialogService = dialogService; + this.creationService = creationService; + this.$q = $q; + } + + SaveAction.prototype.getObjectService = function(){ + // Lazily acquire object service (avoids cyclical dependency) + if (!this.objectService) { + this.injectObjectService(); + } + return this.objectService; } /** @@ -54,23 +70,66 @@ define( urlService = this.urlService, self = this; + function doWizardSave(domainObject, parent) { + var context = domainObject.getCapability("context"); + var wizard = new CreateWizard(domainObject.useCapability('type'), parent, self.policyService); + + // Create and persist the new object, based on user + // input. + function persistResult(formValue) { + var parent = wizard.getLocation(formValue), + newModel = wizard.createModel(formValue); + return self.creationService.createObject(newModel, parent); + } + + function doNothing() { + // Create cancelled, do nothing + return false; + } + + /** + * Add the composees of the 'virtual' object to the + * persisted object + * @param object + * @returns {*} + */ + function composeObject(object){ + return object && self.$q.when(object.hasCapability('composition') && domainObject.hasCapability('composition')) + .then(function(){ + return domainObject.useCapability('composition') + .then(function(composees){ + return self.$q.all(composees.map(function(composee){ + return object.getCapability('composition').add(composee); + })); + }); + }); + } + + return self.dialogService.getUserInput( + wizard.getFormStructure(), + wizard.getInitialFormValue() + ).then(persistResult, doNothing).then(composeObject); + } + // Invoke any save behavior introduced by the editor capability; // this is introduced by EditableDomainObject which is // used to insulate underlying objects from changes made // during editing. function doSave() { - return domainObject.getCapability("editor").save(); + //WARNING: HACK + //This is a new 'virtual panel' that has not been persisted + // yet. + if (domainObject.getModel().type === 'telemetry.panel' && !domainObject.getModel().persisted){ + return self.getObjectService().getObjects([domainObject.getModel().location]).then(function(objs){ doWizardSave(domainObject, objs[domainObject.getModel().location])}); + } else { + return domainObject.getCapability("editor").save(); + } } // Discard the current root view (which will be the editing // UI, which will have been pushed atop the Browse UI.) function returnToBrowse() { - return self.navigationService.setNavigation(self.domainObject.getDomainObject()); - /*return $location.path(urlService.urlForLocation( - "browse", - domainObject - ));*/ } return doSave().then(returnToBrowse); diff --git a/platform/core/src/objects/DomainObjectProvider.js b/platform/core/src/objects/DomainObjectProvider.js index c846cbf665..04e6826670 100644 --- a/platform/core/src/objects/DomainObjectProvider.js +++ b/platform/core/src/objects/DomainObjectProvider.js @@ -70,6 +70,25 @@ define( this.$q = $q; } + // Assemble the results from the model service and the + // capability service into one value, suitable to return + // from this service. Note that ids are matched to capabilities + // by index. + function assembleResult(ids, models, capabilities) { + var result = {}; + ids.forEach(function (id, index) { + if (models[id]) { + // Create the domain object + result[id] = new DomainObjectImpl( + id, + models[id], + capabilities[index] + ); + } + }); + return result; + } + DomainObjectProvider.prototype.getObjects = function getObjects(ids) { var modelService = this.modelService, capabilityService = this.capabilityService, @@ -87,25 +106,6 @@ define( }; } - // Assemble the results from the model service and the - // capability service into one value, suitable to return - // from this service. Note that ids are matched to capabilities - // by index. - function assembleResult(ids, models, capabilities) { - var result = {}; - ids.forEach(function (id, index) { - if (models[id]) { - // Create the domain object - result[id] = new DomainObjectImpl( - id, - models[id], - capabilities[index] - ); - } - }); - return result; - } - return modelService.getModels(ids).then(function (models) { return $q.all( ids.map(capabilityResolver(models)) @@ -115,6 +115,16 @@ define( }); }; + /** + * Given a model, return a fully constituted domain object that has + * not been persisted + * @param model + */ + DomainObjectProvider.prototype.newObject = function newObject(id, model){ + var capabilities = this.capabilityService.getCapabilities(model); + return new DomainObjectImpl(id, model, capabilities); + } + return DomainObjectProvider; } ); diff --git a/platform/core/test/objects/DomainObjectProviderSpec.js b/platform/core/test/objects/DomainObjectProviderSpec.js index 3aca982260..e3641e62d1 100644 --- a/platform/core/test/objects/DomainObjectProviderSpec.js +++ b/platform/core/test/objects/DomainObjectProviderSpec.js @@ -90,6 +90,15 @@ define( expect(result.a.getModel()).toEqual(model); }); + it("provides a new, fully constituted domain object for a" + + " provided model", function () { + var model = { someKey: "some value"}, + result; + result = provider.newObject("a", model); + expect(result.getId()).toEqual("a"); + expect(result.getModel()).toEqual(model); + }); + }); } ); \ No newline at end of file diff --git a/platform/representation/bundle.json b/platform/representation/bundle.json index a8b0da566c..c4ebf51f66 100644 --- a/platform/representation/bundle.json +++ b/platform/representation/bundle.json @@ -21,7 +21,8 @@ { "key": "drop", "implementation": "gestures/DropGesture.js", - "depends": [ "dndService", "$q", "navigationService" ] + "depends": [ "dndService", "$q", "navigationService", + "objectService" ] }, { "key": "menu", diff --git a/platform/representation/src/gestures/DropGesture.js b/platform/representation/src/gestures/DropGesture.js index f1f59bc277..7a488b682e 100644 --- a/platform/representation/src/gestures/DropGesture.js +++ b/platform/representation/src/gestures/DropGesture.js @@ -26,8 +26,9 @@ */ define( ['./GestureConstants', - '../../../commonUI/edit/src/objects/EditableDomainObject'], - function (GestureConstants, EditableDomainObject) { + '../../../commonUI/edit/src/objects/EditableDomainObject', + '../../../commonUI/browse/lib/uuid'], + function (GestureConstants, EditableDomainObject, uuid) { "use strict"; /** @@ -41,7 +42,7 @@ define( * @param {DomainObject} domainObject the domain object whose * composition should be modified as a result of the drop. */ - function DropGesture(dndService, $q, navigationService, element, domainObject) { + function DropGesture(dndService, $q, navigationService, objectService, element, domainObject) { var actionCapability = domainObject.getCapability('action'), editableDomainObject, action; // Action for the drop, when it occurs @@ -86,8 +87,9 @@ define( key: 'compose', selectedObject: selectedObject })[0]; - - if (action) { + //TODO: Fix this. Define an action for creating new + // virtual panel + if (action || selectedObject.getModel().type === 'generator') { event.dataTransfer.dropEffect = 'move'; // Indicate that we will accept the drag @@ -97,10 +99,33 @@ define( } } + /* + composition: Array[0] + location: "mine" + name: "Test Telemetry Panel" + persisted: 1445975352374 + type: "telemetry.panel" + */ + + function createVirtualPanel(base, overlayId){ + var model = { + name: 'New telemetry panel', + type: 'telemetry.panel', + composition: [base.getId(), overlayId], + location: base.getModel().location + }, + id = uuid(); + //ObjectService is wrapped by a decorator which is obscuring + // the newObject method. + return objectService.objectService.newObject(id, model); + + } + function drop(e) { var event = (e || {}).originalEvent || e, id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE), - domainObjectType = editableDomainObject.getModel().type; + domainObjectType = editableDomainObject.getModel().type, + virtualObj; // If currently in edit mode allow drag and drop gestures to the // domain object. An exception to this is folders which have drop @@ -111,10 +136,16 @@ define( // destination domain object's composition, and persist // the change. if (id) { - $q.when(action && action.perform()).then(function (result) { - navigationService.setNavigation(editableDomainObject); + if (domainObjectType === 'generator'){ + virtualObj = new EditableDomainObject(createVirtualPanel(domainObject, id)); + navigationService.setNavigation(virtualObj); broadcastDrop(id, event); - }); + } else { + $q.when(action && action.perform()).then(function (result) { + navigationService.setNavigation(editableDomainObject); + broadcastDrop(id, event); + }); + } } //} // TODO: Alert user if drag and drop is not allowed