diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index 75afb33a84..ab3be7aaeb 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -461,6 +461,22 @@ namespace Umbraco.Core.Services } + public int CountContentTypes() + { + using (var repository = RepositoryFactory.CreateContentTypeRepository(UowProvider.GetUnitOfWork())) + { + return repository.Count(Query.Builder); + } + } + + public int CountMediaTypes() + { + using (var repository = RepositoryFactory.CreateMediaTypeRepository(UowProvider.GetUnitOfWork())) + { + return repository.Count(Query.Builder); + } + } + /// /// Validates the composition, if its invalid a list of property type aliases that were duplicated is returned /// diff --git a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs index 6b440c6b2c..d16e7946b9 100644 --- a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs @@ -15,8 +15,6 @@ namespace Umbraco.Core.Services IContentTypeComposition source, IContentTypeComposition[] allContentTypes) { - - if (source == null) throw new ArgumentNullException("source"); //below is all ported from the old doc type editor and comes with the same weaknesses /insanity / magic // note: there are many sanity checks missing here and there ;-(( @@ -24,12 +22,15 @@ namespace Umbraco.Core.Services //if (allContentTypes.Any(x => x.ParentId > 0 && x.ContentTypeComposition.Any(y => y.Id == x.ParentId) == false)) // throw new Exception("A parent does not belong to a composition."); - // find out if any content type uses this content type - var isUsing = allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == source.Id)).ToArray(); - if (isUsing.Length > 0) + if (source != null) { - //if already in use a composition, do not allow any composited types - return new List(); + // find out if any content type uses this content type + var isUsing = allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == source.Id)).ToArray(); + if (isUsing.Length > 0) + { + //if already in use a composition, do not allow any composited types + return new List(); + } } // if it is not used then composition is possible @@ -61,7 +62,7 @@ namespace Umbraco.Core.Services // .ToArray(); return list - .Where(x => x.Id != source.Id) + .Where(x => x.Id != (source != null ? source.Id : 0)) .OrderBy(x => x.Name) .ToList(); } diff --git a/src/Umbraco.Core/Services/IContentTypeService.cs b/src/Umbraco.Core/Services/IContentTypeService.cs index 9e59308a39..2fa92f2311 100644 --- a/src/Umbraco.Core/Services/IContentTypeService.cs +++ b/src/Umbraco.Core/Services/IContentTypeService.cs @@ -11,6 +11,9 @@ namespace Umbraco.Core.Services /// public interface IContentTypeService : IService { + int CountContentTypes(); + int CountMediaTypes(); + /// /// Validates the composition, if its invalid a list of property type aliases that were duplicated is returned /// 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 a514de7ee8..c8ea32110e 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 @@ -1,7 +1,7 @@ (function() { 'use strict'; - function GroupsBuilderDirective(contentTypeHelper, contentTypeResource, mediaTypeResource, dataTypeHelper, dataTypeResource, $filter) { + function GroupsBuilderDirective(contentTypeHelper, contentTypeResource, mediaTypeResource, dataTypeHelper, dataTypeResource, $filter, iconHelper, $q) { function link(scope, el, attr, ctrl) { @@ -155,7 +155,6 @@ scope.compositionsDialogModel = { title: "Compositions", contentType: scope.model, - availableCompositeContentTypes: scope.model.availableCompositeContentTypes, compositeContentTypes: scope.model.compositeContentTypes, view: "views/common/overlays/contenttypeeditor/compositions/compositions.html", confirmSubmit: { @@ -164,7 +163,6 @@ checkboxLabel: "I know what I'm doing", enable: true }, - show: true, submit: function(model, oldModel, confirmed) { var compositionRemoved = false; @@ -242,6 +240,24 @@ } }; + var availableContentTypeResource = scope.contentType === "documentType" ? contentTypeResource.getAvailableCompositeContentTypes : mediaTypeResource.getAvailableCompositeContentTypes; + var countContentTypeResource = scope.contentType === "documentType" ? contentTypeResource.getCount : mediaTypeResource.getCount; + $q.all([ + //get available composite types + availableContentTypeResource(scope.model.id).then(function (result) { + scope.compositionsDialogModel.availableCompositeContentTypes = result; + // convert icons for composite content types + iconHelper.formatContentTypeIcons(scope.compositionsDialogModel.availableCompositeContentTypes); + }), + //get content type count + countContentTypeResource().then(function (result) { + scope.compositionsDialogModel.totalContentTypes = parseInt(result, 10); + }) + ]).then(function () { + //resolves when both other promises are done, now show it + scope.compositionsDialogModel.show = true; + }); + }; 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 4b1ed8f9c1..a59bc83ccb 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 @@ -7,6 +7,15 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { return { + getCount: function () { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "contentTypeApiBaseUrl", + "GetCount")), + 'Failed to retrieve count'); + }, + getAvailableCompositeContentTypes: function (contentTypeId) { return umbRequestHelper.resourcePromise( $http.get( diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js index 555889e5a3..39315c6074 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js @@ -7,6 +7,15 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { return { + getCount: function () { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetCount")), + 'Failed to retrieve count'); + }, + getAvailableCompositeContentTypes: function (contentTypeId) { return umbRequestHelper.resourcePromise( $http.get( diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/contenttypeeditor/compositions/compositions.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/contenttypeeditor/compositions/compositions.html index 3467b8568e..2cdcef5ee6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/contenttypeeditor/compositions/compositions.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/contenttypeeditor/compositions/compositions.html @@ -15,15 +15,20 @@ + There are no content types available to use as a composition. + + This content type is used in a composition, and therefore cannot be composed itself.
    -
  • +
  • -
    +
  • -
