@@ -461,6 +461,22 @@ namespace Umbraco.Core.Services
|
||||
|
||||
}
|
||||
|
||||
public int CountContentTypes()
|
||||
{
|
||||
using (var repository = RepositoryFactory.CreateContentTypeRepository(UowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Count(Query<IContentType>.Builder);
|
||||
}
|
||||
}
|
||||
|
||||
public int CountMediaTypes()
|
||||
{
|
||||
using (var repository = RepositoryFactory.CreateMediaTypeRepository(UowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Count(Query<IMediaType>.Builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the composition, if its invalid a list of property type aliases that were duplicated is returned
|
||||
/// </summary>
|
||||
|
||||
@@ -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<IContentTypeComposition>();
|
||||
// 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<IContentTypeComposition>();
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public interface IContentTypeService : IService
|
||||
{
|
||||
int CountContentTypes();
|
||||
int CountMediaTypes();
|
||||
|
||||
/// <summary>
|
||||
/// Validates the composition, if its invalid a list of property type aliases that were duplicated is returned
|
||||
/// </summary>
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -15,15 +15,20 @@
|
||||
</div>
|
||||
|
||||
<umb-empty-state
|
||||
ng-if="model.availableCompositeContentTypes.length === 0"
|
||||
ng-if="model.availableCompositeContentTypes.length === 0 && model.totalContentTypes <= 1"
|
||||
position="center">
|
||||
There are no content types available to use as a composition.
|
||||
</umb-empty-state>
|
||||
<umb-empty-state
|
||||
ng-if="model.availableCompositeContentTypes.length === 0 && model.totalContentTypes > 1"
|
||||
position="center">
|
||||
This content type is used in a composition, and therefore cannot be composed itself.
|
||||
</umb-empty-state>
|
||||
|
||||
<ul class="umb-checkbox-list">
|
||||
<li class="umb-checkbox-list__item" ng-repeat="compositeContentType in model.availableCompositeContentTypes | filter:searchTerm" ng-class="{ '-selected': model.compositeContentTypes.indexOf(compositeContentType.alias)+1 }">
|
||||
<li class="umb-checkbox-list__item" ng-repeat="compositeContentType in model.availableCompositeContentTypes | filter:searchTerm" ng-class="{ '-selected': model.contentType.compositeContentTypes.indexOf(compositeContentType.alias)+1 }">
|
||||
|
||||
<div class="umb-checkbox-list__item-checkbox" ng-class="{ '-selected': model.compositeContentTypes.indexOf(compositeContentType.alias)+1 }">
|
||||
<div class="umb-checkbox-list__item-checkbox" ng-class="{ '-selected': model.contentType.compositeContentTypes.indexOf(compositeContentType.alias)+1 }">
|
||||
<input type="checkbox"
|
||||
checklist-model="model.compositeContentTypes"
|
||||
checklist-value="compositeContentType.alias"
|
||||
@@ -36,4 +41,4 @@
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -46,6 +46,10 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
}
|
||||
|
||||
public int GetCount()
|
||||
{
|
||||
return Services.ContentTypeService.CountContentTypes();
|
||||
}
|
||||
|
||||
public ContentTypeDisplay GetById(int id)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,10 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
}
|
||||
|
||||
public int GetCount()
|
||||
{
|
||||
return Services.ContentTypeService.CountContentTypes();
|
||||
}
|
||||
|
||||
public ContentTypeCompositionDisplay GetById(int id)
|
||||
{
|
||||
|
||||
@@ -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<EntityBasic>();
|
||||
}
|
||||
|
||||
//name, alias, icon, thumb, desc, inherited from the content type
|
||||
|
||||
// Templates
|
||||
[DataMember(Name = "allowedTemplates")]
|
||||
public IEnumerable<EntityBasic> AllowedTemplates { get; set; }
|
||||
|
||||
[DataMember(Name = "defaultTemplate")]
|
||||
public EntityBasic DefaultTemplate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
public ContentTypeDisplay()
|
||||
{
|
||||
//initialize collections so at least their never null
|
||||
AllowedTemplates = new List<EntityBasic>();
|
||||
}
|
||||
|
||||
//name, alias, icon, thumb, desc, inherited from the content type
|
||||
|
||||
// Templates
|
||||
[DataMember(Name = "allowedTemplates")]
|
||||
public IEnumerable<EntityBasic> AllowedTemplates { get; set; }
|
||||
|
||||
[DataMember(Name = "defaultTemplate")]
|
||||
public EntityBasic DefaultTemplate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = propertyEditorResolver;
|
||||
}
|
||||
|
||||
public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext)
|
||||
|
||||
Reference in New Issue
Block a user