diff --git a/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js b/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js index f0563d5900..81e3fff441 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js @@ -16,7 +16,8 @@ function appState($rootScope) { touchDevice: null, showTray: null, stickyNavigation: null, - navMode: null + navMode: null, + editingEntity: null }; var sectionState = { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 0a2a74d006..5ed9212d3c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -2,11 +2,13 @@ /** * @ngdoc service * @name umbraco.services.contentEditingHelper -* @description A helper service for content/media/member controllers when editing/creating/saving content. +* @description A helper service for most editors, some methods are specific to content/media/member model types but most are used by +* all editors to share logic and reduce the amount of replicated code among editors. **/ -function contentEditingHelper($location, $routeParams, notificationsService, serverValidationManager, dialogService, formHelper) { +function contentEditingHelper($location, $routeParams, notificationsService, serverValidationManager, dialogService, formHelper, appState) { return { + /** * @ngdoc method @@ -36,15 +38,15 @@ function contentEditingHelper($location, $routeParams, notificationsService, ser * @function * * @description - * re-binds all changed property values to the origContent object from the newContent object and returns an array of changed properties. + * re-binds all changed property values to the origContent object from the savedContent object and returns an array of changed properties. */ - reBindChangedProperties: function (origContent, newContent) { + reBindChangedProperties: function (origContent, savedContent) { var changed = []; //get a list of properties since they are contained in tabs var allOrigProps = this.getAllProps(origContent); - var allNewProps = this.getAllProps(newContent); + var allNewProps = this.getAllProps(savedContent); function getNewProp(alias) { return _.find(allNewProps, function (item) { @@ -66,8 +68,8 @@ function contentEditingHelper($location, $routeParams, notificationsService, ser continue; } - if (!_.isEqual(origContent[o], newContent[o])) { - origContent[o] = newContent[o]; + if (!_.isEqual(origContent[o], savedContent[o])) { + origContent[o] = savedContent[o]; } } @@ -109,9 +111,6 @@ function contentEditingHelper($location, $routeParams, notificationsService, ser if (!args.err) { throw "args.err cannot be null"; } - if (!args.allNewProps && !angular.isArray(args.allNewProps)) { - throw "args.allNewProps must be a valid array"; - } if (args.redirectOnFailure === undefined || args.redirectOnFailure === null) { throw "args.redirectOnFailure must be set to true or false"; } @@ -168,11 +167,11 @@ function contentEditingHelper($location, $routeParams, notificationsService, ser if (!args) { throw "args cannot be null"; } - if (!args.newContent) { - throw "args.newContent cannot be null"; + if (!args.savedContent) { + throw "args.savedContent cannot be null"; } - if (!this.redirectToCreatedContent(args.redirectId ? args.redirectId : args.newContent.id)) { + if (!this.redirectToCreatedContent(args.redirectId ? args.redirectId : args.savedContent.id)) { //we are not redirecting because this is not new content, it is existing content. In this case // we need to detect what properties have changed and re-bind them with the server data. diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editorContext.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editorContext.service.js deleted file mode 100644 index 4f69a3011a..0000000000 --- a/src/Umbraco.Web.UI.Client/src/common/services/editorContext.service.js +++ /dev/null @@ -1,2 +0,0 @@ -angular.module("umbraco.services") - .value('editorContext', undefined); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js index f47b98f5a5..487ba611db 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js @@ -6,7 +6,7 @@ * @description * The controller for the content editor */ -function ContentEditController($scope, $routeParams, $q, $timeout, $window, appState, contentResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, editorContext, treeService, fileManager, formHelper, umbRequestHelper, keyboardService) { +function ContentEditController($scope, $routeParams, $q, $timeout, $window, appState, contentResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, treeService, fileManager, formHelper, umbRequestHelper, keyboardService, umbModelMapper) { //setup scope vars $scope.defaultButton = null; @@ -15,9 +15,6 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS $scope.currentSection = appState.getSectionState("currentSection"); $scope.currentNode = null; //the editors affiliated node - //we need this to share our content object with property editors - editorContext = $scope.content; - //This sets up the action buttons based on what permissions the user has. //The allowedActions parameter contains a list of chars, each represents a button by permission so //here we'll build the buttons according to the chars of the user. @@ -123,11 +120,15 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS contentEditingHelper.handleSuccessfulSave({ scope: $scope, - newContent: data, + savedContent: data, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); + //update appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + configureButtons(data); + navigationService.syncTree({ tree: "content", path: data.path.split(","), forceReload: true }).then(function (syncArgs) { $scope.currentNode = syncArgs.node; }); @@ -139,10 +140,12 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS contentEditingHelper.handleSaveError({ redirectOnFailure: true, err: err, - allNewProps: contentEditingHelper.getAllProps(err.data), - allOrigProps: contentEditingHelper.getAllProps($scope.content) + rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); + //update appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + deferred.reject(err); }); } @@ -159,6 +162,8 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS .then(function(data) { $scope.loaded = true; $scope.content = data; + //put this into appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); configureButtons($scope.content); }); } @@ -168,6 +173,8 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS .then(function(data) { $scope.loaded = true; $scope.content = data; + //put this into appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); configureButtons($scope.content); //in one particular special case, after we've created a new item we redirect back to the edit @@ -194,7 +201,7 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS contentEditingHelper.handleSuccessfulSave({ scope: $scope, - newContent: data, + savedContent: data, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); diff --git a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js index 5a83003c46..7f82dd8fec 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js @@ -45,8 +45,8 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig $scope.preValues = []; if ($routeParams.create) { - //we are creating so get an empty content item - dataTypeResource.getScaffold($routeParams.id, $routeParams.doctype) + //we are creating so get an empty data type item + dataTypeResource.getScaffold($routeParams.id) .then(function(data) { $scope.loaded = true; $scope.preValuesLoaded = true; @@ -101,7 +101,7 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig contentEditingHelper.handleSuccessfulSave({ scope: $scope, - newContent: data, + savedContent: data, rebindCallback: function() { createPreValueProps(data.preValues); } @@ -117,9 +117,7 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig // to be the same thing since that only really matters for content/media. contentEditingHelper.handleSaveError({ redirectOnFailure: false, - err: err, - allNewProps: $scope.preValues, - allOrigProps: $scope.preValues + err: err }); }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js index 99f21c3fb9..1d3e226fd8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js @@ -6,7 +6,7 @@ * @description * The controller for the media editor */ -function mediaEditController($scope, $routeParams, appState, mediaResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, treeService, formHelper) { +function mediaEditController($scope, $routeParams, appState, mediaResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, treeService, formHelper, umbModelMapper) { //setup scope vars $scope.nav = navigationService; @@ -19,7 +19,8 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi .then(function (data) { $scope.loaded = true; $scope.content = data; - + //put this into appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); }); } else { @@ -27,7 +28,9 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi .then(function (data) { $scope.loaded = true; $scope.content = data; - + //put this into appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + //in one particular special case, after we've created a new item we redirect back to the edit // route but there might be server validation errors in the collection which we need to display // after the redirect, so we will bind all subscriptions which will show the server validation errors @@ -52,10 +55,13 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi contentEditingHelper.handleSuccessfulSave({ scope: $scope, - newContent: data, + savedContent: data, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); + //update appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + navigationService.syncTree({ tree: "media", path: data.path, forceReload: true }).then(function (syncArgs) { $scope.currentNode = syncArgs.node; }); @@ -65,9 +71,11 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi contentEditingHelper.handleSaveError({ err: err, redirectOnFailure: true, - allNewProps: contentEditingHelper.getAllProps(err.data), rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); + + //update appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js index f1ade8b374..4a20db9c43 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js @@ -6,19 +6,29 @@ * @description * The controller for the member editor */ -function MemberEditController($scope, $routeParams, $location, $q, $window, appState, memberResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper, treeService) { +function MemberEditController($scope, $routeParams, $location, $q, $window, appState, memberResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper, umbModelMapper) { //setup scope vars $scope.nav = navigationService; $scope.currentSection = appState.getSectionState("currentSection"); $scope.currentNode = null; //the editors affiliated node + //build a path to sync the tree with + function buildTreePath(data) { + //TODO: Will this work for the 'other' list ? + var path = data.name[0] + "," + data.key; + path = path.replace(/-/g, ''); + return path; + } + if ($routeParams.create) { //we are creating so get an empty member item memberResource.getScaffold($routeParams.doctype) .then(function(data) { $scope.loaded = true; $scope.content = data; + //put this into appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); }); } else { @@ -40,9 +50,10 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS $scope.loaded = true; $scope.content = data; - //build a path to sync the tree with - var path = data.name[0]+"," + data.key; - path = path.replace(/-/g,''); + //put this into appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + + var path = buildTreePath(data); navigationService.syncTree({ tree: "member", path: path.split(",") }).then(function (syncArgs) { $scope.currentNode = syncArgs.node; @@ -69,13 +80,18 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS contentEditingHelper.handleSuccessfulSave({ scope: $scope, - newContent: data, + savedContent: data, //specify a custom id to redirect to since we want to use the GUID redirectId: data.key, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); - navigationService.syncTree({ tree: "member", path: path.split(",") }).then(function (syncArgs) { + //update appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + + var path = buildTreePath(data); + + navigationService.syncTree({ tree: "member", path: path.split(","), forceReload: true }).then(function (syncArgs) { $scope.currentNode = syncArgs.node; }); @@ -84,9 +100,11 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS contentEditingHelper.handleSaveError({ redirectOnFailure: false, err: err, - allNewProps: contentEditingHelper.getAllProps(err.data), - allOrigProps: contentEditingHelper.getAllProps($scope.content) + rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); + + //update appState + appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); }); }