From 97c352030a2cd5d70b37097c310b8b7a954de210 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 7 Oct 2015 17:16:42 +0200 Subject: [PATCH] Gets a little more validation working and creating using the new Save models --- .../Mapping/MappingExpressionExtensions.cs | 20 ++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../components/umbgroupsbuilder.directive.js | 1 - .../src/common/services/util.service.js | 8 +- .../less/components/umb-group-builder.less | 2 +- .../src/less/mixins.less | 12 ++ .../views/documenttypes/edit.controller.js | 11 +- .../Models/Mapping/ContentTypeModelMapper.cs | 108 +++++++++++------- src/Umbraco.Web/WebBootManager.cs | 9 +- 9 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 src/Umbraco.Core/Models/Mapping/MappingExpressionExtensions.cs diff --git a/src/Umbraco.Core/Models/Mapping/MappingExpressionExtensions.cs b/src/Umbraco.Core/Models/Mapping/MappingExpressionExtensions.cs new file mode 100644 index 0000000000..570e51dbc3 --- /dev/null +++ b/src/Umbraco.Core/Models/Mapping/MappingExpressionExtensions.cs @@ -0,0 +1,20 @@ +using AutoMapper; + +namespace Umbraco.Core.Models.Mapping +{ + internal static class MappingExpressionExtensions + { + /// + /// Ignores all unmapped members by default - Use with caution! + /// + /// + /// + /// + /// + public static IMappingExpression IgnoreAllUnmapped(this IMappingExpression expression) + { + expression.ForAllMembers(opt => opt.Ignore()); + return expression; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 15e00bcb8f..e05f59d1d6 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -367,6 +367,7 @@ + diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js index 12487187e5..c93df61e13 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js @@ -298,7 +298,6 @@ if (addGroup) { groups.push({ - groups: [], properties: [], parentTabContentTypes: [], parentTabContentTypeNames: [], 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 8b85201b29..75735abe41 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 @@ -497,8 +497,12 @@ function umbDataFormatter() { //TODO: Map these saveModel.allowedTemplates = _.map(displayModel.allowedTemplates, function (t) { return t.alias; }); - saveModel.defaultTemplate = displayModel.defaultTemplate.alias; - saveModel.groups = _.map(displayModel.groups, function (g) { + saveModel.defaultTemplate = displayModel.defaultTemplate ? displayModel.defaultTemplate.alias : null; + var realGroups = _.reject(displayModel.groups, function(g) { + //do not include these tabs + return g.tabState === "init"; + }); + saveModel.groups = _.map(realGroups, function (g) { var saveGroup = _.pick(g, 'inherited', 'id', 'sortOrder', 'name'); var saveProperties = _.map(g.properties, function(p) { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less index 82ce0b412f..a11278722e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-group-builder.less @@ -123,7 +123,7 @@ input.umb-group-builder__group-title-input { } .umb-group-builder__group-title-input.-placeholder { - border: 1px dashed #979797 !important; + border: 1px dashed #979797; } .umb-group-builder__group-inherited-label { diff --git a/src/Umbraco.Web.UI.Client/src/less/mixins.less b/src/Umbraco.Web.UI.Client/src/less/mixins.less index bf2d75e888..38df48a457 100644 --- a/src/Umbraco.Web.UI.Client/src/less/mixins.less +++ b/src/Umbraco.Web.UI.Client/src/less/mixins.less @@ -190,6 +190,18 @@ background-color: @backgroundColor; border-color: @textColor; } + //SD: We could do this but need to get the colors right + /*input.ng-invalid { + &:-moz-placeholder { + color: lighten(@textColor, 50%) !important; + } + &:-ms-input-placeholder { + color: lighten(@textColor, 50%) !important; + } + &::-webkit-input-placeholder { + color: lighten(@textColor, 50%) !important; + } + }*/ } // CSS3 PROPERTIES diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js index 3723a0ccd5..3de552eccc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js @@ -9,7 +9,7 @@ (function() { "use strict"; - function DocumentTypeEditController($scope, $routeParams, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q) { + function DocumentTypesEditController($scope, $routeParams, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q) { var vm = this; @@ -179,10 +179,15 @@ statusMessage: "Saving...", saveMethod: contentTypeResource.save, scope: $scope, - content: vm.contentType + content: vm.contentType, + rebindCallback: function (origContent, savedContent) { + //This is called when the data returns and we need to merge the property values from the saved content to the original content. + //re-binds all changed property values to the origContent object from the savedContent object and returns an array of changed properties. + + } }).then(function (data) { //success - syncTreeNode(vm.contentType, dt.path); + syncTreeNode(vm.contentType, data.path); vm.page.saveButtonState = "success"; diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs index 74d5c96236..3c7f0d7022 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs @@ -86,32 +86,7 @@ namespace Umbraco.Web.Models.Mapping } }); - config.CreateMap() - .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) - .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) - .ForMember(dto => dto.ListViewEditorName, expression => expression.Ignore()) - .ForMember(dto => dto.AvailableCompositeContentTypes, expression => expression.Ignore()) - .ForMember(dto => dto.Notifications, expression => expression.Ignore()) - .ForMember(dto => dto.Errors, expression => expression.Ignore()) - .AfterMap((source, dest) => - { - //sync templates - dest.AllowedTemplates = source.AllowedTemplates.Select(Mapper.Map); - - if (source.DefaultTemplate.IsNullOrWhiteSpace() == false) - { - //if the dest is set and it's the same as the source, then don't change - if (dest.DefaultTemplate == null || source.DefaultTemplate != dest.DefaultTemplate.Alias) - { - var template = applicationContext.Services.FileService.GetTemplate(source.DefaultTemplate); - dest.DefaultTemplate = template == null ? null : Mapper.Map(template); - } - } - else - { - dest.DefaultTemplate = null; - } - }); + //config.CreateMap() // //do the base mapping @@ -218,22 +193,6 @@ namespace Umbraco.Web.Models.Mapping config.CreateMap(); config.CreateMap(); - - config.CreateMap, PropertyGroup>() - .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0)) - .ForMember(g => g.Key, 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)) - //.ForMember(g => g.ParentId, expression => expression.MapFrom(display => display.ParentGroupId)) - //ignore these, this is handled with IContentType.AddPropertyType - .ForMember(g => g.PropertyTypes, expression => expression.MapFrom(display => display.Properties.Select(Mapper.Map))); - - config.CreateMap, PropertyGroupDisplay>() - .ForMember(g => g.Properties, expression => expression.MapFrom(display => display.Properties.Select(Mapper.Map))); - config.CreateMap() .ConstructUsing((PropertyTypeBasic propertyTypeBasic) => @@ -263,7 +222,70 @@ namespace Umbraco.Web.Models.Mapping .ForMember(type => type.DataTypeDefinitionId, expression => expression.MapFrom(display => display.DataTypeId)) .ForMember(type => type.Name, expression => expression.MapFrom(display => display.Label)); - config.CreateMap(); + #region *** Used for mapping on top of an existing display object from a save object *** + + config.CreateMap() + .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) + .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) + .ForMember(dto => dto.ListViewEditorName, expression => expression.Ignore()) + .ForMember(dto => dto.AvailableCompositeContentTypes, expression => expression.Ignore()) + .ForMember(dto => dto.Notifications, expression => expression.Ignore()) + .ForMember(dto => dto.Errors, expression => expression.Ignore()) + .AfterMap((source, dest) => + { + //sync templates + var destAllowedTemplateAliases = dest.AllowedTemplates.Select(x => x.Alias); + //if the dest is set and it's the same as the source, then don't change + if (destAllowedTemplateAliases.SequenceEqual(source.AllowedTemplates) == false) + { + var templates = applicationContext.Services.FileService.GetTemplates(source.AllowedTemplates.ToArray()); + dest.AllowedTemplates = source.AllowedTemplates.Select(x => Mapper.Map(templates.Single(t => t.Alias == x))); + } + + if (source.DefaultTemplate.IsNullOrWhiteSpace() == false) + { + //if the dest is set and it's the same as the source, then don't change + if (dest.DefaultTemplate == null || source.DefaultTemplate != dest.DefaultTemplate.Alias) + { + var template = applicationContext.Services.FileService.GetTemplate(source.DefaultTemplate); + dest.DefaultTemplate = template == null ? null : Mapper.Map(template); + } + } + else + { + dest.DefaultTemplate = null; + } + }); + + config.CreateMap, PropertyGroup>() + .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0)) + .ForMember(g => g.Key, expression => expression.Ignore()) + .ForMember(g => g.HasIdentity, expression => expression.Ignore()) + .ForMember(dto => dto.CreateDate, expression => expression.Ignore()) + .ForMember(dto => dto.UpdateDate, expression => expression.Ignore()) + .ForMember(g => g.ParentId, expression => expression.Ignore()) + .ForMember(g => g.PropertyTypes, expression => expression.MapFrom(basic => basic.Properties.Select(Mapper.Map))); + + config.CreateMap, PropertyGroupDisplay>() + .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0)) + .ForMember(g => g.ParentGroupId, expression => expression.Ignore()) + .ForMember(g => g.ContentTypeId, expression => expression.Ignore()) + .ForMember(g => g.ParentTabContentTypes, expression => expression.Ignore()) + .ForMember(g => g.ParentTabContentTypeNames, expression => expression.Ignore()) + .ForMember(g => g.Properties, expression => expression.MapFrom(display => display.Properties.Select(Mapper.Map))); + + config.CreateMap() + .ForMember(g => g.Editor, expression => expression.Ignore()) + .ForMember(g => g.View, expression => expression.Ignore()) + .ForMember(g => g.Config, expression => expression.Ignore()) + .ForMember(g => g.ContentTypeId, expression => expression.Ignore()) + .ForMember(g => g.ContentTypeName, expression => expression.Ignore()); + + #endregion + + + + } diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index baac1109e4..48486fd676 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; using System.Linq; +using System.Reflection; using System.Web; using System.Web.Configuration; using System.Web.Http; @@ -103,10 +104,10 @@ namespace Umbraco.Web public override IBootManager Initialize() { //This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976 - // when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's - // event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build - // it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the - // boot process has completed. It's a hack but it works. + // when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's + // event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build + // it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the + // boot process has completed. It's a hack but it works. ExamineManager.Instance.BuildingEmptyIndexOnStartup += OnInstanceOnBuildingEmptyIndexOnStartup; base.Initialize();