[New Edit Mode] “Seamless” Edit Mode

* html changes and Edit Action
* Fixed browse controller to correctly navigate to non-editable object
* Added save and cancel actions
This commit is contained in:
Henry 2016-01-07 19:11:21 -08:00
parent 9cc03123b1
commit c71aa43581
9 changed files with 78 additions and 40 deletions

@ -19,12 +19,13 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<span ng-controller="BrowseObjectController">
<span ng-controller="BrowseObjectController" class="abs l-flex-col">
<div class="object-browse-bar l-flex-row">
<div class="items-select left flex-elem l-flex-row grows">
<mct-representation key="'back-arrow'"
mct-object="domainObject"
class="flex-elem l-back"></mct-representation>
class="flex-elem l-back">
</mct-representation>
<mct-representation key="'object-header'"
mct-object="domainObject"
class="l-flex-row flex-elem grows object-header">
@ -43,8 +44,25 @@
</mct-representation>
</div>
</div>
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs object-holder">
</mct-representation>
<div class="holder l-flex-col flex-elem grows l-object-wrapper"
ng-class="{'edit-main':editMode}" style="margin-top: 50px;">
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
<!-- Toolbar and Save/Cancel buttons -->
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
<mct-toolbar name="mctToolbar"
structure="toolbar.structure"
ng-model="toolbar.state"
class="flex-elem grows">
</mct-toolbar>
<mct-representation key="'edit-action-buttons'"
mct-object="domainObject"
class='flex-elem conclude-editing'>
</mct-representation>
</div>
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs flex-elem grows object-holder-main scroll"
toolbar="toolbar">
</mct-representation>
</div><!--/ l-object-wrapper-inner -->
</span>

@ -20,7 +20,7 @@
at runtime from the About dialog for additional information.
-->
<div class="abs holder-all browse-mode" ng-controller="BrowseController">
<div class="abs holder-all" ng-controller="BrowseController">
<mct-include key="'topbar-browse'"></mct-include>
<div class="abs holder holder-main browse-area s-browse-area browse-wrapper"
ng-controller="PaneController as modelPaneTree"
@ -72,7 +72,7 @@
<div class="split-pane-component t-inspect pane right mobile-hide">
<mct-representation key="'object-inspector'"
mct-object="domainObject"
mct-object="navigatedObject"
ng-model="treeModel">
</mct-representation>
<a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect"

