diff --git a/src/Umbraco.Tests/Controllers/WebApiEditors/EnsureUserPermissionForContentAttributeTests.cs b/src/Umbraco.Tests/Controllers/WebApiEditors/EnsureUserPermissionForContentAttributeTests.cs index 72d0cf3641..5f24e12e21 100644 --- a/src/Umbraco.Tests/Controllers/WebApiEditors/EnsureUserPermissionForContentAttributeTests.cs +++ b/src/Umbraco.Tests/Controllers/WebApiEditors/EnsureUserPermissionForContentAttributeTests.cs @@ -14,6 +14,7 @@ using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using Umbraco.Web; +using Umbraco.Web.Editors; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; using umbraco.presentation.channels.businesslogic; @@ -21,7 +22,7 @@ using umbraco.presentation.channels.businesslogic; namespace Umbraco.Tests.Controllers.WebApiEditors { [TestFixture] - public class EnsureUserPermissionForContentAttributeTests + public class ContentControllerUnitTests { [Test] public void Does_Not_Throw_Exception_When_Access_Allowed_By_Path() @@ -37,15 +38,12 @@ namespace Umbraco.Tests.Controllers.WebApiEditors var userService = MockRepository.GenerateStub(); var permissions = new List(); userService.Stub(x => x.GetPermissions(user, 1234)).Return(permissions); - var ctx = new HttpActionContext(); - ctx.ActionArguments.Add("id", 1234); - var attribute = new EnsureUserPermissionForContentAttribute(user, userService, contentService, 1234, 'F'); //act - attribute.OnActionExecuting(ctx); + var result = ContentController.CheckPermissions(new Dictionary(), user, userService, contentService, 1234, 'F'); //assert - Assert.Pass(); + Assert.IsTrue(result); } [Test] @@ -62,11 +60,9 @@ namespace Umbraco.Tests.Controllers.WebApiEditors var userService = MockRepository.GenerateStub(); var permissions = new List(); userService.Stub(x => x.GetPermissions(user, 1234)).Return(permissions); - var ctx = new HttpActionContext(); - var attribute = new EnsureUserPermissionForContentAttribute(user, userService, contentService, 1234, 'F'); - + //act/assert - Assert.Throws(() => attribute.OnActionExecuting(ctx)); + Assert.Throws(() => ContentController.CheckPermissions(new Dictionary(), user, userService, contentService, 1234, 'F')); } [Test] @@ -83,11 +79,12 @@ namespace Umbraco.Tests.Controllers.WebApiEditors var userService = MockRepository.GenerateStub(); var permissions = new List(); userService.Stub(x => x.GetPermissions(user, 1234)).Return(permissions); - var ctx = new HttpActionContext(); - var attribute = new EnsureUserPermissionForContentAttribute(user, userService, contentService, 1234, 'F'); - //act/assert - Assert.Throws(() => attribute.OnActionExecuting(ctx)); + //act + var result = ContentController.CheckPermissions(new Dictionary(), user, userService, contentService, 1234, 'F'); + + //assert + Assert.IsFalse(result); } [Test] @@ -107,11 +104,12 @@ namespace Umbraco.Tests.Controllers.WebApiEditors new EntityPermission(9, 1234, new string[]{ "A", "B", "C" }) }; userService.Stub(x => x.GetPermissions(user, 1234)).Return(permissions); - var ctx = new HttpActionContext(); - var attribute = new EnsureUserPermissionForContentAttribute(user, userService, contentService, 1234, 'F'); - //act/assert - Assert.Throws(() => attribute.OnActionExecuting(ctx)); + //act + var result = ContentController.CheckPermissions(new Dictionary(), user, userService, contentService, 1234, 'F'); + + //assert + Assert.IsFalse(result); } [Test] @@ -131,15 +129,12 @@ namespace Umbraco.Tests.Controllers.WebApiEditors new EntityPermission(9, 1234, new string[]{ "A", "F", "C" }) }; userService.Stub(x => x.GetPermissions(user, 1234)).Return(permissions); - var ctx = new HttpActionContext(); - ctx.ActionArguments.Add("id", 1234); - var attribute = new EnsureUserPermissionForContentAttribute(user, userService, contentService, 1234, 'F'); //act - attribute.OnActionExecuting(ctx); + var result = ContentController.CheckPermissions(new Dictionary(), user, userService, contentService, 1234, 'F'); //assert - Assert.Pass(); + Assert.IsTrue(result); } [Test] @@ -156,15 +151,12 @@ namespace Umbraco.Tests.Controllers.WebApiEditors var userService = MockRepository.GenerateStub(); var permissions = new List(); userService.Stub(x => x.GetPermissions(user, 1234)).Return(permissions); - var ctx = new HttpActionContext(); - ctx.ActionArguments.Add("id", 1234); - var attribute = new EnsureUserPermissionForContentAttribute(user, userService, contentService, 1234, 'F'); //act - attribute.OnActionExecuting(ctx); + var result = ContentController.CheckPermissions(new Dictionary(), user, userService, contentService, 1234, 'F'); //assert - Assert.Pass(); + Assert.IsTrue(result); } } diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js index b7b181d25b..14fb6d8da8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js @@ -38,7 +38,7 @@ { alias: "textarea", label: "textarea", view: "textarea", value: "ajsdka sdjkds", config: { rows: 4 } }, { alias: "map", label: "Map", view: "googlemaps", value: "37.4419,-122.1419", config: { mapType: "ROADMAP", zoom: 4 } }, { alias: "media", label: "Media picker", view: "mediapicker", value: "" }, - { alias: "content", label: "Content picker", view: "contentpicker", value: "" } + { alias: "content", label: "Content picker", view: "contentpicker", value: "1234,23242,23232,23231" } ] }, { @@ -120,6 +120,10 @@ return node; }, + getMockEntity : function(id){ + return {name: "hello", id: id, icon: "icon-file"}; + }, + /** generally used for unit tests, calling this will disable the auth check and always return true */ disableAuth: function() { doAuth = false; @@ -162,9 +166,25 @@ getParameterByName: function(url, name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(url); - return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }, + + getParametersByName: function(url, name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + + var regex = new RegExp(name + "=([^&#]*)", "mg"), results = []; + var match; + + while ( ( match = regex.exec(url) ) !== null ) + { + results.push(decodeURIComponent(match[1].replace(/\+/g, " "))); + } + + return results; } }; }]); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/content.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/content.mocks.js index d0cf5b8f63..199dac4514 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/content.mocks.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/content.mocks.js @@ -95,6 +95,23 @@ angular.module('umbraco.mocks'). return [200, node, null]; } + function returnNodebyIds(status, data, headers) { + + if (!mocksUtils.checkAuth()) { + return [401, null, null]; + } + + var ids = mocksUtils.getParameterByName(data, "ids") || [1234,23324,2323,23424]; + var nodes = []; + + $(ids).each(function(i, id){ + var _id = parseInt(id, 10); + nodes.push(mocksUtils.getMockContent(_id)); + }); + + return [200, nodes, null]; + } + function returnSort(status, data, headers) { if (!mocksUtils.checkAuth()) { return [401, null, null]; @@ -114,7 +131,11 @@ angular.module('umbraco.mocks'). .respond(returnChildren); $httpBackend - .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Content/GetById')) + .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Content/GetByIds')) + .respond(returnNodebyIds); + + $httpBackend + .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Content/GetById?')) .respond(returnNodebyId); $httpBackend diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js new file mode 100644 index 0000000000..baaf2f5fc3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js @@ -0,0 +1,48 @@ +angular.module('umbraco.mocks'). + factory('entityMocks', ['$httpBackend', 'mocksUtils', function ($httpBackend, mocksUtils) { + 'use strict'; + + function returnEntitybyId(status, data, headers) { + + if (!mocksUtils.checkAuth()) { + return [401, null, null]; + } + + var id = mocksUtils.getParameterByName(data, "id") || "1234"; + id = parseInt(id, 10); + + var node = mocksUtils.getMockEntity(id); + + return [200, node, null]; + } + + function returnEntitybyIds(status, data, headers) { + + if (!mocksUtils.checkAuth()) { + return [401, null, null]; + } + + var ids = mocksUtils.getParametersByName(data, "ids") || [1234,23324,2323,23424]; + var nodes = []; + + $(ids).each(function(i, id){ + var _id = parseInt(id, 10); + nodes.push(mocksUtils.getMockEntity(_id)); + }); + + return [200, nodes, null]; + } + + + return { + register: function () { + $httpBackend + .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetByIds')) + .respond(returnEntitybyIds); + + $httpBackend + .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetById?')) + .respond(returnEntitybyId); + } + }; + }]); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.httpbackend.js b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.httpbackend.js index 2ccbe13d67..448743e70f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.httpbackend.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.httpbackend.js @@ -1,7 +1,7 @@ var umbracoAppDev = angular.module('umbraco.httpbackend', ['umbraco', 'ngMockE2E', 'umbraco.mocks']); -function initBackEnd($httpBackend, contentMocks, mediaMocks, treeMocks, userMocks, contentTypeMocks, sectionMocks) { +function initBackEnd($httpBackend, contentMocks, mediaMocks, treeMocks, userMocks, contentTypeMocks, sectionMocks, entityMocks) { console.log("httpBackend inited"); @@ -15,6 +15,8 @@ function initBackEnd($httpBackend, contentMocks, mediaMocks, treeMocks, userMock contentTypeMocks.register(); + entityMocks.register(); + $httpBackend.whenGET(/^views\//).passThrough(); $httpBackend.whenGET(/^js\//).passThrough(); $httpBackend.whenGET(/^lib\//).passThrough(); diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js index 2a51738bbd..dd19a43810 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js @@ -13,6 +13,7 @@ Umbraco.Sys.ServerVariables = { "authenticationApiBaseUrl": "/umbraco/UmbracoApi/Authentication/", //For this we'll just provide a file that exists during the mock session since we don't really have legay js tree stuff "legacyTreeJs": "/belle/lib/yepnope/empty.js", + "entityApiBaseUrl": "/umbraco/UmbracoApi/Entity/" }, umbracoSettings: { "umbracoPath": "/umbraco", diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 3931deef32..797d50310e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -1,8 +1,28 @@ /** - * @ngdoc service - * @name umbraco.resources.contentResource - * @description Loads/saves in data for content -**/ + * @ngdoc service + * @name umbraco.resources.contentResource + * @description Handles all transactions of content data + * from the angular application to the Umbraco database, using the Content WebApi controller + * + * all methods returns a resource promise async, so all operations won't complete untill .then() is completed. + * + * @requires $q + * @requires $http + * @requires umbDataFormatter + * @requires umbRequestHelper + * + * ##usage + * To use, simply inject the contentResource into any controller or service that needs it, and make + * sure the umbraco.resources module is accesible - which it should be by default. + * + *
+  *    contentResource.getById(1234)
+  *          .then(function(data) {
+  *              $scope.content = data;
+  *          });    
+  * 
+ **/ + function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { /** internal method process the saving of data and post processing the result */ @@ -16,6 +36,28 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { return { + /** + * @ngdoc method + * @name umbraco.resources.contentResource#sort + * @methodOf umbraco.resources.contentResource + * + * @description + * Sorts all children below a given parent node id, based on a collection of node-ids + * + * ##usage + *
+         * var ids = [123,34533,2334,23434];
+         * contentResource.sort({ parentId: 1244, sortedIds: ids })
+         *    .then(function() {
+         *        $scope.complete = true;
+         *    });
+         * 
+ * @param {Object} args arguments object + * @param {Int} args.parentId the ID of the parent node + * @param {Array} options.sortedIds array of node IDs as they should be sorted + * @returns {Promise} resourcePromise object. + * + */ sort: function (args) { if (!args) { throw "args cannot be null"; @@ -36,6 +78,25 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to sort content'); }, + /** + * @ngdoc method + * @name umbraco.resources.contentResource#emptyRecycleBin + * @methodOf umbraco.resources.contentResource + * + * @description + * Empties the content recycle bin + * + * ##usage + *
+         * contentResource.emptyRecycleBin()
+         *    .then(function() {
+         *        alert('its empty!');
+         *    });
+         * 
+ * + * @returns {Promise} resourcePromise object. + * + */ emptyRecycleBin: function() { return umbRequestHelper.resourcePromise( $http.delete( @@ -45,6 +106,26 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to empty the recycle bin'); }, + /** + * @ngdoc method + * @name umbraco.resources.contentResource#deleteById + * @methodOf umbraco.resources.contentResource + * + * @description + * Deletes a content item with a given id + * + * ##usage + *
+         * contentResource.deleteById(1234)
+         *    .then(function() {
+         *        alert('its gone!');
+         *    });
+         * 
+ * + * @param {Int} id id of content item to delete + * @returns {Promise} resourcePromise object. + * + */ deleteById: function(id) { return umbRequestHelper.resourcePromise( $http.delete( @@ -55,6 +136,27 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to delete item ' + id); }, + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getById + * @methodOf umbraco.resources.contentResource + * + * @description + * Gets a content item with a given id + * + * ##usage + *
+         * contentResource.getById(1234)
+         *    .then(function(content) {
+         *        var myDoc = content; 
+         *        alert('its here!');
+         *    });
+         * 
+ * + * @param {Int} id id of content item to return + * @returns {Promise} resourcePromise object containing the content item. + * + */ getById: function (id) { return umbRequestHelper.resourcePromise( $http.get( @@ -65,6 +167,27 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to retreive data for content id ' + id); }, + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getByIds + * @methodOf umbraco.resources.contentResource + * + * @description + * Gets an array of content items, given a collection of ids + * + * ##usage + *
+         * contentResource.getByIds( [1234,2526,28262])
+         *    .then(function(contentArray) {
+         *        var myDoc = contentArray; 
+         *        alert('they are here!');
+         *    });
+         * 
+ * + * @param {Array} ids ids of content items to return as an array + * @returns {Promise} resourcePromise object containing the content items array. + * + */ getByIds: function (ids) { var idQuery = ""; @@ -81,8 +204,39 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to retreive data for content id ' + id); }, - /** returns an empty content object which can be persistent on the content service - requires the parent id and the alias of the content type to base the scaffold on */ + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getScaffold + * @methodOf umbraco.resources.contentResource + * + * @description + * Returns a scaffold of an empty content item, given the id of the content item to place it underneath and the content type alias. + * + * - Parent Id must be provided so umbraco knows where to store the content + * - Content Type alias must be provided so umbraco knows which properties to put on the content scaffold + * + * The scaffold is used to build editors for content that has not yet been populated with data. + * + * ##usage + *
+         * contentResource.getScaffold(1234, 'homepage')
+         *    .then(function(scaffold) {
+         *        var myDoc = scaffold;
+         *        myDoc.name = "My new document"; 
+         *
+         *        contentResource.publishContent(myDoc, true)
+         *            .then(function(content){
+         *                alert("Retrieved, updated and published again");
+         *            });
+         *    });
+         * 
+ * + * @param {Int} parentId id of content item to return + * @param {String} alias contenttype alias to base the scaffold on + * @returns {Promise} resourcePromise object containing the content scaffold. + * + */ getScaffold: function (parentId, alias) { return umbRequestHelper.resourcePromise( @@ -94,6 +248,33 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to retreive data for empty content item type ' + alias); }, + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getChildren + * @methodOf umbraco.resources.contentResource + * + * @description + * Gets children of a content item with a given id + * + * ##usage + *
+         * contentResource.getChildren(1234, {pageSize: 10, pageNumber: 2})
+         *    .then(function(contentArray) {
+         *        var children = contentArray; 
+         *        alert('they are here!');
+         *    });
+         * 
+ * + * @param {Int} parentid id of content item to return children of + * @param {Object} options optional options object + * @param {Int} options.pageSize if paging data, number of nodes per page, default = 0 + * @param {Int} options.pageNumber if paging data, current page index, default = 0 + * @param {String} options.filter if provided, query will only return those with names matching the filter + * @param {String} options.orderDirection can be `Ascending` or `Descending` - Default: `Ascending` + * @param {String} options.orderBy property to order items by, default: `SortOrder` + * @returns {Promise} resourcePromise object containing an array of content items. + * + */ getChildren: function (parentId, options) { var defaults = { @@ -134,12 +315,67 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { 'Failed to retreive children for content item ' + parentId); }, - /** saves or updates a content object */ + /** + * @ngdoc method + * @name umbraco.resources.contentResource#saveContent + * @methodOf umbraco.resources.contentResource + * + * @description + * Saves changes made to a content item to its current version, if the content item is new, the isNew paramater must be passed to force creation + * if the content item needs to have files attached, they must be provided as the files param and passed seperately + * + * + * ##usage + *
+         * contentResource.getById(1234)
+         *    .then(function(content) {
+         *          content.name = "I want a new name!";
+         *          contentResource.saveContent(content, false)
+         *            .then(function(content){
+         *                alert("Retrieved, updated and saved again");
+         *            });
+         *    });
+         * 
+ * + * @param {Object} content The content item object with changes applied + * @param {Bool} isNew set to true to create a new item or to update an existing + * @param {Array} files collection of files for the document + * @returns {Promise} resourcePromise object containing the saved content item. + * + */ saveContent: function (content, isNew, files) { return saveContentItem(content, "save" + (isNew ? "New" : ""), files); }, - /** saves and publishes a content object */ + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#publishContent + * @methodOf umbraco.resources.contentResource + * + * @description + * Saves and publishes changes made to a content item to a new version, if the content item is new, the isNew paramater must be passed to force creation + * if the content item needs to have files attached, they must be provided as the files param and passed seperately + * + * + * ##usage + *
+         * contentResource.getById(1234)
+         *    .then(function(content) {
+         *          content.name = "I want a new name, and be published!";
+         *          contentResource.publishContent(content, false)
+         *            .then(function(content){
+         *                alert("Retrieved, updated and published again");
+         *            });
+         *    });
+         * 
+ * + * @param {Object} content The content item object with changes applied + * @param {Bool} isNew set to true to create a new item or to update an existing + * @param {Array} files collection of files for the document + * @returns {Promise} resourcePromise object containing the saved content item. + * + */ publishContent: function (content, isNew, files) { return saveContentItem(content, "publish" + (isNew ? "New" : ""), files); } diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js new file mode 100644 index 0000000000..f205ca573f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js @@ -0,0 +1,88 @@ +/** + * @ngdoc service + * @name umbraco.resources.entityResource + * @description Loads in basic data for all entities + * + * ##What is an entity? + * An entity is a basic **read-only** representation of an Umbraco node. It contains only the most + * basic properties used to display the item in trees, lists and navigation. + * + **/ +function entityResource($q, $http, umbRequestHelper) { + + //the factory object returned + return { + + /** + * @ngdoc method + * @name umbraco.resources.entityResource#getById + * @methodOf umbraco.resources.entityResource + * + * @description + * Gets an entity with a given id + * + * ##usage + *
+         * entityResource.getById(1234)
+         *    .then(function(ent) {
+         *        var myDoc = ent; 
+         *        alert('its here!');
+         *    });
+         * 
+ * + * @param {Int} id id of entity to return + * @returns {Promise} resourcePromise object containing the entity. + * + */ + getById: function (id) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "entityApiBaseUrl", + "GetById", + [{ id: id }])), + 'Failed to retreive entity data for id ' + id); + }, + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getByIds + * @methodOf umbraco.resources.contentResource + * + * @description + * Gets an array of content items, given a collection of ids + * + * ##usage + *
+         * contentResource.getByIds( [1234,2526,28262])
+         *    .then(function(contentArray) {
+         *        var myDoc = contentArray; 
+         *        alert('they are here!');
+         *    });
+         * 
+ * + * @param {Array} ids ids of entities to return as an array + * @returns {Promise} resourcePromise object containing the entity array. + * + */ + getByIds: function (ids) { + + var idQuery = ""; + _.each(ids, function(item) { + idQuery += "ids=" + item + "&"; + }); + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "entityApiBaseUrl", + "GetByIds", + idQuery)), + 'Failed to retreive entity data for ids ' + idQuery); + } + + + }; +} + +angular.module('umbraco.resources').factory('entityResource', entityResource); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js index 1e75bae95d..207b3d2d8d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js @@ -23,7 +23,7 @@ * var dialog = dialogService.open({template: 'path/to/page.html', show: true, callback: done}); * functon done(data){ * //The dialog has been submitted - * // data contains whatever the dialog has selected / attached + * //data contains whatever the dialog has selected / attached * } * */ diff --git a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js index 51749ec24f..e5393069c9 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js @@ -294,7 +294,7 @@ function umbDataFormatter() { _.each(tab.properties, function (prop) { //don't include the custom generic tab properties - if (tab.id !== 0 && !prop.alias.startsWith("_umb_")) { + if (!prop.alias.startsWith("_umb_")) { saveModel.properties.push({ id: prop.id, alias: prop.alias, diff --git a/src/Umbraco.Web.UI.Client/src/views/directives/umb-editor.html b/src/Umbraco.Web.UI.Client/src/views/directives/umb-editor.html index bbaf7c3da1..21a8a3dc3c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/directives/umb-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/directives/umb-editor.html @@ -1,7 +1,7 @@
-
+
 {{model | json}}
 
diff --git a/src/Umbraco.Web.UI.Client/src/views/media/edit.html b/src/Umbraco.Web.UI.Client/src/views/media/edit.html index a5d5335cde..bb4504f1f8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/edit.html @@ -19,13 +19,16 @@ - - - - +
+ + + + +
-
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js index d9b445437f..d1a3104a02 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js @@ -2,12 +2,29 @@ //with a specified callback, this callback will receive an object with a selection on it angular.module('umbraco') .controller("Umbraco.Editors.ContentPickerController", - function($scope, dialogService){ - $scope.openContentPicker =function(){ - var d = dialogService.contentPicker({scope: $scope, callback: populate}); - }; + + function($scope, dialogService, entityResource){ + $scope.ids = $scope.model.value.split(','); + $scope.renderModel = []; - function populate(data){ - $scope.model.value = data.selection; - } + entityResource.getByIds($scope.ids).then(function(data){ + $(data).each(function(i, item){ + $scope.renderModel.push({name: item.name, id: item.id, icon: item.icon}); + }); + }); + + $scope.openContentPicker =function(){ + var d = dialogService.contentPicker({scope: $scope, callback: populate}); + }; + + function populate(data){ + $(data.selection).each(function(i, item){ + $scope.renderModel.push({name: item.name, id: item.id, icon: item.icon}) + $scope.ids.push(item.id); + }); + + //set the model value to a comma-sep string + //TOOD: consider if we should save more managed model? + $scope.model.value = $scope.ids.join(); + } }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html index 2af37287fc..9cc3a8451a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.html @@ -1,6 +1,6 @@