Fixes boolean conversion logic in ColorPickerConfigurationEditor, Fixes tree grouping logic and moves groups cache to the ApplicationTreeService, fix other merge issues
This commit is contained in:
@@ -985,7 +985,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (properties.ContainsKey(temp.VersionId))
|
||||
temp.Content.Properties = properties[temp.VersionId];
|
||||
else
|
||||
throw new InvalidOperationException($"No property data found for version: '{cc.Version}'.");
|
||||
throw new InvalidOperationException($"No property data found for version: '{temp.VersionId}'.");
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
temp.Content.ResetDirtyProperties(false);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
@@ -41,10 +42,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <returns>Returns a ApplicationTree Array</returns>
|
||||
IEnumerable<ApplicationTree> GetAll();
|
||||
|
||||
|
||||
IEnumerable<Type> GetAllTypes();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the application tree for the applcation with the specified alias
|
||||
/// </summary>
|
||||
@@ -59,6 +57,14 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="onlyInitialized"></param>
|
||||
/// <returns>Returns a ApplicationTree Array</returns>
|
||||
IEnumerable<ApplicationTree> GetApplicationTrees(string applicationAlias, bool onlyInitialized);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the grouped application trees for the application with the specified alias
|
||||
/// </summary>
|
||||
/// <param name="applicationAlias"></param>
|
||||
/// <param name="onlyInitialized"></param>
|
||||
/// <returns></returns>
|
||||
IDictionary<string, IEnumerable<ApplicationTree>> GetGroupedApplicationTrees(string applicationAlias, bool onlyInitialized);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -117,7 +123,7 @@ namespace Umbraco.Core.Services
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<Type> GetAllTypes()
|
||||
public IDictionary<string, IEnumerable<ApplicationTree>> GetGroupedApplicationTrees(string applicationAlias, bool onlyInitialized)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
}
|
||||
else {
|
||||
// From: https://stackoverflow.com/a/51789597/5018
|
||||
var type = vm.src.substring(vm.src.indexOf("/") + 1, scope.src.indexOf(";base64"));
|
||||
var type = vm.src.substring(vm.src.indexOf("/") + 1, vm.src.indexOf(";base64"));
|
||||
if (type.startsWith("svg")) {
|
||||
vm.isCroppable = false;
|
||||
vm.hasDimensions = false;
|
||||
|
||||
@@ -130,7 +130,8 @@ angular.module('umbraco')
|
||||
* @param {any} crop
|
||||
*/
|
||||
function crop(crop) {
|
||||
$scope.currentCrop = crop;
|
||||
// clone the crop so we can discard the changes
|
||||
$scope.currentCrop = angular.copy(crop);
|
||||
$scope.currentPoint = null;
|
||||
|
||||
//set form to dirty to track changes
|
||||
|
||||
@@ -105,7 +105,11 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
// handle useLabel
|
||||
if (editorValues.TryGetValue("useLabel", out var useLabelObj))
|
||||
output.UseLabel = useLabelObj.TryConvertTo<bool>();
|
||||
{
|
||||
var convertBool = useLabelObj.TryConvertTo<bool>();
|
||||
if (convertBool.Success)
|
||||
output.UseLabel = convertBool.Result;
|
||||
}
|
||||
|
||||
// auto-assigning our ids, get next id from existing values
|
||||
var nextId = 1;
|
||||
@@ -124,7 +128,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
var id = item.Property("id")?.Value?.Value<int>() ?? 0;
|
||||
if (id >= nextId) nextId = id + 1;
|
||||
|
||||
|
||||
var label = item.Property("label")?.Value?.Value<string>();
|
||||
value = JsonConvert.SerializeObject(new { value, label });
|
||||
|
||||
|
||||
@@ -21,15 +21,16 @@ namespace Umbraco.Web.Services
|
||||
private readonly ILogger _logger;
|
||||
private readonly CacheHelper _cache;
|
||||
private Lazy<IEnumerable<ApplicationTree>> _allAvailableTrees;
|
||||
private IEnumerable<Type> _treeTypes;
|
||||
internal const string TreeConfigFileName = "trees.config";
|
||||
private static string _treeConfig;
|
||||
private static readonly object Locker = new object();
|
||||
private readonly Lazy<IReadOnlyCollection<IGrouping<string, string>>> _groupedTrees;
|
||||
|
||||
public ApplicationTreeService(ILogger logger, CacheHelper cache)
|
||||
{
|
||||
_logger = logger;
|
||||
_cache = cache;
|
||||
_groupedTrees = new Lazy<IReadOnlyCollection<IGrouping<string, string>>>(InitGroupedTrees);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -252,11 +253,6 @@ namespace Umbraco.Web.Services
|
||||
return GetAppTrees().OrderBy(x => x.SortOrder);
|
||||
}
|
||||
|
||||
public IEnumerable<Type> GetAllTypes()
|
||||
{
|
||||
return _treeTypes ?? (_treeTypes = GetAll().Select(x => x.GetRuntimeType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the application tree for the applcation with the specified alias
|
||||
/// </summary>
|
||||
@@ -287,6 +283,46 @@ namespace Umbraco.Web.Services
|
||||
return list.OrderBy(x => x.SortOrder).ToArray();
|
||||
}
|
||||
|
||||
public IDictionary<string, IEnumerable<ApplicationTree>> GetGroupedApplicationTrees(string applicationAlias, bool onlyInitialized)
|
||||
{
|
||||
var result = new Dictionary<string, IEnumerable<ApplicationTree>>();
|
||||
var foundTrees = GetApplicationTrees(applicationAlias, onlyInitialized);
|
||||
foreach(var treeGroup in _groupedTrees.Value)
|
||||
{
|
||||
List<ApplicationTree> resultGroup = null;
|
||||
foreach(var tree in foundTrees)
|
||||
{
|
||||
foreach(var treeAliasInGroup in treeGroup)
|
||||
{
|
||||
if (tree.Alias == treeAliasInGroup)
|
||||
{
|
||||
if (resultGroup == null) resultGroup = new List<ApplicationTree>();
|
||||
resultGroup.Add(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resultGroup != null)
|
||||
result[treeGroup.Key ?? string.Empty] = resultGroup; //key cannot be null so make empty string
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a group of all tree groups and their tree aliases
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Used to initialize the <see cref="_groupedTrees"/> field
|
||||
/// </remarks>
|
||||
private IReadOnlyCollection<IGrouping<string, string>> InitGroupedTrees()
|
||||
{
|
||||
var result = GetAll()
|
||||
.Select(x => (treeAlias: x.Alias, treeGroup: x.GetRuntimeType().GetCustomAttribute<CoreTreeAttribute>(false)?.TreeGroup))
|
||||
.GroupBy(x => x.treeGroup, x => x.treeAlias)
|
||||
.ToList();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads in the xml structure from disk if one is found, otherwise loads in an empty xml structure, calls the
|
||||
/// callback with the xml document and saves the structure back to disk if saveAfterCallback is true.
|
||||
|
||||
@@ -21,20 +21,7 @@ namespace Umbraco.Web.Trees
|
||||
[AngularJsonOnlyConfiguration]
|
||||
[PluginController("UmbracoTrees")]
|
||||
public class ApplicationTreeController : UmbracoAuthorizedApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// Fetches all registered trees and groups them together if they have a [CoreTree]
|
||||
/// Attribute with a 'TreeGroup' property set
|
||||
/// This allows the settings section trees to be grouped by Settings, Templating & Other
|
||||
/// </summary>
|
||||
private static readonly Lazy<IReadOnlyCollection<IGrouping<string, (Type, string)>>> CoreTrees
|
||||
= new Lazy<IReadOnlyCollection<IGrouping<string, (Type, string)>>>(() =>
|
||||
Current.Services.ApplicationTreeService.GetAllTypes()
|
||||
.Select(x => (TreeType: x, TreeGroup: x.GetCustomAttribute<CoreTreeAttribute>(false)?.TreeGroup))
|
||||
.GroupBy(x => x.TreeGroup)
|
||||
.ToList());
|
||||
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the tree nodes for an application
|
||||
/// </summary>
|
||||
@@ -51,13 +38,14 @@ namespace Umbraco.Web.Trees
|
||||
if (string.IsNullOrEmpty(application)) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
|
||||
//find all tree definitions that have the current application alias
|
||||
var appTrees = Services.ApplicationTreeService.GetApplicationTrees(application, onlyInitialized).ToArray();
|
||||
var groupedTrees = Services.ApplicationTreeService.GetGroupedApplicationTrees(application, onlyInitialized);
|
||||
var allTrees = groupedTrees.Values.SelectMany(x => x).ToList();
|
||||
|
||||
if (string.IsNullOrEmpty(tree) == false || appTrees.Length <= 1)
|
||||
if (string.IsNullOrEmpty(tree) == false || allTrees.Count <= 1)
|
||||
{
|
||||
var apptree = string.IsNullOrEmpty(tree) == false
|
||||
? appTrees.SingleOrDefault(x => x.Alias == tree)
|
||||
: appTrees.SingleOrDefault();
|
||||
var apptree = !tree.IsNullOrWhiteSpace()
|
||||
? allTrees.FirstOrDefault(x => x.Alias == tree)
|
||||
: allTrees.FirstOrDefault();
|
||||
|
||||
if (apptree == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
|
||||
@@ -74,22 +62,22 @@ namespace Umbraco.Web.Trees
|
||||
}
|
||||
}
|
||||
|
||||
var collection = new TreeNodeCollection();
|
||||
foreach (var apptree in appTrees)
|
||||
{
|
||||
//return the root nodes for each tree in the app
|
||||
var rootNode = await GetRootForMultipleAppTree(apptree, queryStrings);
|
||||
//This could be null if the tree decides not to return it's root (i.e. the member type tree does this when not in umbraco membership mode)
|
||||
if (rootNode != null)
|
||||
{
|
||||
collection.Add(rootNode);
|
||||
}
|
||||
}
|
||||
|
||||
//Don't apply fancy grouping logic futher down, if we only have one group of items
|
||||
var hasGroups = CoreTrees.Value.Count > 0;
|
||||
var hasGroups = groupedTrees.Count > 1;
|
||||
if (!hasGroups)
|
||||
{
|
||||
var collection = new TreeNodeCollection();
|
||||
foreach (var apptree in allTrees)
|
||||
{
|
||||
//return the root nodes for each tree in the app
|
||||
var rootNode = await GetRootForMultipleAppTree(apptree, queryStrings);
|
||||
//This could be null if the tree decides not to return it's root (i.e. the member type tree does this when not in umbraco membership mode)
|
||||
if (rootNode != null)
|
||||
{
|
||||
collection.Add(rootNode);
|
||||
}
|
||||
}
|
||||
|
||||
var multiTree = TreeRootNode.CreateMultiTreeRoot(collection);
|
||||
multiTree.Name = Services.TextService.Localize("sections/" + application);
|
||||
|
||||
@@ -99,32 +87,23 @@ namespace Umbraco.Web.Trees
|
||||
var rootNodeGroups = new List<TreeRootNode>();
|
||||
|
||||
//Group trees by [CoreTree] attribute with a TreeGroup property
|
||||
foreach (var treeSectionGroup in CoreTrees.Value)
|
||||
foreach (var treeSectionGroup in groupedTrees)
|
||||
{
|
||||
var treeGroupName = treeSectionGroup.Key;
|
||||
|
||||
var groupNodeCollection = new TreeNodeCollection();
|
||||
foreach (var treeItem in treeSectionGroup)
|
||||
foreach (var appTree in treeSectionGroup.Value)
|
||||
{
|
||||
//Item1 tuple - is the type from all tree types
|
||||
var treeItemType = treeItem.Item1;
|
||||
|
||||
var findAppTree = appTrees.FirstOrDefault(x => x.GetRuntimeType() == treeItemType);
|
||||
if (findAppTree != null)
|
||||
var rootNode = await GetRootForMultipleAppTree(appTree, queryStrings);
|
||||
if (rootNode != null)
|
||||
{
|
||||
//Now we need to get the 'TreeNode' which is in 'collection'
|
||||
var treeItemNode = collection.FirstOrDefault(x => x.AdditionalData["treeAlias"].ToString() == findAppTree.Alias);
|
||||
|
||||
if (treeItemNode != null)
|
||||
{
|
||||
//Add to a new list/collection
|
||||
groupNodeCollection.Add(treeItemNode);
|
||||
}
|
||||
//Add to a new list/collection
|
||||
groupNodeCollection.Add(rootNode);
|
||||
}
|
||||
}
|
||||
|
||||
//If treeGroupName == null then its third party
|
||||
if (treeGroupName == null)
|
||||
if (treeGroupName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//This is used for the localisation key
|
||||
//treeHeaders/thirdPartyGroup
|
||||
|
||||
Reference in New Issue
Block a user