Fixes mapping tests, simplifies property group mappings, adds another test to test composition mappings.
This commit is contained in:
@@ -227,17 +227,7 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
.Returns(new[] { new TextboxPropertyEditor() });
|
||||
|
||||
var contentType = MockedContentTypes.CreateTextpageContentType();
|
||||
//ensure everything has ids
|
||||
contentType.Id = 1234;
|
||||
var itemid = 8888;
|
||||
foreach (var propertyGroup in contentType.CompositionPropertyGroups)
|
||||
{
|
||||
propertyGroup.Id = itemid++;
|
||||
}
|
||||
foreach (var propertyType in contentType.CompositionPropertyTypes)
|
||||
{
|
||||
propertyType.Id = itemid++;
|
||||
}
|
||||
MockedContentTypes.EnsureAllIds(contentType, 8888);
|
||||
|
||||
//Act
|
||||
|
||||
@@ -289,6 +279,94 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IContentTypeComposition_To_ContentTypeDisplay()
|
||||
{
|
||||
//Arrange
|
||||
|
||||
// setup the mocks to return the data we want to test against...
|
||||
|
||||
// for any call to GetPreValuesCollectionByDataTypeId just return an empty dictionary for now
|
||||
// TODO: but we'll need to change this to return some pre-values to test the mappings
|
||||
_dataTypeService.Setup(x => x.GetPreValuesCollectionByDataTypeId(It.IsAny<int>()))
|
||||
.Returns(new PreValueCollection(new Dictionary<string, PreValue>()));
|
||||
|
||||
//return a textbox property editor for any requested editor by alias
|
||||
_propertyEditorResolver.Setup(resolver => resolver.GetByAlias(It.IsAny<string>()))
|
||||
.Returns(new TextboxPropertyEditor());
|
||||
//for testing, just return a list of whatever property editors we want
|
||||
_propertyEditorResolver.Setup(resolver => resolver.PropertyEditors)
|
||||
.Returns(new[] { new TextboxPropertyEditor() });
|
||||
|
||||
var ctMain = MockedContentTypes.CreateSimpleContentType();
|
||||
//not assigned to tab
|
||||
ctMain.AddPropertyType(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext)
|
||||
{
|
||||
Alias = "umbracoUrlName", Name = "Slug", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88
|
||||
});
|
||||
MockedContentTypes.EnsureAllIds(ctMain, 8888);
|
||||
var ctChild1 = MockedContentTypes.CreateSimpleContentType("child1", "Child 1", ctMain, true);
|
||||
MockedContentTypes.EnsureAllIds(ctChild1, 7777);
|
||||
var contentType = MockedContentTypes.CreateSimpleContentType("child2", "Child 2", ctChild1, true, "CustomGroup");
|
||||
//not assigned to tab
|
||||
contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext)
|
||||
{
|
||||
Alias = "umbracoUrlAlias", Name = "AltUrl", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88
|
||||
});
|
||||
MockedContentTypes.EnsureAllIds(contentType, 6666);
|
||||
|
||||
|
||||
//Act
|
||||
|
||||
var result = Mapper.Map<ContentTypeDisplay>(contentType);
|
||||
|
||||
//Assert
|
||||
|
||||
Assert.AreEqual(contentType.Alias, result.Alias);
|
||||
Assert.AreEqual(contentType.Description, result.Description);
|
||||
Assert.AreEqual(contentType.Icon, result.Icon);
|
||||
Assert.AreEqual(contentType.Id, result.Id);
|
||||
Assert.AreEqual(contentType.Name, result.Name);
|
||||
Assert.AreEqual(contentType.ParentId, result.ParentId);
|
||||
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(contentType.CompositionPropertyGroups.Select(x => x.Name).Distinct().Count(), result.Groups.Count(x => x.Id != -666));
|
||||
Assert.AreEqual(1, result.Groups.Count(x => x.Id == -666));
|
||||
Assert.AreEqual(contentType.PropertyGroups.Count(), result.Groups.Count(x => x.Inherited == false && x.Id != -666));
|
||||
|
||||
var allPropertiesMapped = result.Groups.SelectMany(x => x.Properties).ToArray();
|
||||
var allPropertyIdsMapped = allPropertiesMapped.Select(x => x.Id).ToArray();
|
||||
var allSourcePropertyIds = contentType.CompositionPropertyTypes.Select(x => x.Id).ToArray();
|
||||
|
||||
Assert.AreEqual(contentType.PropertyTypes.Count(), allPropertiesMapped.Count(x => x.Inherited == false));
|
||||
Assert.AreEqual(allPropertyIdsMapped.Count(), allSourcePropertyIds.Count());
|
||||
Assert.IsTrue(allPropertyIdsMapped.ContainsAll(allSourcePropertyIds));
|
||||
|
||||
Assert.AreEqual(1, result.Groups.Count(x => x.ParentTabContentTypes.Any()));
|
||||
Assert.IsTrue(result.Groups.SelectMany(x => x.ParentTabContentTypes).ContainsAll(new[] {ctMain.Id, ctChild1.Id}));
|
||||
|
||||
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()
|
||||
{
|
||||
return new ContentTypeDisplay
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
@@ -181,11 +182,24 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.TinyMCEAlias, DataTypeDatabaseType.Ntext) { Alias = RandomAlias("bodyText", randomizeAliases), Name = "Body Text", Description = "", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -87 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = RandomAlias("author", randomizeAliases) , Name = "Author", Description = "Name of the author", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88 });
|
||||
|
||||
contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = propertyGroupName, SortOrder = 1 });
|
||||
var pg = new PropertyGroup(contentCollection) {Name = propertyGroupName, SortOrder = 1};
|
||||
contentType.PropertyGroups.Add(pg);
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
var foundPg = parent.PropertyGroups.FirstOrDefault(x => x.Name == propertyGroupName);
|
||||
if (foundPg != null)
|
||||
{
|
||||
//this exists on the parent, so set the parent id
|
||||
pg.ParentId = foundPg.Id;
|
||||
}
|
||||
}
|
||||
|
||||
//ensure that nothing is marked as dirty
|
||||
contentType.ResetDirtyProperties(false);
|
||||
|
||||
contentType.SetDefaultTemplate(new Template("Textpage", "textpage"));
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@@ -399,6 +413,21 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public static void EnsureAllIds(ContentType contentType, int seedId)
|
||||
{
|
||||
//ensure everything has ids
|
||||
contentType.Id = seedId;
|
||||
var itemid = seedId + 1;
|
||||
foreach (var propertyGroup in contentType.PropertyGroups)
|
||||
{
|
||||
propertyGroup.Id = itemid++;
|
||||
}
|
||||
foreach (var propertyType in contentType.PropertyTypes)
|
||||
{
|
||||
propertyType.Id = itemid++;
|
||||
}
|
||||
}
|
||||
|
||||
private static string RandomAlias(string alias, bool randomizeAliases)
|
||||
{
|
||||
if (randomizeAliases)
|
||||
|
||||
@@ -126,6 +126,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
|
||||
config.CreateMap<IContentType, ContentTypeDisplay>()
|
||||
.ForMember(display => display.AllowAsRoot, expression => expression.MapFrom(type => type.AllowedAsRoot))
|
||||
.ForMember(display => display.ListViewEditorName, expression => expression.Ignore())
|
||||
//Ignore because this is not actually used for content types
|
||||
.ForMember(display => display.Trashed, expression => expression.Ignore())
|
||||
|
||||
|
||||
@@ -34,20 +34,28 @@ namespace Umbraco.Web.Models.Mapping
|
||||
Constants.System.DefaultMembersListViewDataTypeId
|
||||
};
|
||||
|
||||
config.CreateMap<PropertyEditor, DataTypeBasic>();
|
||||
config.CreateMap<PropertyEditor, DataTypeBasic>()
|
||||
.ForMember(x => x.IsSystemDataType, expression => expression.Ignore())
|
||||
.ForMember(x => x.Id, expression => expression.Ignore())
|
||||
.ForMember(x => x.Trashed, expression => expression.Ignore())
|
||||
.ForMember(x => x.Key, expression => expression.Ignore())
|
||||
.ForMember(x => x.ParentId, expression => expression.Ignore())
|
||||
.ForMember(x => x.Path, expression => expression.Ignore())
|
||||
.ForMember(x => x.AdditionalData, expression => expression.Ignore());
|
||||
|
||||
config.CreateMap<IDataTypeDefinition, DataTypeBasic>()
|
||||
.ForMember(x => x.Icon, expression => expression.Ignore())
|
||||
.ForMember(x => x.Alias, expression => expression.Ignore())
|
||||
.ForMember(x => x.Group, expression => expression.Ignore())
|
||||
.ForMember(x => x.IsSystemDataType, expression => expression.MapFrom(definition => systemIds.Contains(definition.Id)))
|
||||
.AfterMap( (def,basic) =>
|
||||
.AfterMap((def, basic) =>
|
||||
{
|
||||
var editor = PropertyEditorResolver.Current.GetByAlias(def.PropertyEditorAlias);
|
||||
if(editor != null){
|
||||
if (editor != null)
|
||||
{
|
||||
basic.Group = editor.Group;
|
||||
basic.Icon = editor.Icon;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
config.CreateMap<IDataTypeDefinition, DataTypeDisplay>()
|
||||
@@ -59,7 +67,17 @@ namespace Umbraco.Web.Models.Mapping
|
||||
.ForMember(x => x.Notifications, expression => expression.Ignore())
|
||||
.ForMember(x => x.Icon, expression => expression.Ignore())
|
||||
.ForMember(x => x.Alias, expression => expression.Ignore())
|
||||
.ForMember(x => x.IsSystemDataType, expression => expression.MapFrom(definition => systemIds.Contains(definition.Id)));
|
||||
.ForMember(x => x.Group, expression => expression.Ignore())
|
||||
.ForMember(x => x.IsSystemDataType, expression => expression.MapFrom(definition => systemIds.Contains(definition.Id)))
|
||||
.AfterMap((def, basic) =>
|
||||
{
|
||||
var editor = PropertyEditorResolver.Current.GetByAlias(def.PropertyEditorAlias);
|
||||
if (editor != null)
|
||||
{
|
||||
basic.Group = editor.Group;
|
||||
basic.Icon = editor.Icon;
|
||||
}
|
||||
});
|
||||
|
||||
//gets a list of PreValueFieldDisplay objects from the data type definition
|
||||
config.CreateMap<IDataTypeDefinition, IEnumerable<PreValueFieldDisplay>>()
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace Umbraco.Web.Models.Mapping
|
||||
//only map id if set to something higher then zero
|
||||
.ForMember(dto => dto.Id, expression => expression.Condition(display => (Convert.ToInt32(display.Id) > 0)))
|
||||
.ForMember(dto => dto.Id, expression => expression.MapFrom(display => Convert.ToInt32(display.Id)))
|
||||
.ForMember(dto => dto.AllowedAsRoot, expression => expression.Ignore())
|
||||
.ForMember(dto => dto.IsContainer, expression => expression.Ignore())
|
||||
.ForMember(dto => dto.CreatorId, expression => expression.Ignore())
|
||||
.ForMember(dto => dto.Level, expression => expression.Ignore())
|
||||
.ForMember(dto => dto.SortOrder, expression => expression.Ignore())
|
||||
|
||||
@@ -1,180 +1,190 @@
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
|
||||
|
||||
internal class PropertyTypeGroupResolver : ValueResolver<IContentTypeComposition, IEnumerable<PropertyGroupDisplay>>
|
||||
{
|
||||
private readonly ApplicationContext _applicationContext;
|
||||
private readonly Lazy<PropertyEditorResolver> _propertyEditorResolver;
|
||||
|
||||
public PropertyTypeGroupResolver(ApplicationContext applicationContext, Lazy<PropertyEditorResolver> propertyEditorResolver)
|
||||
{
|
||||
_applicationContext = applicationContext;
|
||||
_propertyEditorResolver = propertyEditorResolver;
|
||||
}
|
||||
|
||||
|
||||
protected override IEnumerable<PropertyGroupDisplay> ResolveCore(IContentTypeComposition source)
|
||||
{
|
||||
var groups = new Dictionary<int,PropertyGroupDisplay>();
|
||||
|
||||
//for storing generic properties
|
||||
var genericProperties = new List<PropertyTypeDisplay>();
|
||||
|
||||
|
||||
//iterate through all composite types
|
||||
foreach (var ct in source.ContentTypeComposition)
|
||||
{
|
||||
//process each tab
|
||||
foreach(var tab in ct.CompositionPropertyGroups){
|
||||
var group = new PropertyGroupDisplay() { Id = tab.Id, Inherited = true, Name = tab.Name, SortOrder = tab.SortOrder };
|
||||
group.ContentTypeId = ct.Id;
|
||||
group.ParentTabContentTypes = new[] { ct.Id };
|
||||
group.ParentTabContentTypeNames = new[] { ct.Name };
|
||||
|
||||
if (tab.ParentId.HasValue)
|
||||
group.ParentGroupId = tab.ParentId.Value;
|
||||
|
||||
group.Properties = MapProperties(tab.PropertyTypes, ct, tab.Id, true);
|
||||
groups.Add(tab.Id, group);
|
||||
}
|
||||
|
||||
//process inherited generic properties
|
||||
var inheritedGenProperties = ct.CompositionPropertyTypes.Where(x => x.PropertyGroupId == null);
|
||||
if (inheritedGenProperties.Any())
|
||||
genericProperties.AddRange(MapProperties(inheritedGenProperties, ct, 0, true));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//pull from own groups
|
||||
foreach (var ownTab in source.CompositionPropertyGroups)
|
||||
{
|
||||
PropertyGroupDisplay group;
|
||||
|
||||
//if already added
|
||||
if (groups.ContainsKey(ownTab.Id))
|
||||
group = groups[ownTab.Id];
|
||||
|
||||
//if parent
|
||||
else if (ownTab.ParentId.HasValue && groups.ContainsKey(ownTab.ParentId.Value))
|
||||
group = groups[ownTab.ParentId.Value];
|
||||
|
||||
else
|
||||
{
|
||||
//if own
|
||||
group = new PropertyGroupDisplay() { Id = ownTab.Id, Inherited = false, Name = ownTab.Name, SortOrder = ownTab.SortOrder, ContentTypeId = source.Id };
|
||||
groups.Add(ownTab.Id, group);
|
||||
}
|
||||
|
||||
//merge the properties
|
||||
var mergedProperties = new List<PropertyTypeDisplay>();
|
||||
mergedProperties.AddRange(group.Properties);
|
||||
|
||||
var newproperties = MapProperties( ownTab.PropertyTypes , source, ownTab.Id, false).Where(x => mergedProperties.Any( y => y.Id == x.Id ) == false);
|
||||
mergedProperties.AddRange(newproperties);
|
||||
|
||||
group.Properties = mergedProperties.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
|
||||
//get all generic properties not already mapped to the generic props collection
|
||||
var ownGenericProperties = source.CompositionPropertyTypes.Where(x => x.PropertyGroupId == null && !genericProperties.Any(y => y.Id == x.Id));
|
||||
genericProperties.AddRange(MapProperties(ownGenericProperties, source, 0, false));
|
||||
|
||||
if (genericProperties.Any())
|
||||
{
|
||||
var genericTab = new PropertyGroupDisplay() { Id = -666, Name = "Generic properties", ParentGroupId = 0, ContentTypeId = source.Id, SortOrder = 999, Inherited = false };
|
||||
genericTab.Properties = genericProperties;
|
||||
groups.Add(0, genericTab);
|
||||
}
|
||||
|
||||
|
||||
//merge tabs based on names (magic and insanity)
|
||||
var nameGroupedGroups = groups.Values.GroupBy(x => x.Name);
|
||||
if (nameGroupedGroups.Any(x => x.Count() > 1))
|
||||
{
|
||||
var sortedGroups = new List<PropertyGroupDisplay>();
|
||||
|
||||
foreach (var groupOfGroups in nameGroupedGroups)
|
||||
{
|
||||
//single name groups
|
||||
if(groupOfGroups.Count() == 1)
|
||||
sortedGroups.Add(groupOfGroups.First());
|
||||
else{
|
||||
//multiple name groups
|
||||
|
||||
//find the mother tab - if we have our own use it. otherwise pick a random inherited one - since it wont matter
|
||||
var mainTab = groupOfGroups.FirstOrDefault(x => x.Inherited == false);
|
||||
if (mainTab == null)
|
||||
mainTab = groupOfGroups.First();
|
||||
|
||||
|
||||
//take all properties from all the other tabs and merge into one tab
|
||||
var properties = new List<PropertyTypeDisplay>();
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
|
||||
|
||||
internal class PropertyTypeGroupResolver : ValueResolver<IContentTypeComposition, IEnumerable<PropertyGroupDisplay>>
|
||||
{
|
||||
private readonly ApplicationContext _applicationContext;
|
||||
private readonly Lazy<PropertyEditorResolver> _propertyEditorResolver;
|
||||
|
||||
public PropertyTypeGroupResolver(ApplicationContext applicationContext, Lazy<PropertyEditorResolver> propertyEditorResolver)
|
||||
{
|
||||
_applicationContext = applicationContext;
|
||||
_propertyEditorResolver = propertyEditorResolver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will recursively check all compositions (of compositions) to find the content type that contains the
|
||||
/// tabId being searched for.
|
||||
/// </summary>
|
||||
/// <param name="ct"></param>
|
||||
/// <param name="tabId"></param>
|
||||
/// <returns></returns>
|
||||
private IContentTypeComposition GetContentTypeFromTabId(IContentTypeComposition ct, int tabId)
|
||||
{
|
||||
if (ct.PropertyGroups.Any(x => x.Id == tabId)) return ct;
|
||||
|
||||
foreach (var composition in ct.ContentTypeComposition)
|
||||
{
|
||||
var found = GetContentTypeFromTabId(composition, tabId);
|
||||
if (found != null) return found;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override IEnumerable<PropertyGroupDisplay> ResolveCore(IContentTypeComposition source)
|
||||
{
|
||||
var groups = new Dictionary<int,PropertyGroupDisplay>();
|
||||
|
||||
//for storing generic properties
|
||||
var genericProperties = new List<PropertyTypeDisplay>();
|
||||
|
||||
//add groups directly assigned to this content type
|
||||
foreach (var tab in source.PropertyGroups)
|
||||
{
|
||||
var group = new PropertyGroupDisplay()
|
||||
{
|
||||
Id = tab.Id, Inherited = false, Name = tab.Name, SortOrder = tab.SortOrder, ContentTypeId = source.Id
|
||||
};
|
||||
group.Properties = MapProperties(tab.PropertyTypes, source, tab.Id, false);
|
||||
groups.Add(tab.Id, group);
|
||||
}
|
||||
|
||||
//add groups not assigned to this content type (via compositions)
|
||||
foreach (var tab in source.CompositionPropertyGroups)
|
||||
{
|
||||
if (groups.ContainsKey(tab.Id)) continue;
|
||||
|
||||
var composition = GetContentTypeFromTabId(source, tab.Id);
|
||||
if (composition == null)
|
||||
throw new InvalidOperationException("The tabId " + tab.Id + " was not found on any of the content type's compositions");
|
||||
|
||||
var group = new PropertyGroupDisplay()
|
||||
{
|
||||
Id = tab.Id, Inherited = false, Name = tab.Name, SortOrder = tab.SortOrder, ContentTypeId = composition.Id,
|
||||
ParentTabContentTypes = new[] {composition.Id},
|
||||
ParentTabContentTypeNames = new[] {composition.Name}
|
||||
};
|
||||
|
||||
if (tab.ParentId.HasValue)
|
||||
group.ParentGroupId = tab.ParentId.Value;
|
||||
|
||||
group.Properties = MapProperties(tab.PropertyTypes, composition, tab.Id, true);
|
||||
groups.Add(tab.Id, group);
|
||||
}
|
||||
|
||||
//process generic properties assigned to this content item (without a group)
|
||||
|
||||
//NOTE: -666 is just a thing that is checked for on the front-end... I'm not a fan of this for the mapping
|
||||
// since this is just for front-end, this could probably be updated to be -666 in the controller which is associated
|
||||
// with giving the front-end it's data
|
||||
|
||||
var entityGenericProperties = source.PropertyTypes.Where(x => x.PropertyGroupId == null);
|
||||
genericProperties.AddRange(MapProperties(entityGenericProperties, source, -666, false));
|
||||
|
||||
//process generic properties from compositions (ensures properties are flagged as inherited)
|
||||
var currentGenericPropertyIds = genericProperties.Select(x => x.Id).ToArray();
|
||||
var compositionGenericProperties = source.CompositionPropertyTypes
|
||||
.Where(x => x.PropertyGroupId == null && currentGenericPropertyIds.Contains(x.Id) == false);
|
||||
genericProperties.AddRange(MapProperties(compositionGenericProperties, source, -666, true));
|
||||
|
||||
//now add the group if there are any generic props
|
||||
if (genericProperties.Any())
|
||||
{
|
||||
var genericTab = new PropertyGroupDisplay
|
||||
{
|
||||
Id = -666, Name = "Generic properties", ParentGroupId = 0, ContentTypeId = source.Id, SortOrder = 999, Inherited = false, Properties = genericProperties
|
||||
};
|
||||
groups.Add(0, genericTab);
|
||||
}
|
||||
|
||||
|
||||
//merge tabs based on names (magic and insanity)
|
||||
var nameGroupedGroups = groups.Values.GroupBy(x => x.Name).ToArray();
|
||||
if (nameGroupedGroups.Any(x => x.Count() > 1))
|
||||
{
|
||||
var sortedGroups = new List<PropertyGroupDisplay>();
|
||||
|
||||
foreach (var groupOfGroups in nameGroupedGroups)
|
||||
{
|
||||
//single name groups
|
||||
if (groupOfGroups.Count() == 1)
|
||||
{
|
||||
sortedGroups.Add(groupOfGroups.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
//multiple name groups
|
||||
|
||||
//find the mother tab - if we have our own use it. otherwise pick a random inherited one - since it wont matter
|
||||
var mainTab = groupOfGroups.FirstOrDefault(x => x.Inherited == false) ?? groupOfGroups.First();
|
||||
|
||||
//take all properties from all the other tabs and merge into one tab
|
||||
var properties = new List<PropertyTypeDisplay>();
|
||||
properties.AddRange(groupOfGroups.Where(x => x.Id != mainTab.Id).SelectMany(x => x.Properties));
|
||||
properties.AddRange(mainTab.Properties);
|
||||
mainTab.Properties = properties;
|
||||
|
||||
//lock the tab
|
||||
mainTab.Inherited = true;
|
||||
|
||||
properties.AddRange(mainTab.Properties);
|
||||
mainTab.Properties = properties;
|
||||
|
||||
//lock the tab
|
||||
mainTab.Inherited = true;
|
||||
|
||||
//collect all the involved content types
|
||||
var parents = groupOfGroups.Where(x => x.ContentTypeId != source.Id).ToList();
|
||||
mainTab.ParentTabContentTypes = parents.Select(x => x.ContentTypeId);
|
||||
mainTab.ParentTabContentTypeNames = parents.SelectMany(x => x.ParentTabContentTypeNames);
|
||||
sortedGroups.Add(mainTab);
|
||||
}
|
||||
}
|
||||
|
||||
return sortedGroups.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
|
||||
return groups.Values.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
private IEnumerable<PropertyTypeDisplay> MapProperties(IEnumerable<PropertyType> properties, IContentTypeBase contentType, int groupId, bool inherited)
|
||||
{
|
||||
var mappedProperties = new List<PropertyTypeDisplay>();
|
||||
foreach (var p in properties.Where(x => x.DataTypeDefinitionId != 0) )
|
||||
{
|
||||
var editor = _propertyEditorResolver.Value.GetByAlias(p.PropertyEditorAlias);
|
||||
var preVals = _applicationContext.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(p.DataTypeDefinitionId);
|
||||
|
||||
mappedProperties.Add(
|
||||
new PropertyTypeDisplay()
|
||||
{
|
||||
Id = p.Id,
|
||||
Alias = p.Alias,
|
||||
Description = p.Description,
|
||||
Editor = p.PropertyEditorAlias,
|
||||
Validation = new PropertyTypeValidation() { Mandatory = p.Mandatory, Pattern = p.ValidationRegExp },
|
||||
Label = p.Name,
|
||||
View = editor.ValueEditor.View,
|
||||
Config = editor.PreValueEditor.ConvertDbToEditor(editor.DefaultPreValues, preVals) ,
|
||||
Value = "",
|
||||
ContentTypeId = contentType.Id,
|
||||
ContentTypeName = contentType.Name,
|
||||
GroupId = groupId,
|
||||
Inherited = inherited,
|
||||
DataTypeId = p.DataTypeDefinitionId,
|
||||
SortOrder = p.SortOrder
|
||||
});
|
||||
}
|
||||
|
||||
return mappedProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
mainTab.ParentTabContentTypes = parents.SelectMany(x => x.ParentTabContentTypes).ToArray();
|
||||
mainTab.ParentTabContentTypeNames = parents.SelectMany(x => x.ParentTabContentTypeNames).ToArray();
|
||||
sortedGroups.Add(mainTab);
|
||||
}
|
||||
}
|
||||
|
||||
return sortedGroups.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
|
||||
return groups.Values.OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
private IEnumerable<PropertyTypeDisplay> MapProperties(IEnumerable<PropertyType> properties, IContentTypeBase contentType, int groupId, bool inherited)
|
||||
{
|
||||
var mappedProperties = new List<PropertyTypeDisplay>();
|
||||
foreach (var p in properties.Where(x => x.DataTypeDefinitionId != 0) )
|
||||
{
|
||||
var editor = _propertyEditorResolver.Value.GetByAlias(p.PropertyEditorAlias);
|
||||
var preVals = _applicationContext.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(p.DataTypeDefinitionId);
|
||||
|
||||
mappedProperties.Add(
|
||||
new PropertyTypeDisplay()
|
||||
{
|
||||
Id = p.Id,
|
||||
Alias = p.Alias,
|
||||
Description = p.Description,
|
||||
Editor = p.PropertyEditorAlias,
|
||||
Validation = new PropertyTypeValidation() { Mandatory = p.Mandatory, Pattern = p.ValidationRegExp },
|
||||
Label = p.Name,
|
||||
View = editor.ValueEditor.View,
|
||||
Config = editor.PreValueEditor.ConvertDbToEditor(editor.DefaultPreValues, preVals) ,
|
||||
Value = "",
|
||||
ContentTypeId = contentType.Id,
|
||||
ContentTypeName = contentType.Name,
|
||||
GroupId = groupId,
|
||||
Inherited = inherited,
|
||||
DataTypeId = p.DataTypeDefinitionId,
|
||||
SortOrder = p.SortOrder
|
||||
});
|
||||
}
|
||||
|
||||
return mappedProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user