diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs index e35d474204..8dba129d93 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs @@ -853,7 +853,7 @@ AND umbracoNode.id <> @id", //first we want to get the main content type data this is 1 : 1 with umbraco node data var ct = result - .Where(x => x.ctId == currentCtId) + .Where(x => (int)x.ctId == currentCtId) .Select(x => new { x.ctPk, x.ctId, x.ctAlias, x.ctAllowAtRoot, x.ctDesc, x.ctIcon, x.ctIsContainer, x.ctThumb, x.nName, x.nCreateDate, x.nLevel, x.nObjectType, x.nUser, x.nParentId, x.nPath, x.nSortOrder, x.nTrashed, x.nUniqueId }) .DistinctBy(x => (int)x.ctId) .FirstOrDefault(); diff --git a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs index 0e45a24adb..6ace0f6203 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs @@ -4,6 +4,7 @@ using System.Linq; using AutoMapper; using Moq; using NUnit.Framework; +using umbraco; using umbraco.cms.presentation; using Umbraco.Core; using Umbraco.Core.Logging; @@ -177,11 +178,35 @@ namespace Umbraco.Tests.Models.Mapping Assert.AreEqual(display.Thumbnail, result.Thumbnail); Assert.AreEqual(display.IsContainer, result.IsContainer); Assert.AreEqual(display.AllowAsRoot, result.AllowedAsRoot); + Assert.AreEqual(display.CreateDate, result.CreateDate); + Assert.AreEqual(display.UpdateDate, result.UpdateDate); //TODO: Now we need to assert all of the more complicated parts - Assert.AreEqual(1, result.PropertyGroups.Count); - Assert.AreEqual(1, result.PropertyGroups[0].PropertyTypes.Count); + Assert.AreEqual(display.Groups.Count(), result.PropertyGroups.Count); + for (var i = 0; i < display.Groups.Count(); i++) + { + Assert.AreEqual(display.Groups.ElementAt(i).Id, result.PropertyGroups.ElementAt(i).Id); + Assert.AreEqual(display.Groups.ElementAt(i).Name, result.PropertyGroups.ElementAt(i).Name); + var propTypes = display.Groups.ElementAt(i).Properties; + Assert.AreEqual(propTypes.Count(), result.PropertyTypes.Count()); + for (var j = 0; j < propTypes.Count(); j++) + { + Assert.AreEqual(propTypes.ElementAt(j).Id, result.PropertyTypes.ElementAt(j).Id); + Assert.AreEqual(propTypes.ElementAt(j).DataTypeId, result.PropertyTypes.ElementAt(j).DataTypeDefinitionId); + } + } + Assert.AreEqual(display.AllowedTemplates.Count(), result.AllowedTemplates.Count()); + for (var i = 0; i < display.AllowedTemplates.Count(); i++) + { + Assert.AreEqual(display.AllowedTemplates.ElementAt(i).Id, result.AllowedTemplates.ElementAt(i).Id); + } + + Assert.AreEqual(display.AllowedContentTypes.Count(), result.AllowedContentTypes.Count()); + for (var i = 0; i < display.AllowedContentTypes.Count(); i++) + { + Assert.AreEqual(display.AllowedContentTypes.ElementAt(i), result.AllowedContentTypes.ElementAt(i).Id.Value); + } } [Test] @@ -231,13 +256,39 @@ namespace Umbraco.Tests.Models.Mapping Assert.AreEqual(contentType.Path, result.Path); Assert.AreEqual(contentType.Thumbnail, result.Thumbnail); Assert.AreEqual(contentType.IsContainer, result.IsContainer); - + Assert.AreEqual(contentType.CreateDate, result.CreateDate); + Assert.AreEqual(contentType.UpdateDate, result.UpdateDate); Assert.AreEqual(contentType.DefaultTemplate.Alias, result.DefaultTemplate.Alias); //TODO: Now we need to assert all of the more complicated parts - Assert.AreEqual(2, result.Groups.Count()); - Assert.AreEqual(2, result.Groups.ElementAt(0).Properties.Count()); - Assert.AreEqual(2, result.Groups.ElementAt(1).Properties.Count()); + + Assert.AreEqual(contentType.PropertyGroups.Count(), result.Groups.Count()); + for (var i = 0; i < contentType.PropertyGroups.Count(); i++) + { + Assert.AreEqual(contentType.PropertyGroups.ElementAt(i).Id, result.Groups.ElementAt(i).Id); + Assert.AreEqual(contentType.PropertyGroups.ElementAt(i).Name, result.Groups.ElementAt(i).Name); + var propTypes = contentType.PropertyGroups.ElementAt(i).PropertyTypes; + + Assert.AreEqual(propTypes.Count(), result.Groups.ElementAt(i).Properties.Count()); + for (var j = 0; j < propTypes.Count(); j++) + { + Assert.AreEqual(propTypes.ElementAt(j).Id, result.Groups.ElementAt(i).Properties.ElementAt(j).Id); + Assert.AreEqual(propTypes.ElementAt(j).DataTypeDefinitionId, result.Groups.ElementAt(i).Properties.ElementAt(j).DataTypeId); + } + } + + Assert.AreEqual(contentType.AllowedTemplates.Count(), result.AllowedTemplates.Count()); + for (var i = 0; i < contentType.AllowedTemplates.Count(); i++) + { + Assert.AreEqual(contentType.AllowedTemplates.ElementAt(i).Id, result.AllowedTemplates.ElementAt(i).Id); + } + + Assert.AreEqual(contentType.AllowedContentTypes.Count(), result.AllowedContentTypes.Count()); + for (var i = 0; i < contentType.AllowedContentTypes.Count(); i++) + { + Assert.AreEqual(contentType.AllowedContentTypes.ElementAt(i).Id.Value, result.AllowedContentTypes.ElementAt(i)); + } + } private ContentTypeDisplay CreateSimpleContentTypeDisplay() @@ -246,7 +297,22 @@ namespace Umbraco.Tests.Models.Mapping { Alias = "test", AllowAsRoot = true, - AllowedTemplates = new List(), + AllowedTemplates = new List + { + new EntityBasic + { + Id = 555, + Alias = "template1", + Name = "Template1" + }, + new EntityBasic + { + Id = 556, + Alias = "template2", + Name = "Template2" + } + }, + AllowedContentTypes = new [] {666, 667}, AvailableCompositeContentTypes = new List(), DefaultTemplate = new EntityBasic(){ Alias = "test" }, Description = "hello world", diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs index de7fed05bf..cd8c151f25 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using AutoMapper; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -16,9 +17,11 @@ using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Tests.Persistence.Repositories { + [RequiresAutoMapperMappings] [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] [TestFixture] public class ContentTypeRepositoryTest : BaseDatabaseFactoryTest @@ -108,12 +111,44 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(contentType.HasIdentity, Is.True); Assert.That(contentType.PropertyGroups.All(x => x.HasIdentity), Is.True); + Assert.That(contentType.PropertyTypes.All(x => x.HasIdentity), Is.True); Assert.That(contentType.Path.Contains(","), Is.True); Assert.That(contentType.SortOrder, Is.GreaterThan(0)); } } + [Test] + public void Can_Perform_Add_On_ContentTypeRepository_After_Model_Mapping() + { + // Arrange + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + using (var repository = CreateRepository(unitOfWork)) + { + // Act + var contentType = (IContentType)MockedContentTypes.CreateSimpleContentType(); + var display = Mapper.Map(contentType); + //simulate what would happen in the controller, we'd never map to a 'existing' content type, + // we'd map to an new content type when updating. + var mapped = Mapper.Map(display); + + repository.AddOrUpdate(mapped); + unitOfWork.Commit(); + + //re-get + contentType = repository.Get(mapped.Id); + + // Assert + Assert.That(contentType.HasIdentity, Is.True); + Assert.That(contentType.PropertyGroups.All(x => x.HasIdentity), Is.True); + Assert.That(contentType.PropertyTypes.All(x => x.HasIdentity), Is.True); + Assert.That(contentType.Path.Contains(","), Is.True); + Assert.That(contentType.SortOrder, Is.GreaterThan(0)); + } + + } + [Test] public void Can_Perform_Update_On_ContentTypeRepository() { @@ -149,6 +184,66 @@ namespace Umbraco.Tests.Persistence.Repositories } + [Test] + public void Can_Perform_Update_On_ContentTypeRepository_After_Model_Mapping() + { + // Arrange + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + using (var repository = CreateRepository(unitOfWork)) + { + // Act + var contentType = repository.Get(NodeDto.NodeIdSeed + 1); + + var display = Mapper.Map(contentType); + + display.Thumbnail = "Doc2.png"; + var contentGroup = display.Groups.Single(x => x.Name == "Content"); + + //add property + contentGroup.Properties = contentGroup.Properties.Concat(new[] + { + new PropertyTypeDisplay() + { + Alias = "subtitle", + Editor = "test", + Label = "Subtitle", + Description = "Optional Subtitle", + Validation = new PropertyTypeValidation() + { + Mandatory = false, + Pattern = "" + }, + SortOrder = 1, + DataTypeId = -88 + } + }); + + //simulate what would happen in the controller, we'd never map to a 'new' content type, + // we'd map to an existing content type when updating. + var mapped = Mapper.Map(display, contentType); + + repository.AddOrUpdate(mapped); + unitOfWork.Commit(); + + var dirty = mapped.IsDirty(); + + //re-get + contentType = repository.Get(NodeDto.NodeIdSeed + 1); + + // Assert + Assert.That(contentType.HasIdentity, Is.True); + Assert.That(dirty, Is.False); + Assert.That(contentType.Thumbnail, Is.EqualTo("Doc2.png")); + Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "subtitle"), Is.True); + foreach (var propertyType in contentType.PropertyTypes) + { + Assert.IsTrue(propertyType.HasIdentity); + Assert.Greater(propertyType.Id, 0); + } + } + } + [Test] public void Can_Perform_Delete_On_ContentTypeRepository() { diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index 7408429fa4..02ca5afcdb 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -13,6 +13,7 @@ using Umbraco.Tests.TestHelpers.Entities; namespace Umbraco.Tests.Services { + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] [TestFixture, RequiresSTA] public class ContentTypeServiceTests : BaseServiceTest diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js index 512036dff0..a2f8fbbfc4 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js @@ -4,7 +4,7 @@ * @restrict E **/ angular.module("umbraco.directives") - .directive('umbOverlay', function () { + .directive('umbOverlay', function ($timeout) { return { scope: { @@ -37,8 +37,59 @@ angular.module("umbraco.directives") } cssClass += " " + shadow; - scope.overlayCssClass = cssClass; + + + function setTargetPosition() { + + var position = { + right: "inherit", + left: "inherit", + top: "inherit", + bottom: "inherit" + }; + + // viewport size + var viewportWidth = $(window).innerWidth(); + var viewportHeight = $(window).innerHeight(); + + // mouse click position + var mousePositionClickX = scope.model.event.pageX; + var mousePositionClickY = scope.model.event.pageY; + + // element size + var elementHeight = element.context.clientHeight; + var elementWidth = element.context.clientWidth; + + // move element to this position + position.left = mousePositionClickX - (elementWidth / 2); + position.top = mousePositionClickY - (elementHeight / 2); + + // check to see if element is outside screen + // outside right + if( position.left + elementWidth > viewportWidth) { + position.right = 0; + position.left = "inherit"; + } + + // outside bottom + if( position.top + elementHeight > viewportHeight ) { + position.bottom = 0; + position.top = "inherit"; + } + + element.css(position); + + + } + + + $timeout(function() { + if(scope.position === "target") { + setTargetPosition(); + } + }); + scope.closeOverLay = function(){ if(scope.model.close){ scope.model.close(scope.model); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/events/events.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/events/events.directive.js index 0077853ac5..704b46bf1b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/events/events.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/events/events.directive.js @@ -64,7 +64,7 @@ angular.module('umbraco.directives') scope.$on("$destroy", function() { $(document).off("click", oneTimeClick); }); - }, 1000); + }); // Temp removal of 1 sec timeout to prevent bug where overlay does not open. We need to find a better solution. }; }) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/overlays.less b/src/Umbraco.Web.UI.Client/src/less/components/overlays.less index 55c128797c..2767ce894f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/overlays.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/overlays.less @@ -26,6 +26,34 @@ } } + +// TARGET OVERLAY +.umb-overlay-target { + position: fixed; + width: 400px; + height: 400px; + overflow: hidden; + border: 1px solid #ccc; + background: white; + padding: 7px; + z-index: 996660; + box-sizing: border-box; + .umb-overlay-header{ + border-bottom: 1px solid #d9d9d9; + color: #999; + padding: 10px; + margin-top: 0; + text-align: center; + } + .umb-overlay-container{ + position: absolute; + top: 68px; + left: 7px; + right: 7px; + bottom: 7px; + overflow: auto; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/less/pages/document-type-editor.less b/src/Umbraco.Web.UI.Client/src/less/pages/document-type-editor.less index 7c9302de4b..0b6449953d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/pages/document-type-editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/pages/document-type-editor.less @@ -692,4 +692,54 @@ } +/* ---------- DIALOG ---------- */ + +.dialog-grid { + text-align: center; + display: flex; + flex-wrap: wrap; + align-content: space-between; +} + +.dialog-grid-element { + flex: 0 0 80px; + height: 80px; + padding: 5px; + overflow: hidden; + font-size: 11px; + margin: 5px 0; + display: flex; + align-items: center; + justify-content: center; +} + + +.dialog-grid-element:hover { + background: #2e8aea; +} + +.dialog-grid-element a { + color: #222; + text-decoration: none; +} + +.dialog-grid-element i { + font-size: 30px; + color: #999; + display: block; + margin-bottom: 10px; +} + + +.dialog-grid-element a:hover { + background: #2e8aea; + color: white; +} + +.dialog-grid-element a:hover i { + color: white; +} + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttype/dialogs/contenttypes/contenttypes.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttype/dialogs/contenttypes/contenttypes.controller.js new file mode 100644 index 0000000000..01f28b50a8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/documenttype/dialogs/contenttypes/contenttypes.controller.js @@ -0,0 +1,15 @@ +/** + * @ngdoc controller + * @name Umbraco.Editors.DocumentType.PropertyController + * @function + * + * @description + * The controller for the content type editor property dialog + */ +function CompositionsController($scope, contentTypeResource) { + + + +} + +angular.module("umbraco").controller("Umbraco.Editors.DocumentType.CompositionsController", CompositionsController); diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttype/dialogs/contenttypes/contenttypes.html b/src/Umbraco.Web.UI.Client/src/views/documenttype/dialogs/contenttypes/contenttypes.html new file mode 100644 index 0000000000..1219026d67 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/documenttype/dialogs/contenttypes/contenttypes.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.controller.js index 33225d18c4..8dec85d911 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.controller.js @@ -6,12 +6,11 @@ * @description * The controller for the content type editor property dialog */ -function PermissionsController($scope, contentTypeResource) { +function PermissionsController($scope, contentTypeResource, $log) { /* ----------- SCOPE VARIABLES ----------- */ $scope.contentTypes = []; - $scope.showPlaceholderDetails = false; /* ---------- INIT ---------- */ @@ -47,46 +46,6 @@ function PermissionsController($scope, contentTypeResource) { } - $scope.addSelectedContentType = function(selectedContentType) { - - if(selectedContentType.alias !== "undefined" || selectedContentType.alias !== null) { - - var reformatedContentType = { - "name": selectedContentType.name, - "id": { - "m_boxed": { - "m_value": selectedContentType.id - } - }, - "icon": selectedContentType.icon, - "key": selectedContentType.key, - "alias": selectedContentType.alias - }; - - // push selected content type to allowed array - $scope.contentType.allowedContentTypes.push(reformatedContentType); - - // hide selected content type from content types array - for (var contentTypeIndex = 0; contentTypeIndex < $scope.contentTypes.length; contentTypeIndex++) { - - var contentType = $scope.contentTypes[contentTypeIndex]; - - if( selectedContentType.alias === contentType.alias ) { - contentType.show = false; - } - } - - // hide placeholder details - $scope.showPlaceholderDetails = false; - - } - - }; - - $scope.togglePlaceholderDetails = function() { - $scope.showPlaceholderDetails = !$scope.showPlaceholderDetails; - }; - $scope.removeAllowedChildNode = function(selectedContentType) { // splice from array @@ -105,6 +64,53 @@ function PermissionsController($scope, contentTypeResource) { }; + $scope.addItemOverlay = function ($event) { + + $scope.showDialog = false; + $scope.dialogModel = {}; + $scope.dialogModel.title = "Choose content type"; + $scope.dialogModel.contentTypes = $scope.contentTypes; + $scope.dialogModel.event = $event; + $scope.dialogModel.view = "views/documentType/dialogs/contenttypes/contenttypes.html"; + $scope.showDialog = true; + + $scope.dialogModel.chooseContentType = function(selectedContentType) { + + // format content type to match service + var reformatedContentType = { + "name": selectedContentType.name, + "id": { + "m_boxed": { + "m_value": selectedContentType.id + } + }, + "icon": selectedContentType.icon, + "key": selectedContentType.key, + "alias": selectedContentType.alias + }; + + // push to content type model + $scope.contentType.allowedContentTypes.push(reformatedContentType); + + // hide selected content type from content types array + for (var contentTypeIndex = 0; contentTypeIndex < $scope.contentTypes.length; contentTypeIndex++) { + + var contentType = $scope.contentTypes[contentTypeIndex]; + + if( selectedContentType.alias === contentType.alias ) { + contentType.show = false; + } + } + + $scope.showDialog = false; + $scope.dialogModel = null; + }; + + $scope.dialogModel.close = function(){ + $scope.showDialog = false; + $scope.dialogModel = null; + }; + }; } diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.html index 5e6b087b93..754a10baad 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttype/views/permissions/permissions.html @@ -51,14 +51,8 @@ -
-
Allow child node
-
- - Allow -
+
+
Allow child node
@@ -74,4 +68,13 @@
+ + + \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeBasic.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeBasic.cs index 2e527cfd93..b12233b1b3 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeBasic.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeBasic.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations; +using System; +using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; using Umbraco.Core; using Umbraco.Core.IO; @@ -14,6 +15,11 @@ namespace Umbraco.Web.Models.ContentEditing [DataContract(Name = "contentType", Namespace = "")] public class ContentTypeBasic : EntityBasic { + [DataMember(Name = "updateDate")] + public DateTime UpdateDate { get; set; } + + [DataMember(Name = "createDate")] + public DateTime CreateDate { get; set; } [DataMember(Name = "description")] public string Description { get; set; } diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs index ad26dd8014..c7ed92ec5b 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs @@ -46,8 +46,6 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dto => dto.AllowedAsRoot, expression => expression.MapFrom(display => display.AllowAsRoot)) .ForMember(dto => dto.CreatorId, expression => expression.Ignore()) .ForMember(dto => dto.Level, expression => expression.Ignore()) - .ForMember(dto => dto.CreateDate, expression => expression.Ignore()) - .ForMember(dto => dto.UpdateDate, expression => expression.Ignore()) .ForMember(dto => dto.SortOrder, expression => expression.Ignore()) //mapped in aftermap .ForMember(dto => dto.AllowedContentTypes, expression => expression.Ignore()) @@ -65,7 +63,7 @@ namespace Umbraco.Web.Models.Mapping //Sync allowed child types var allowedTypes = source.AllowedContentTypes.Select((t, i) => new ContentTypeSort(t, i)); - dest.AllowedContentTypes = allowedTypes; + dest.AllowedContentTypes = allowedTypes.ToArray(); //sync compositions var current = dest.CompositionAliases().ToArray(); @@ -108,22 +106,17 @@ namespace Umbraco.Web.Models.Mapping .ForMember( dto => dto.CompositeContentTypes, expression => expression.MapFrom(dto => dto.ContentTypeComposition)) - - .ForMember( - dto => dto.CompositeContentTypes, - expression => expression.MapFrom(dto => dto.ContentTypeComposition)) - + .ForMember( dto => dto.Groups, expression => expression.ResolveUsing(new PropertyTypeGroupResolver(applicationContext, _propertyEditorResolver))); config.CreateMap() .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0)) - .ForMember(g => g.CreateDate, expression => expression.Ignore()) .ForMember(g => g.Key, expression => expression.Ignore()) - .ForMember(g => g.CreateDate, expression => expression.Ignore()) - .ForMember(g => g.HasIdentity, expression => expression.Ignore()) - .ForMember(g => g.UpdateDate, expression => expression.Ignore()) + .ForMember(g => g.HasIdentity, expression => expression.Ignore()) + .ForMember(dto => dto.CreateDate, expression => expression.Ignore()) + .ForMember(dto => dto.UpdateDate, expression => expression.Ignore()) //only map if a parent is actually set .ForMember(g => g.ParentId, expression => expression.Condition(display => display.ParentGroupId > 0)) @@ -150,6 +143,9 @@ namespace Umbraco.Web.Models.Mapping if (dataType == null) throw new NullReferenceException("No data type found with id " + propertyTypeDisplay.DataTypeId); return new PropertyType(dataType, propertyTypeDisplay.Alias); }) + .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0)) + .ForMember(dto => dto.CreateDate, expression => expression.Ignore()) + .ForMember(dto => dto.UpdateDate, expression => expression.Ignore()) .ForMember(type => type.PropertyGroupId, expression => expression.MapFrom(display => new Lazy(() => display.GroupId, LazyThreadSafetyMode.None))) .ForMember(type => type.Key, expression => expression.Ignore()) .ForMember(type => type.HelpText, expression => expression.Ignore()) @@ -158,9 +154,6 @@ namespace Umbraco.Web.Models.Mapping .ForMember(type => type.Alias, expression => expression.Ignore()) //ignore because this is obsolete and shouldn't be used .ForMember(type => type.DataTypeId, expression => expression.Ignore()) - //ignore because these are 'readonly' - .ForMember(type => type.CreateDate, expression => expression.Ignore()) - .ForMember(type => type.UpdateDate, expression => expression.Ignore()) .ForMember(type => type.Mandatory, expression => expression.MapFrom(display => display.Validation.Mandatory)) .ForMember(type => type.ValidationRegExp, expression => expression.MapFrom(display => display.Validation.Pattern)) .ForMember(type => type.PropertyEditorAlias, expression => expression.MapFrom(display => display.Editor)) diff --git a/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs b/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs index cc26be9305..7c9799a059 100644 --- a/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs @@ -165,7 +165,9 @@ namespace Umbraco.Web.Models.Mapping ContentTypeId = contentType.Id, ContentTypeName = contentType.Name, GroupId = groupId, - Inherited = inherited + Inherited = inherited, + DataTypeId = p.DataTypeDefinitionId, + SortOrder = p.SortOrder }); }