@ -71,10 +71,14 @@ define(
// Callback for updating the in-scope reference to the object
// that is currently navigated-to.
function setNavigation(domainObject) {
//If the domain object has editor capability, retrieve the
// original uneditable domain object
var nonEditableObject = domainObject.hasCapability("editor") ? domainObject.getCapability("editor").getDomainObject() : domainObject;
$scope.navigatedObject = domainObject;
$scope.treeModel.selectedObject = domainObject;
$scope.treeModel.selectedObject = nonEditableObject;
navigationService.setNavigation(domainObject);
updateRoute(domainObject);
updateRoute(nonEditableObject);
}
function navigateTo(domainObject) {

@ -38,7 +38,7 @@
{
"key": "edit",
"implementation": "actions/EditAction.js",
"depends": [ "$location", "navigationService", "$log" ],
"depends": [ "$location", "$q", "navigationService", "$log" ],
"description": "Edit this object.",
"category": "view-control",
"glyph": "p"
@ -67,7 +67,7 @@
"implementation": "actions/SaveAction.js",
"name": "Save",
"description": "Save changes made to these objects.",
"depends": [ "$location", "urlService" ],
"depends": [ "$location", "navigationService" ],
"priority": "mandatory"
},
{
@ -76,7 +76,7 @@
"implementation": "actions/CancelAction.js",
"name": "Cancel",
"description": "Discard changes made to these objects.",
"depends": [ "$location", "urlService" ]
"depends": [ "$location", "navigationService" ]
}
],
"policies": [

@ -33,10 +33,10 @@ define(
* @memberof platform/commonUI/edit
* @implements {Action}
*/
function CancelAction($location, urlService, context) {
function CancelAction($location, navigationService, context) {
this.domainObject = context.domainObject;
this.$location = $location;
this.urlService = urlService;
this.navigationService = navigationService;
}
/**
@ -48,7 +48,7 @@ define(
CancelAction.prototype.perform = function () {
var domainObject = this.domainObject,
$location = this.$location,
urlService = this.urlService;
navigationService = this.navigationService;
// Look up the object's "editor.completion" capability;
// this is introduced by EditableDomainObject which is
@ -64,13 +64,9 @@ define(
return editor.cancel();
}
// Discard the current root view (which will be the editing
// UI, which will have been pushed atop the Browise UI.)
function returnToBrowse() {
$location.path($location.path(urlService.urlForLocation(
"browse",
domainObject
)));
//Return navigation state to the non-editable version of the object.
function returnToBrowse(nonEditableDomainObject) {
navigationService.setNavigation(nonEditableDomainObject);
}
return doCancel(getEditorCapability())

@ -25,8 +25,8 @@
* Module defining EditAction. Created by vwoeltje on 11/14/14.
*/
define(
[],
function () {
['../objects/EditableDomainObject'],
function (EditableDomainObject) {
"use strict";
// A no-op action to return in the event that the action cannot
@ -46,7 +46,7 @@ define(
* @constructor
* @implements {Action}
*/
function EditAction($location, navigationService, $log, context) {
function EditAction($location, $q, navigationService, $log, context) {
var domainObject = (context || {}).domainObject;
// We cannot enter Edit mode if we have no domain object to
@ -65,14 +65,15 @@ define(
this.domainObject = domainObject;
this.$location = $location;
this.navigationService = navigationService;
this.$q = $q;
}
/**
* Enter edit mode.
*/
EditAction.prototype.perform = function () {
this.navigationService.setNavigation(this.domainObject);
this.$location.path("/edit");
this.domainObject.getCapability('status').set('editing', true);
this.navigationService.setNavigation(new EditableDomainObject(this.domainObject, this.$q));
};
/**
@ -85,8 +86,11 @@ define(
var domainObject = (context || {}).domainObject,
type = domainObject && domainObject.getCapability('type');
// Only allow creatable types to be edited
return type && type.hasFeature('creation');
// Only allow creatable types to be edited, and objects that are
// not already being edited
return type
&& type.hasFeature('creation')
&& !domainObject.getCapability('status').get('editing');
};
return EditAction;

@ -34,10 +34,10 @@ define(
* @implements {Action}
* @memberof platform/commonUI/edit
*/
function SaveAction($location, urlService, context) {
function SaveAction($location, navigationService, context) {
this.domainObject = (context || {}).domainObject;
this.$location = $location;
this.urlService = urlService;
this.navigationService = navigationService;
}
/**
@ -50,7 +50,8 @@ define(
SaveAction.prototype.perform = function () {
var domainObject = this.domainObject,
$location = this.$location,
urlService = this.urlService;
urlService = this.urlService,
navigationService = this.navigationService;
// Invoke any save behavior introduced by the editor capability;
// this is introduced by EditableDomainObject which is
@ -62,11 +63,12 @@ define(
// Discard the current root view (which will be the editing
// UI, which will have been pushed atop the Browise UI.)
function returnToBrowse() {
return $location.path(urlService.urlForLocation(
function returnToBrowse(nonEditableDomainObject) {
navigationService.setNavigation(nonEditableDomainObject);
/*return $location.path(urlService.urlForLocation(
"browse",
domainObject
));
));*/
}
return doSave().then(returnToBrowse);

@ -95,9 +95,16 @@ define(
return domainObject.getCapability('persistence').persist();
}
return nonrecursive ?
resolvePromise(doMutate()).then(doPersist) :
resolvePromise(cache.saveAll());
function saveChanges() {
return nonrecursive ?
resolvePromise(doMutate()).then(doPersist) :
resolvePromise(cache.saveAll());
}
return saveChanges().then(function(){
domainObject.getCapability('status').set('editing', false);
return domainObject;
})
};
/**
@ -109,7 +116,8 @@ define(
* @memberof platform/commonUI/edit.EditorCapability#
*/
EditorCapability.prototype.cancel = function () {
return resolvePromise(undefined);
this.domainObject.getCapability('status').set('editing', false);
return resolvePromise(this.domainObject);
};
/**
@ -121,6 +129,10 @@ define(
return this.cache.dirty();
};
EditorCapability.prototype.getDomainObject = function () {
return this.domainObject;
}
return EditorCapability;
}
);

@ -47,6 +47,7 @@ define(
*/
function EditRepresenter($q, $log, scope) {
var self = this;
this.scope = scope;
// Mutate and persist a new version of a domain object's model.
function doPersist(model) {
@ -100,6 +101,7 @@ define(
this.key = (representation || {}).key;
// Track the represented object
this.domainObject = representedObject;
this.scope.editMode = representedObject.hasCapability("status") && representedObject.getCapability("status").get("editing");
// Ensure existing watches are released
this.destroy();
};