diff --git a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs index fd475c558a..37f1e5127f 100644 --- a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs @@ -37,12 +37,14 @@ namespace Umbraco.Core.Services /// This is required because in the case of creating/modifying a content type because new property types being added to it are not yet persisted so cannot /// be looked up via the db, they need to be passed in. /// + /// Wether the composite content types should be applicable for an element type /// internal static ContentTypeAvailableCompositionsResults GetAvailableCompositeContentTypes(this IContentTypeService ctService, IContentTypeComposition source, IContentTypeComposition[] allContentTypes, string[] filterContentTypes = null, - string[] filterPropertyTypes = null) + string[] filterPropertyTypes = null, + bool isElement = false) { filterContentTypes = filterContentTypes == null ? Array.Empty() @@ -61,7 +63,7 @@ namespace Umbraco.Core.Services .Select(c => c.Alias) .Union(filterPropertyTypes) .ToArray(); - + var sourceId = source?.Id ?? 0; // find out if any content type uses this content type @@ -79,8 +81,9 @@ namespace Umbraco.Core.Services x => x.Id)); // usable types are those that are top-level + // do not allow element types to be composed by non-element types as this will break the model generation in ModelsBuilder var usableContentTypes = allContentTypes - .Where(x => x.ContentTypeComposition.Any() == false).ToArray(); + .Where(x => x.ContentTypeComposition.Any() == false && (isElement == false || x.IsElement)).ToArray(); foreach (var x in usableContentTypes) list.Add(x); 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 7c4af11022..ba479429f1 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 @@ -257,7 +257,7 @@ view: "views/common/infiniteeditors/compositions/compositions.html", size: "small", submit: function() { - + // make sure that all tabs has an init property if (scope.model.groups.length !== 0) { angular.forEach(scope.model.groups, function(group) { @@ -341,7 +341,7 @@ scope.compositionsButtonState = "busy"; $q.all([ //get available composite types - availableContentTypeResource(scope.model.id, [], propAliasesExisting).then(function (result) { + availableContentTypeResource(scope.model.id, [], propAliasesExisting, scope.model.isElement).then(function (result) { setupAvailableContentTypesModel(result); }), //get where used document types diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js index 4e4c8d2eb5..64accc18c1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js @@ -16,7 +16,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca 'Failed to retrieve count'); }, - getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes) { + getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes, isElement) { if (!filterContentTypes) { filterContentTypes = []; } @@ -27,7 +27,8 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca var query = { contentTypeId: contentTypeId, filterContentTypes: filterContentTypes, - filterPropertyTypes: filterPropertyTypes + filterPropertyTypes: filterPropertyTypes, + isElement: isElement }; return umbRequestHelper.resourcePromise( diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index cf8b6c3859..e99cbdca4a 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -132,7 +132,7 @@ namespace Umbraco.Web.Editors [HttpPost] public HttpResponseMessage GetAvailableCompositeContentTypes(GetAvailableCompositionsFilter filter) { - var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.DocumentType, filter.FilterContentTypes, filter.FilterPropertyTypes) + var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.DocumentType, filter.FilterContentTypes, filter.FilterPropertyTypes, filter.IsElement) .Select(x => new { contentType = x.Item1, diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index 9b8a098e21..2b3990c7a1 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -53,11 +53,13 @@ namespace Umbraco.Web.Editors /// be looked up via the db, they need to be passed in. /// /// + /// Wether the composite content types should be applicable for an element type /// protected IEnumerable> PerformGetAvailableCompositeContentTypes(int contentTypeId, UmbracoObjectTypes type, string[] filterContentTypes, - string[] filterPropertyTypes) + string[] filterPropertyTypes, + bool isElement) { IContentTypeComposition source = null; @@ -98,7 +100,7 @@ namespace Umbraco.Web.Editors throw new ArgumentOutOfRangeException("The entity type was not a content type"); } - var availableCompositions = Services.ContentTypeService.GetAvailableCompositeContentTypes(source, allContentTypes, filterContentTypes, filterPropertyTypes); + var availableCompositions = Services.ContentTypeService.GetAvailableCompositeContentTypes(source, allContentTypes, filterContentTypes, filterPropertyTypes, isElement); diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index 24d8f696b6..43569c77e2 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -110,7 +110,7 @@ namespace Umbraco.Web.Editors [HttpPost] public HttpResponseMessage GetAvailableCompositeMediaTypes(GetAvailableCompositionsFilter filter) { - var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.MediaType, filter.FilterContentTypes, filter.FilterPropertyTypes) + var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.MediaType, filter.FilterContentTypes, filter.FilterPropertyTypes, filter.IsElement) .Select(x => new { contentType = x.Item1, diff --git a/src/Umbraco.Web/Editors/MemberTypeController.cs b/src/Umbraco.Web/Editors/MemberTypeController.cs index f406988ae5..fffead9155 100644 --- a/src/Umbraco.Web/Editors/MemberTypeController.cs +++ b/src/Umbraco.Web/Editors/MemberTypeController.cs @@ -89,7 +89,7 @@ namespace Umbraco.Web.Editors [FromUri]string[] filterContentTypes, [FromUri]string[] filterPropertyTypes) { - var result = PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MemberType, filterContentTypes, filterPropertyTypes) + var result = PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MemberType, filterContentTypes, filterPropertyTypes, false) .Select(x => new { contentType = x.Item1, diff --git a/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs b/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs index 38442f6da5..b1528db697 100644 --- a/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs +++ b/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs @@ -16,5 +16,10 @@ /// along with any content types that have matching property types that are included in the filtered content types /// public string[] FilterContentTypes { get; set; } + + /// + /// Wether the content type is currently marked as an element type + /// + public bool IsElement { get; set; } } }