Merge remote-tracking branch 'origin/dev-v7' into temp8

This commit is contained in:
Sebastiaan Janssen
2018-06-06 22:36:22 +02:00
11 changed files with 203 additions and 10 deletions

View File

@@ -109,6 +109,23 @@ namespace Umbraco.Core.Services
return new ContentTypeAvailableCompositionsResults(ancestors, result);
}
/// <summary>
/// Returns the list of content types the composition is used in
/// </summary>
/// <param name="allContentTypes"></param>
/// <param name="ctService"></param>
/// <param name="source"></param>
/// <returns></returns>
internal static IEnumerable<IContentTypeComposition> GetWhereCompositionIsUsedInContentTypes(this IContentTypeService ctService,
IContentTypeComposition source,
IContentTypeComposition[] allContentTypes)
{
var sourceId = source != null ? source.Id : 0;
// find which content types are using this composition
return allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == sourceId)).ToArray();
}
private static IContentTypeComposition[] GetAncestors(IContentTypeComposition ctype, IContentTypeComposition[] allContentTypes)
{

View File

@@ -348,9 +348,10 @@
}
};
//select which resource methods to use, eg document Type or Media Type versions
var availableContentTypeResource = scope.contentType === "documentType" ? contentTypeResource.getAvailableCompositeContentTypes : mediaTypeResource.getAvailableCompositeContentTypes;
var countContentTypeResource = scope.contentType === "documentType" ? contentTypeResource.getCount : mediaTypeResource.getCount;
var whereUsedContentTypeResource = scope.contentType === "documentType" ? contentTypeResource.getWhereCompositionIsUsedInContentTypes : mediaTypeResource.getWhereCompositionIsUsedInContentTypes;
var countContentTypeResource = scope.contentType === "documentType" ? contentTypeResource.getCount : mediaTypeResource.getCount;
//get the currently assigned property type aliases - ensure we pass these to the server side filer
var propAliasesExisting = _.filter(_.flatten(_.map(scope.model.groups, function(g) {
@@ -363,7 +364,14 @@
$q.all([
//get available composite types
availableContentTypeResource(scope.model.id, [], propAliasesExisting).then(function (result) {
setupAvailableContentTypesModel(result);
setupAvailableContentTypesModel(result);
}),
//get where used document types
whereUsedContentTypeResource(scope.model.id).then(function (whereUsed) {
//pass to the dialog model the content type eg documentType or mediaType
scope.compositionsDialogModel.section = scope.contentType;
//pass the list of 'where used' document types
scope.compositionsDialogModel.whereCompositionUsed = whereUsed;
}),
//get content type count
countContentTypeResource().then(function(result) {

View File

@@ -38,7 +38,37 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
query),
'Failed to retrieve data for content type id ' + contentTypeId);
},
/**
* @ngdoc method
* @name umbraco.resources.contentTypeResource#getWhereCompositionIsUsedInContentTypes
* @methodOf umbraco.resources.contentTypeResource
*
* @description
* Returns a list of content types which use a specific composition with a given id
*
* ##usage
* <pre>
* contentTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
* .then(function(contentTypeList) {
* console.log(contentTypeList);
* });
* </pre>
* @param {Int} contentTypeId id of the composition content type to retrieve the list of the content types where it has been used
* @returns {Promise} resourcePromise object.
*
*/
getWhereCompositionIsUsedInContentTypes: function (contentTypeId) {
var query = {
contentTypeId: contentTypeId
};
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"contentTypeApiBaseUrl",
"GetWhereCompositionIsUsedInContentTypes"),
query),
'Failed to retrieve data for content type id ' + contentTypeId);
},
/**
* @ngdoc method

View File

@@ -38,7 +38,38 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
query),
'Failed to retrieve data for content type id ' + contentTypeId);
},
/**
* @ngdoc method
* @name umbraco.resources.mediaTypeResource#getWhereCompositionIsUsedInContentTypes
* @methodOf umbraco.resources.mediaTypeResource
*
* @description
* Returns a list of media types which use a specific composition with a given id
*
* ##usage
* <pre>
* mediaTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
* .then(function(mediaTypeList) {
* console.log(mediaTypeList);
* });
* </pre>
* @param {Int} contentTypeId id of the composition content type to retrieve the list of the media types where it has been used
* @returns {Promise} resourcePromise object.
*
*/
getWhereCompositionIsUsedInContentTypes: function (contentTypeId) {
var query = {
contentTypeId: contentTypeId
};
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"mediaTypeApiBaseUrl",
"GetWhereCompositionIsUsedInContentTypes"),
query),
'Failed to retrieve data for content type id ' + contentTypeId);
},
/**
* @ngdoc method
* @name umbraco.resources.mediaTypeResource#getAllowedTypes

View File

@@ -1,17 +1,23 @@
(function() {
"use strict";
function CompositionsOverlay($scope) {
function CompositionsOverlay($scope,$location) {
var vm = this;
vm.isSelected = isSelected;
vm.openContentType = openContentType;
function isSelected(alias) {
if($scope.model.contentType.compositeContentTypes.indexOf(alias) !== -1) {
return true;
}
}
function openContentType(contentType, section) {
var url = (section === "documentType" ? "/settings/documenttypes/edit/" : "/settings/mediaTypes/edit/") + contentType.id;
$location.path(url);
}
}
angular.module("umbraco").controller("Umbraco.Overlays.CompositionsOverlay", CompositionsOverlay);

View File

@@ -22,11 +22,16 @@
position="center">
<localize key="contentTypeEditor_noAvailableCompositions"></localize>
</umb-empty-state>
<umb-empty-state ng-if="model.availableCompositeContentTypes.length === 0 && model.totalContentTypes > 1"
position="center">
<umb-empty-state ng-if="model.availableCompositeContentTypes.length === 0 && model.totalContentTypes > 1">
<localize key="contentTypeEditor_compositionInUse"></localize>
</umb-empty-state>
<div ng-if="model.availableCompositeContentTypes.length === 0 && model.totalContentTypes > 1 && model.whereCompositionUsed.length > 0">
<h5><localize key="contentTypeEditor_compositionUsageHeading"></localize></h5>
<p><localize key="contentTypeEditor_compositionUsageSpecification"></localize></p>
<ul class="umb-checkbox-list">
<li class="umb-checkbox-list__item" ng-repeat="contentTypeEntity in model.whereCompositionUsed"><a ng-click="vm.openContentType(contentTypeEntity.contentType, model.section)"><i class="{{contentTypeEntity.contentType.icon}}"></i>&nbsp;{{contentTypeEntity.contentType.name}}</a></li>
</ul>
</div>
<ul class="umb-checkbox-list">
<li class="umb-checkbox-list__item"
ng-repeat="compositeContentType in model.availableCompositeContentTypes | filter:searchTerm"
@@ -50,4 +55,4 @@
</li>
</ul>
</div>
</div>

View File

@@ -1521,6 +1521,9 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="showOnMemberProfileDescription">Allow this property value to be displayed on the member profile page</key>
<key alias="tabHasNoSortOrder">tab has no sort order</key>
<key alias="compositionUsageHeading">Where is this composition used?</key>
<key alias="compositionUsageSpecification">This composition is currently used in the composition of the following content types:</key>
</area>
<area alias="modelsBuilder">

View File

@@ -1646,6 +1646,9 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="showOnMemberProfileDescription">Allow this property value to be displayed on the member profile page</key>
<key alias="tabHasNoSortOrder">tab has no sort order</key>
<key alias="compositionUsageHeading">Where is this composition used?</key>
<key alias="compositionUsageSpecification">This composition is currently used in the composition of the following content types:</key>
</area>
<area alias="languages">

View File

@@ -111,6 +111,22 @@ namespace Umbraco.Web.Editors
});
return Request.CreateResponse(result);
}
/// <summary>
/// Returns where a particular composition has been used
/// This has been wrapped in a dto instead of simple parameters to support having multiple parameters in post request body
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage GetWhereCompositionIsUsedInContentTypes(GetAvailableCompositionsFilter filter)
{
var result = PerformGetWhereCompositionIsUsedInContentTypes(filter.ContentTypeId, UmbracoObjectTypes.DocumentType)
.Select(x => new
{
contentType = x
});
return Request.CreateResponse(result);
}
[UmbracoTreeAuthorize(
Constants.Trees.DocumentTypes, Constants.Trees.Content,

View File

@@ -113,7 +113,66 @@ namespace Umbraco.Web.Editors
.ToList();
}
/// <summary>
/// Returns a list of content types where a particular composition content type is used
/// </summary>
/// <param name="type">Type of content Type, eg documentType or mediaType</param>
/// <param name="contentTypeId">Id of composition content type</param>
/// <returns></returns>
protected IEnumerable<EntityBasic> PerformGetWhereCompositionIsUsedInContentTypes(int contentTypeId,
UmbracoObjectTypes type)
{
IContentTypeComposition source = null;
//below is all ported from the old doc type editor and comes with the same weaknesses /insanity / magic
IContentTypeComposition[] allContentTypes;
switch (type)
{
case UmbracoObjectTypes.DocumentType:
if (contentTypeId > 0)
{
source = Services.ContentTypeService.GetContentType(contentTypeId);
if (source == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
allContentTypes = Services.ContentTypeService.GetAllContentTypes().Cast<IContentTypeComposition>().ToArray();
break;
case UmbracoObjectTypes.MediaType:
if (contentTypeId > 0)
{
source = Services.ContentTypeService.GetMediaType(contentTypeId);
if (source == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
allContentTypes = Services.ContentTypeService.GetAllMediaTypes().Cast<IContentTypeComposition>().ToArray();
break;
case UmbracoObjectTypes.MemberType:
if (contentTypeId > 0)
{
source = Services.MemberTypeService.Get(contentTypeId);
if (source == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
allContentTypes = Services.MemberTypeService.GetAll().Cast<IContentTypeComposition>().ToArray();
break;
default:
throw new ArgumentOutOfRangeException("The entity type was not a content type");
}
var contentTypesWhereCompositionIsUsed = Services.ContentTypeService.GetWhereCompositionIsUsedInContentTypes(source, allContentTypes);
return contentTypesWhereCompositionIsUsed
.Select(x => Mapper.Map<IContentTypeComposition, EntityBasic>(x))
.Select(x =>
{
//translate the name
x.Name = TranslateItem(x.Name);
return x;
})
.ToList();
}
protected string TranslateItem(string text)
{
if (text == null)

View File

@@ -109,7 +109,22 @@ namespace Umbraco.Web.Editors
});
return Request.CreateResponse(result);
}
/// <summary>
/// Returns where a particular composition has been used
/// This has been wrapped in a dto instead of simple parameters to support having multiple parameters in post request body
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage GetWhereCompositionIsUsedInContentTypes(GetAvailableCompositionsFilter filter)
{
var result = PerformGetWhereCompositionIsUsedInContentTypes(filter.ContentTypeId, UmbracoObjectTypes.MediaType)
.Select(x => new
{
contentType = x
});
return Request.CreateResponse(result);
}
public MediaTypeDisplay GetEmpty(int parentId)
{
var ct = new MediaType(parentId) {Icon = "icon-picture"};