Merge branch 'netcore/feature/use-request-cache-instead-of-httpcontext-items' into netcore/feature/move-files-after-umbraco-context-abstractions
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Editors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
[DataContract(Name = "contentTypeImportModel")]
|
||||
public class ContentTypeImportModel : INotificationModel, IHaveUploadedFiles
|
||||
{
|
||||
[DataMember(Name = "alias")]
|
||||
public string Alias { get; set; }
|
||||
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataMember(Name = "notifications")]
|
||||
public List<BackOfficeNotification> Notifications { get; } = new List<BackOfficeNotification>();
|
||||
|
||||
[DataMember(Name = "tempFileName")]
|
||||
public string TempFileName { get; set; }
|
||||
|
||||
public List<ContentPropertyFile> UploadedFiles => new List<ContentPropertyFile>();
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
internal class ImageProcessorImageUrlGenerator : IImageUrlGenerator
|
||||
{
|
||||
public string GetImageUrl(ImageUrlGenerationOptions options)
|
||||
{
|
||||
if (options == null) return null;
|
||||
|
||||
var imageProcessorUrl = new StringBuilder(options.ImageUrl ?? string.Empty);
|
||||
|
||||
if (options.FocalPoint != null) AppendFocalPoint(imageProcessorUrl, options);
|
||||
else if (options.Crop != null) AppendCrop(imageProcessorUrl, options);
|
||||
else if (options.DefaultCrop) imageProcessorUrl.Append("?anchor=center&mode=crop");
|
||||
else
|
||||
{
|
||||
imageProcessorUrl.Append("?mode=").Append((options.ImageCropMode ?? "crop").ToLower());
|
||||
|
||||
if (options.ImageCropAnchor != null) imageProcessorUrl.Append("&anchor=").Append(options.ImageCropAnchor.ToLower());
|
||||
}
|
||||
|
||||
var hasFormat = options.FurtherOptions != null && options.FurtherOptions.InvariantContains("&format=");
|
||||
|
||||
//Only put quality here, if we don't have a format specified.
|
||||
//Otherwise we need to put quality at the end to avoid it being overridden by the format.
|
||||
if (options.Quality != null && hasFormat == false) imageProcessorUrl.Append("&quality=").Append(options.Quality);
|
||||
if (options.HeightRatio != null) imageProcessorUrl.Append("&heightratio=").Append(options.HeightRatio.Value.ToString(CultureInfo.InvariantCulture));
|
||||
if (options.WidthRatio != null) imageProcessorUrl.Append("&widthratio=").Append(options.WidthRatio.Value.ToString(CultureInfo.InvariantCulture));
|
||||
if (options.Width != null) imageProcessorUrl.Append("&width=").Append(options.Width);
|
||||
if (options.Height != null) imageProcessorUrl.Append("&height=").Append(options.Height);
|
||||
if (options.UpScale == false) imageProcessorUrl.Append("&upscale=false");
|
||||
if (options.AnimationProcessMode != null) imageProcessorUrl.Append("&animationprocessmode=").Append(options.AnimationProcessMode);
|
||||
if (options.FurtherOptions != null) imageProcessorUrl.Append(options.FurtherOptions);
|
||||
|
||||
//If furtherOptions contains a format, we need to put the quality after the format.
|
||||
if (options.Quality != null && hasFormat) imageProcessorUrl.Append("&quality=").Append(options.Quality);
|
||||
if (options.CacheBusterValue != null) imageProcessorUrl.Append("&rnd=").Append(options.CacheBusterValue);
|
||||
|
||||
return imageProcessorUrl.ToString();
|
||||
}
|
||||
|
||||
private void AppendFocalPoint(StringBuilder imageProcessorUrl, ImageUrlGenerationOptions options)
|
||||
{
|
||||
imageProcessorUrl.Append("?center=");
|
||||
imageProcessorUrl.Append(options.FocalPoint.Top.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.FocalPoint.Left.ToString(CultureInfo.InvariantCulture));
|
||||
imageProcessorUrl.Append("&mode=crop");
|
||||
}
|
||||
|
||||
private void AppendCrop(StringBuilder imageProcessorUrl, ImageUrlGenerationOptions options)
|
||||
{
|
||||
imageProcessorUrl.Append("?crop=");
|
||||
imageProcessorUrl.Append(options.Crop.X1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.Y1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.X2.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.Y2.ToString(CultureInfo.InvariantCulture));
|
||||
imageProcessorUrl.Append("&cropmode=percentage");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Editors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A model that represents uploading a local package
|
||||
/// </summary>
|
||||
[DataContract(Name = "localPackageInstallModel")]
|
||||
public class LocalPackageInstallModel : PackageInstallModel, IHaveUploadedFiles, INotificationModel
|
||||
{
|
||||
public List<ContentPropertyFile> UploadedFiles { get; } = new List<ContentPropertyFile>();
|
||||
|
||||
[DataMember(Name = "notifications")]
|
||||
public List<BackOfficeNotification> Notifications { get; } = new List<BackOfficeNotification>();
|
||||
|
||||
/// <summary>
|
||||
/// A flag to determine if this package is compatible to be installed
|
||||
/// </summary>
|
||||
[DataMember(Name = "isCompatible")]
|
||||
public bool IsCompatible { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum umbraco version that this package is pinned to
|
||||
/// </summary>
|
||||
[DataMember(Name = "umbracoVersion")]
|
||||
public string UmbracoVersion { get; set; }
|
||||
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataMember(Name = "url")]
|
||||
public string Url { get; set; }
|
||||
|
||||
[DataMember(Name = "version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If this is not null then it means the package is being from this version
|
||||
/// </summary>
|
||||
[DataMember(Name = "originalVersion")]
|
||||
public string OriginalVersion { get; set; }
|
||||
|
||||
[DataMember(Name = "containsUnsecureFiles")]
|
||||
public bool ContainsUnsecureFiles { get; set; }
|
||||
|
||||
[DataMember(Name = "containsTemplateConflicts")]
|
||||
public bool ContainsTemplateConflicts => ConflictingTemplateAliases != null && ConflictingTemplateAliases.Count > 0;
|
||||
|
||||
[DataMember(Name = "containsStyleSheetConflicts")]
|
||||
public bool ContainsStyleSheetConflicts => ConflictingStyleSheetNames != null && ConflictingStyleSheetNames.Count > 0;
|
||||
|
||||
[DataMember(Name = "containsMacroConflict")]
|
||||
public bool ContainsMacroConflict => ConflictingMacroAliases != null && ConflictingMacroAliases.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Key value of name + alias
|
||||
/// </summary>
|
||||
[DataMember(Name = "conflictingTemplateAliases")]
|
||||
public IDictionary<string, string> ConflictingTemplateAliases { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key value of name + alias
|
||||
/// </summary>
|
||||
[DataMember(Name = "conflictingStyleSheetNames")]
|
||||
public IDictionary<string, string> ConflictingStyleSheetNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key value of name + alias
|
||||
/// </summary>
|
||||
[DataMember(Name = "conflictingMacroAliases")]
|
||||
public IDictionary<string, string> ConflictingMacroAliases { get; set; }
|
||||
|
||||
[DataMember(Name = "readme")]
|
||||
public string Readme { get; set; }
|
||||
|
||||
[DataMember(Name = "licenseUrl")]
|
||||
public string LicenseUrl { get; set; }
|
||||
|
||||
[DataMember(Name = "license")]
|
||||
public string License { get; set; }
|
||||
|
||||
[DataMember(Name = "authorUrl")]
|
||||
public string AuthorUrl { get; set; }
|
||||
|
||||
[DataMember(Name = "author")]
|
||||
public string Author { get; set; }
|
||||
|
||||
[DataMember(Name = "contributors")]
|
||||
public IList<string> Contributors { get; set; }
|
||||
|
||||
[DataMember(Name = "iconUrl")]
|
||||
public string IconUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IVariationContextAccessor"/> on top of <see cref="IHttpContextAccessor"/>.
|
||||
/// </summary>
|
||||
public class HttpContextVariationContextAccessor : IVariationContextAccessor
|
||||
{
|
||||
public const string ContextKey = "Umbraco.Web.Models.PublishedContent.DefaultVariationContextAccessor";
|
||||
public readonly IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpContextVariationContextAccessor"/> class.
|
||||
/// </summary>
|
||||
public HttpContextVariationContextAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public VariationContext VariationContext
|
||||
{
|
||||
get => (VariationContext) HttpContextAccessor.HttpContext?.Items[ContextKey];
|
||||
set => HttpContextAccessor.HttpContext.Items[ContextKey] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
@@ -7,8 +8,8 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
/// </summary>
|
||||
internal class HybridVariationContextAccessor : HybridAccessorBase<VariationContext>, IVariationContextAccessor
|
||||
{
|
||||
public HybridVariationContextAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
public HybridVariationContextAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -23,4 +24,4 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
set => Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a default implementation for <see cref="IPublishedValueFallback"/>.
|
||||
/// </summary>
|
||||
public class PublishedValueFallback : IPublishedValueFallback
|
||||
{
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedValueFallback"/> class.
|
||||
/// </summary>
|
||||
public PublishedValueFallback(ServiceContext serviceContext, IVariationContextAccessor variationContextAccessor)
|
||||
{
|
||||
_localizationService = serviceContext.LocalizationService;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetValue(IPublishedProperty property, string culture, string segment, Fallback fallback, object defaultValue, out object value)
|
||||
{
|
||||
return TryGetValue<object>(property, culture, segment, fallback, defaultValue, out value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetValue<T>(IPublishedProperty property, string culture, string segment, Fallback fallback, T defaultValue, out T value)
|
||||
{
|
||||
_variationContextAccessor.ContextualizeVariation(property.PropertyType.Variations, ref culture, ref segment);
|
||||
|
||||
foreach (var f in fallback)
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
case Fallback.None:
|
||||
continue;
|
||||
case Fallback.DefaultValue:
|
||||
value = defaultValue;
|
||||
return true;
|
||||
case Fallback.Language:
|
||||
if (TryGetValueWithLanguageFallback(property, culture, segment, out value))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
throw NotSupportedFallbackMethod(f, "property");
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetValue(IPublishedElement content, string alias, string culture, string segment, Fallback fallback, object defaultValue, out object value)
|
||||
{
|
||||
return TryGetValue<object>(content, alias, culture, segment, fallback, defaultValue, out value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetValue<T>(IPublishedElement content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value)
|
||||
{
|
||||
var propertyType = content.ContentType.GetPropertyType(alias);
|
||||
if (propertyType == null)
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
_variationContextAccessor.ContextualizeVariation(propertyType.Variations, ref culture, ref segment);
|
||||
|
||||
foreach (var f in fallback)
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
case Fallback.None:
|
||||
continue;
|
||||
case Fallback.DefaultValue:
|
||||
value = defaultValue;
|
||||
return true;
|
||||
case Fallback.Language:
|
||||
if (TryGetValueWithLanguageFallback(content, alias, culture, segment, out value))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
throw NotSupportedFallbackMethod(f, "element");
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetValue(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, object defaultValue, out object value, out IPublishedProperty noValueProperty)
|
||||
{
|
||||
return TryGetValue<object>(content, alias, culture, segment, fallback, defaultValue, out value, out noValueProperty);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool TryGetValue<T>(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value, out IPublishedProperty noValueProperty)
|
||||
{
|
||||
noValueProperty = default;
|
||||
|
||||
var propertyType = content.ContentType.GetPropertyType(alias);
|
||||
if (propertyType != null)
|
||||
{
|
||||
_variationContextAccessor.ContextualizeVariation(propertyType.Variations, ref culture, ref segment);
|
||||
noValueProperty = content.GetProperty(alias);
|
||||
}
|
||||
|
||||
// note: we don't support "recurse & language" which would walk up the tree,
|
||||
// looking at languages at each level - should someone need it... they'll have
|
||||
// to implement it.
|
||||
|
||||
foreach (var f in fallback)
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
case Fallback.None:
|
||||
continue;
|
||||
case Fallback.DefaultValue:
|
||||
value = defaultValue;
|
||||
return true;
|
||||
case Fallback.Language:
|
||||
if (propertyType == null)
|
||||
continue;
|
||||
if (TryGetValueWithLanguageFallback(content, alias, culture, segment, out value))
|
||||
return true;
|
||||
break;
|
||||
case Fallback.Ancestors:
|
||||
if (TryGetValueWithAncestorsFallback(content, alias, culture, segment, out value, ref noValueProperty))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
throw NotSupportedFallbackMethod(f, "content");
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private NotSupportedException NotSupportedFallbackMethod(int fallback, string level)
|
||||
{
|
||||
return new NotSupportedException($"Fallback {GetType().Name} does not support fallback code '{fallback}' at {level} level.");
|
||||
}
|
||||
|
||||
// tries to get a value, recursing the tree
|
||||
// because we recurse, content may not even have the a property with the specified alias (but only some ancestor)
|
||||
// in case no value was found, noValueProperty contains the first property that was found (which does not have a value)
|
||||
private bool TryGetValueWithAncestorsFallback<T>(IPublishedContent content, string alias, string culture, string segment, out T value, ref IPublishedProperty noValueProperty)
|
||||
{
|
||||
IPublishedProperty property; // if we are here, content's property has no value
|
||||
do
|
||||
{
|
||||
content = content.Parent;
|
||||
|
||||
var propertyType = content?.ContentType.GetPropertyType(alias);
|
||||
|
||||
if (propertyType != null)
|
||||
{
|
||||
culture = null;
|
||||
segment = null;
|
||||
_variationContextAccessor.ContextualizeVariation(propertyType.Variations, ref culture, ref segment);
|
||||
}
|
||||
|
||||
property = content?.GetProperty(alias);
|
||||
if (property != null && noValueProperty == null)
|
||||
{
|
||||
noValueProperty = property;
|
||||
}
|
||||
}
|
||||
while (content != null && (property == null || property.HasValue(culture, segment) == false));
|
||||
|
||||
// if we found a content with the property having a value, return that property value
|
||||
if (property != null && property.HasValue(culture, segment))
|
||||
{
|
||||
value = property.Value<T>(culture, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
// tries to get a value, falling back onto other languages
|
||||
private bool TryGetValueWithLanguageFallback<T>(IPublishedProperty property, string culture, string segment, out T value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (culture.IsNullOrWhiteSpace()) return false;
|
||||
|
||||
var visited = new HashSet<int>();
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language == null) return false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (language.FallbackLanguageId == null) return false;
|
||||
|
||||
var language2Id = language.FallbackLanguageId.Value;
|
||||
if (visited.Contains(language2Id)) return false;
|
||||
visited.Add(language2Id);
|
||||
|
||||
var language2 = _localizationService.GetLanguageById(language2Id);
|
||||
if (language2 == null) return false;
|
||||
var culture2 = language2.IsoCode;
|
||||
|
||||
if (property.HasValue(culture2, segment))
|
||||
{
|
||||
value = property.Value<T>(culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
language = language2;
|
||||
}
|
||||
}
|
||||
|
||||
// tries to get a value, falling back onto other languages
|
||||
private bool TryGetValueWithLanguageFallback<T>(IPublishedElement content, string alias, string culture, string segment, out T value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (culture.IsNullOrWhiteSpace()) return false;
|
||||
|
||||
var visited = new HashSet<int>();
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language == null) return false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (language.FallbackLanguageId == null) return false;
|
||||
|
||||
var language2Id = language.FallbackLanguageId.Value;
|
||||
if (visited.Contains(language2Id)) return false;
|
||||
visited.Add(language2Id);
|
||||
|
||||
var language2 = _localizationService.GetLanguageById(language2Id);
|
||||
if (language2 == null) return false;
|
||||
var culture2 = language2.IsoCode;
|
||||
|
||||
if (content.HasValue(alias, culture2, segment))
|
||||
{
|
||||
value = content.Value<T>(alias, culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
language = language2;
|
||||
}
|
||||
}
|
||||
|
||||
// tries to get a value, falling back onto other languages
|
||||
private bool TryGetValueWithLanguageFallback<T>(IPublishedContent content, string alias, string culture, string segment, out T value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (culture.IsNullOrWhiteSpace()) return false;
|
||||
|
||||
var visited = new HashSet<int>();
|
||||
|
||||
// TODO: _localizationService.GetXxx() is expensive, it deep clones objects
|
||||
// we want _localizationService.GetReadOnlyXxx() returning IReadOnlyLanguage which cannot be saved back = no need to clone
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language == null) return false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (language.FallbackLanguageId == null) return false;
|
||||
|
||||
var language2Id = language.FallbackLanguageId.Value;
|
||||
if (visited.Contains(language2Id)) return false;
|
||||
visited.Add(language2Id);
|
||||
|
||||
var language2 = _localizationService.GetLanguageById(language2Id);
|
||||
if (language2 == null) return false;
|
||||
var culture2 = language2.IsoCode;
|
||||
|
||||
if (content.HasValue(alias, culture2, segment))
|
||||
{
|
||||
value = content.Value<T>(alias, culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
language = language2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
public sealed class CreateChildEntity : ActionMenuItem
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public CreateChildEntity(string name, bool separatorBefore = false)
|
||||
: base(ActionNew.ActionAlias, name)
|
||||
{
|
||||
Icon = "add"; Name = name;
|
||||
SeparatorBefore = separatorBefore;
|
||||
}
|
||||
|
||||
public CreateChildEntity(ILocalizedTextService textService, bool separatorBefore = false)
|
||||
: base(ActionNew.ActionAlias, textService)
|
||||
{
|
||||
Icon = "add";
|
||||
SeparatorBefore = separatorBefore;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the export member menu item
|
||||
/// </summary>
|
||||
public sealed class ExportMember : ActionMenuItem
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public ExportMember(ILocalizedTextService textService) : base("export", textService)
|
||||
{
|
||||
Icon = "download-alt";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user