+ \ No newline at end of file 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 641ac1c954..bef23de45b 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 @@ -218,13 +218,7 @@ } function init(contentType) { - //get available composite types - contentTypeResource.getAvailableCompositeContentTypes(contentType.id).then(function (result) { - contentType.availableCompositeContentTypes = result; - // convert icons for composite content types - iconHelper.formatContentTypeIcons(contentType.availableCompositeContentTypes); - }); - + // set all tab to inactive if (contentType.groups.length !== 0) { angular.forEach(contentType.groups, function (group) { diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js index bcfb826811..9f366b3e03 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js @@ -168,13 +168,7 @@ } function init(contentType) { - //get available composite types - mediaTypeResource.getAvailableCompositeContentTypes(contentType.id).then(function (result) { - contentType.availableCompositeContentTypes = result; - // convert legacy icons - iconHelper.formatContentTypeIcons(contentType.availableCompositeContentTypes); - }); - + // set all tab to inactive if (contentType.groups.length !== 0) { angular.forEach(contentType.groups, function (group) { diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 4622fee1b5..b70683dd93 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -46,6 +46,10 @@ namespace Umbraco.Web.Editors { } + public int GetCount() + { + return Services.ContentTypeService.CountContentTypes(); + } public ContentTypeDisplay GetById(int id) { diff --git a/src/Umbraco.Web/Editors/DataTypeController.cs b/src/Umbraco.Web/Editors/DataTypeController.cs index c2d7ec37d2..931d00968b 100644 --- a/src/Umbraco.Web/Editors/DataTypeController.cs +++ b/src/Umbraco.Web/Editors/DataTypeController.cs @@ -299,14 +299,16 @@ namespace Umbraco.Web.Editors { var dataTypes = Services.DataTypeService .GetAllDataTypeDefinitions() - .Select(Mapper.Map); + .Select(Mapper.Map) + .ToArray(); var propertyEditors = PropertyEditorResolver.Current.PropertyEditors.ToArray(); foreach (var dataType in dataTypes) { - var propertyEditor = propertyEditors.Single(x => x.Alias == dataType.Alias); - dataType.HasPrevalues = propertyEditor.PreValueEditor.Fields.Any(); ; + var propertyEditor = propertyEditors.SingleOrDefault(x => x.Alias == dataType.Alias); + if(propertyEditor != null) + dataType.HasPrevalues = propertyEditor.PreValueEditor.Fields.Any(); ; } var grouped = dataTypes diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index d54981ff45..f00f10de1e 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -51,6 +51,10 @@ namespace Umbraco.Web.Editors } + public int GetCount() + { + return Services.ContentTypeService.CountContentTypes(); + } public ContentTypeCompositionDisplay GetById(int id) { diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs index e0165450ed..12d08ac683 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs @@ -1,31 +1,26 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace Umbraco.Web.Models.ContentEditing -{ - - [DataContract(Name = "contentType", Namespace = "")] - public class ContentTypeDisplay : ContentTypeCompositionDisplay +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + + [DataContract(Name = "contentType", Namespace = "")] + public class ContentTypeDisplay : ContentTypeCompositionDisplay { - public ContentTypeDisplay() - { - //initialize collections so at least their never null - AllowedTemplates = new List(); - } - - //name, alias, icon, thumb, desc, inherited from the content type - - // Templates - [DataMember(Name = "allowedTemplates")] - public IEnumerable AllowedTemplates { get; set; } - - [DataMember(Name = "defaultTemplate")] - public EntityBasic DefaultTemplate { get; set; } - - } -} + public ContentTypeDisplay() + { + //initialize collections so at least their never null + AllowedTemplates = new List(); + } + + //name, alias, icon, thumb, desc, inherited from the content type + + // Templates + [DataMember(Name = "allowedTemplates")] + public IEnumerable AllowedTemplates { get; set; } + + [DataMember(Name = "defaultTemplate")] + public EntityBasic DefaultTemplate { get; set; } + + } +} diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs index 39f4a57b32..a77125c475 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs @@ -9,6 +9,7 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Web.Models.ContentEditing; using System.Collections.Generic; using AutoMapper.Internal; +using Umbraco.Core.Services; using Property = umbraco.NodeFactory.Property; namespace Umbraco.Web.Models.Mapping @@ -29,7 +30,7 @@ namespace Umbraco.Web.Models.Mapping //ctor can be used for testing public ContentTypeModelMapper(Lazy propertyEditorResolver) { - _propertyEditorResolver = propertyEditorResolver; + _propertyEditorResolver = propertyEditorResolver; } public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext)