Refactored the ManifestContentAppDefinition to have a factory and a seperate data class.
This commit is contained in:
@@ -6,11 +6,11 @@ using Umbraco.Core.Serialization;
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a json read converter for <see cref="IContentAppDefinition"/>.
|
||||
/// Implements a json read converter for <see cref="ManifestContentAppDefinition"/>.
|
||||
/// </summary>
|
||||
internal class ContentAppDefinitionConverter : JsonReadConverter<IContentAppDefinition>
|
||||
internal class ContentAppDefinitionConverter : JsonReadConverter<ManifestContentAppDefinition>
|
||||
{
|
||||
protected override IContentAppDefinition Create(Type objectType, string path, JObject jObject)
|
||||
protected override ManifestContentAppDefinition Create(Type objectType, string path, JObject jObject)
|
||||
=> new ManifestContentAppDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,9 @@ namespace Umbraco.Core.Manifest
|
||||
/// Represents a content app definition, parsed from a manifest.
|
||||
/// </summary>
|
||||
[DataContract(Name = "appdef", Namespace = "")]
|
||||
public class ManifestContentAppDefinition : IContentAppDefinition
|
||||
public class ManifestContentAppDefinition
|
||||
{
|
||||
private string _view;
|
||||
private ContentApp _app;
|
||||
private ShowRule[] _showRules;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the content app.
|
||||
@@ -83,132 +81,5 @@ namespace Umbraco.Core.Manifest
|
||||
[DataMember(Name = "show")]
|
||||
public string[] Show { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public ContentApp GetContentAppFor(object o, IEnumerable<IReadOnlyUserGroup> userGroups)
|
||||
{
|
||||
string partA, partB;
|
||||
|
||||
switch (o)
|
||||
{
|
||||
case IContent content:
|
||||
partA = "content";
|
||||
partB = content.ContentType.Alias;
|
||||
break;
|
||||
|
||||
case IMedia media:
|
||||
partA = "media";
|
||||
partB = media.ContentType.Alias;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
var rules = _showRules ?? (_showRules = ShowRule.Parse(Show).ToArray());
|
||||
var userGroupsList = userGroups.ToList();
|
||||
|
||||
var okRole = false;
|
||||
var hasRole = false;
|
||||
var okType = false;
|
||||
var hasType = false;
|
||||
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if (rule.PartA.InvariantEquals("role"))
|
||||
{
|
||||
// if roles have been ok-ed already, skip the rule
|
||||
if (okRole)
|
||||
continue;
|
||||
|
||||
// remember we have role rules
|
||||
hasRole = true;
|
||||
|
||||
foreach (var group in userGroupsList)
|
||||
{
|
||||
// if the entry does not apply, skip
|
||||
if (!rule.Matches("role", group.Alias))
|
||||
continue;
|
||||
|
||||
// if the entry applies,
|
||||
// if it's an exclude entry, exit, do not display the content app
|
||||
if (!rule.Show)
|
||||
return null;
|
||||
|
||||
// else ok to display, remember roles are ok, break from userGroupsList
|
||||
okRole = rule.Show;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // it is a type rule
|
||||
{
|
||||
// if type has been ok-ed already, skip the rule
|
||||
if (okType)
|
||||
continue;
|
||||
|
||||
// remember we have type rules
|
||||
hasType = true;
|
||||
|
||||
// if the entry does not apply, skip it
|
||||
if (!rule.Matches(partA, partB))
|
||||
continue;
|
||||
|
||||
// if the entry applies,
|
||||
// if it's an exclude entry, exit, do not display the content app
|
||||
if (!rule.Show)
|
||||
return null;
|
||||
|
||||
// else ok to display, remember type rules are ok
|
||||
okType = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if roles rules are specified but not ok,
|
||||
// or if type roles are specified but not ok,
|
||||
// cannot display the content app
|
||||
if ((hasRole && !okRole) || (hasType && !okType))
|
||||
return null;
|
||||
|
||||
// else
|
||||
// content app can be displayed
|
||||
return _app ?? (_app = new ContentApp
|
||||
{
|
||||
Alias = Alias,
|
||||
Name = Name,
|
||||
Icon = Icon,
|
||||
View = View,
|
||||
Weight = Weight
|
||||
});
|
||||
}
|
||||
|
||||
private class ShowRule
|
||||
{
|
||||
private static readonly Regex ShowRegex = new Regex("^([+-])?([a-z]+)/([a-z0-9_]+|\\*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public bool Show { get; private set; }
|
||||
public string PartA { get; private set; }
|
||||
public string PartB { get; private set; }
|
||||
|
||||
public bool Matches(string partA, string partB)
|
||||
{
|
||||
return (PartA == "*" || PartA.InvariantEquals(partA)) && (PartB == "*" || PartB.InvariantEquals(partB));
|
||||
}
|
||||
|
||||
public static IEnumerable<ShowRule> Parse(string[] rules)
|
||||
{
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
var match = ShowRegex.Match(rule);
|
||||
if (!match.Success)
|
||||
throw new FormatException($"Illegal 'show' entry \"{rule}\" in manifest.");
|
||||
|
||||
yield return new ShowRule
|
||||
{
|
||||
Show = match.Groups[1].Value != "-",
|
||||
PartA = match.Groups[2].Value,
|
||||
PartB = match.Groups[3].Value
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
// contentApps: [
|
||||
// {
|
||||
// name: 'App Name', // required
|
||||
// alias: 'appAlias', // required
|
||||
// weight: 0, // optional, default is 0, use values between -99 and +99
|
||||
// icon: 'icon.app', // required
|
||||
// view: 'path/view.htm', // required
|
||||
// show: [ // optional, default is always show
|
||||
// '-content/foo', // hide for content type 'foo'
|
||||
// '+content/*', // show for all other content types
|
||||
// '+media/*', // show for all media types
|
||||
// '+role/admin' // show for admin users. Role based permissions will override others.
|
||||
// ]
|
||||
// },
|
||||
// ...
|
||||
// ]
|
||||
|
||||
/// <summary>
|
||||
/// Represents a content app definition, parsed from a manifest.
|
||||
/// </summary>
|
||||
public class ManifestContentAppFactory : IContentAppFactory
|
||||
{
|
||||
private readonly ManifestContentAppDefinition _definition;
|
||||
|
||||
|
||||
public ManifestContentAppFactory(ManifestContentAppDefinition definition)
|
||||
{
|
||||
_definition = definition;
|
||||
}
|
||||
|
||||
private ContentApp _app;
|
||||
private ShowRule[] _showRules;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ContentApp GetContentAppFor(object o,IEnumerable<IReadOnlyUserGroup> userGroups)
|
||||
{
|
||||
string partA, partB;
|
||||
|
||||
switch (o)
|
||||
{
|
||||
case IContent content:
|
||||
partA = "content";
|
||||
partB = content.ContentType.Alias;
|
||||
break;
|
||||
|
||||
case IMedia media:
|
||||
partA = "media";
|
||||
partB = media.ContentType.Alias;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
var rules = _showRules ?? (_showRules = ShowRule.Parse(_definition.Show).ToArray());
|
||||
var userGroupsList = userGroups.ToList();
|
||||
|
||||
var okRole = false;
|
||||
var hasRole = false;
|
||||
var okType = false;
|
||||
var hasType = false;
|
||||
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if (rule.PartA.InvariantEquals("role"))
|
||||
{
|
||||
// if roles have been ok-ed already, skip the rule
|
||||
if (okRole)
|
||||
continue;
|
||||
|
||||
// remember we have role rules
|
||||
hasRole = true;
|
||||
|
||||
foreach (var group in userGroupsList)
|
||||
{
|
||||
// if the entry does not apply, skip
|
||||
if (!rule.Matches("role", group.Alias))
|
||||
continue;
|
||||
|
||||
// if the entry applies,
|
||||
// if it's an exclude entry, exit, do not display the content app
|
||||
if (!rule.Show)
|
||||
return null;
|
||||
|
||||
// else ok to display, remember roles are ok, break from userGroupsList
|
||||
okRole = rule.Show;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // it is a type rule
|
||||
{
|
||||
// if type has been ok-ed already, skip the rule
|
||||
if (okType)
|
||||
continue;
|
||||
|
||||
// remember we have type rules
|
||||
hasType = true;
|
||||
|
||||
// if the entry does not apply, skip it
|
||||
if (!rule.Matches(partA, partB))
|
||||
continue;
|
||||
|
||||
// if the entry applies,
|
||||
// if it's an exclude entry, exit, do not display the content app
|
||||
if (!rule.Show)
|
||||
return null;
|
||||
|
||||
// else ok to display, remember type rules are ok
|
||||
okType = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if roles rules are specified but not ok,
|
||||
// or if type roles are specified but not ok,
|
||||
// cannot display the content app
|
||||
if ((hasRole && !okRole) || (hasType && !okType))
|
||||
return null;
|
||||
|
||||
// else
|
||||
// content app can be displayed
|
||||
return _app ?? (_app = new ContentApp
|
||||
{
|
||||
Alias = _definition.Alias,
|
||||
Name = _definition.Name,
|
||||
Icon = _definition.Icon,
|
||||
View = _definition.View,
|
||||
Weight = _definition.Weight
|
||||
});
|
||||
}
|
||||
|
||||
private class ShowRule
|
||||
{
|
||||
private static readonly Regex ShowRegex = new Regex("^([+-])?([a-z]+)/([a-z0-9_]+|\\*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public bool Show { get; private set; }
|
||||
public string PartA { get; private set; }
|
||||
public string PartB { get; private set; }
|
||||
|
||||
public bool Matches(string partA, string partB)
|
||||
{
|
||||
return (PartA == "*" || PartA.InvariantEquals(partA)) && (PartB == "*" || PartB.InvariantEquals(partB));
|
||||
}
|
||||
|
||||
public static IEnumerable<ShowRule> Parse(string[] rules)
|
||||
{
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
var match = ShowRegex.Match(rule);
|
||||
if (!match.Success)
|
||||
throw new FormatException($"Illegal 'show' entry \"{rule}\" in manifest.");
|
||||
|
||||
yield return new ShowRule
|
||||
{
|
||||
Show = match.Groups[1].Value != "-",
|
||||
PartA = match.Groups[2].Value,
|
||||
PartB = match.Groups[3].Value
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ namespace Umbraco.Core.Manifest
|
||||
var propertyEditors = new List<IDataEditor>();
|
||||
var parameterEditors = new List<IDataEditor>();
|
||||
var gridEditors = new List<GridEditor>();
|
||||
var contentApps = new List<IContentAppDefinition>();
|
||||
var contentApps = new List<ManifestContentAppDefinition>();
|
||||
var dashboards = new List<ManifestDashboardDefinition>();
|
||||
|
||||
foreach (var manifest in manifests)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Manifest
|
||||
public GridEditor[] GridEditors { get; set; } = Array.Empty<GridEditor>();
|
||||
|
||||
[JsonProperty("contentApps")]
|
||||
public IContentAppDefinition[] ContentApps { get; set; } = Array.Empty<IContentAppDefinition>();
|
||||
public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty<ManifestContentAppDefinition>();
|
||||
|
||||
[JsonProperty("dashboards")]
|
||||
public ManifestDashboardDefinition[] Dashboards { get; set; } = Array.Empty<ManifestDashboardDefinition>();
|
||||
|
||||
+3
-1
@@ -1,13 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Core.Models.ContentEditing
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a content app definition.
|
||||
/// </summary>
|
||||
public interface IContentAppDefinition
|
||||
public interface IContentAppFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the content app for an object.
|
||||
@@ -336,6 +336,7 @@
|
||||
<Compile Include="Manifest\ContentAppDefinitionConverter.cs" />
|
||||
<Compile Include="Manifest\DashboardAccessRuleConverter.cs" />
|
||||
<Compile Include="Manifest\ManifestContentAppDefinition.cs" />
|
||||
<Compile Include="Manifest\ManifestContentAppFactory.cs" />
|
||||
<Compile Include="Manifest\ManifestDashboardDefinition.cs" />
|
||||
<Compile Include="Migrations\IncompleteMigrationExpressionException.cs" />
|
||||
<Compile Include="Migrations\MigrationBase_Extra.cs" />
|
||||
@@ -380,7 +381,7 @@
|
||||
<Compile Include="Models\ConsentExtensions.cs" />
|
||||
<Compile Include="Models\ConsentState.cs" />
|
||||
<Compile Include="Models\ContentEditing\ContentApp.cs" />
|
||||
<Compile Include="Models\ContentEditing\IContentAppDefinition.cs" />
|
||||
<Compile Include="Models\ContentEditing\IContentAppFactory.cs" />
|
||||
<Compile Include="Models\ContentSchedule.cs" />
|
||||
<Compile Include="Models\ContentScheduleAction.cs" />
|
||||
<Compile Include="Models\ContentScheduleCollection.cs" />
|
||||
|
||||
@@ -67,7 +67,8 @@ namespace Umbraco.Tests.Manifest
|
||||
private void AssertDefinition(object source, bool expected, string[] show, IReadOnlyUserGroup[] groups)
|
||||
{
|
||||
var definition = JsonConvert.DeserializeObject<ManifestContentAppDefinition>("{" + (show.Length == 0 ? "" : " \"show\": [" + string.Join(",", show.Select(x => "\"" + x + "\"")) + "] ") + "}");
|
||||
var app = definition.GetContentAppFor(source, groups);
|
||||
var factory = new ManifestContentAppFactory(definition);
|
||||
var app = factory.GetContentAppFor(source, groups);
|
||||
if (expected)
|
||||
Assert.IsNotNull(app);
|
||||
else
|
||||
|
||||
@@ -5,15 +5,17 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
public class ContentAppDefinitionCollection : BuilderCollectionBase<IContentAppDefinition>
|
||||
public class ContentAppDefinitionCollection : BuilderCollectionBase<IContentAppFactory>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IContentAppFactory _factory;
|
||||
|
||||
public ContentAppDefinitionCollection(IEnumerable<IContentAppDefinition> items, ILogger logger)
|
||||
public ContentAppDefinitionCollection(IEnumerable<IContentAppFactory> items, ILogger logger)
|
||||
: base(items)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -32,7 +34,10 @@ namespace Umbraco.Web.ContentApps
|
||||
public IEnumerable<ContentApp> GetContentAppsFor(object o, IEnumerable<IReadOnlyUserGroup> userGroups=null)
|
||||
{
|
||||
var roles = GetCurrentUserGroups();
|
||||
var apps = this.Select(x => x.GetContentAppFor(o, roles)).WhereNotNull().OrderBy(x => x.Weight).ToList();
|
||||
|
||||
|
||||
var apps = Enumerable.Empty<ContentApp>();// this.Select(x => x.GetContentAppFor(o, roles)).WhereNotNull().OrderBy(x => x.Weight).ToList();
|
||||
|
||||
|
||||
var aliases = new HashSet<string>();
|
||||
List<string> dups = null;
|
||||
|
||||
@@ -5,14 +5,16 @@ using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
public class ContentAppDefinitionCollectionBuilder : OrderedCollectionBuilderBase<ContentAppDefinitionCollectionBuilder, ContentAppDefinitionCollection, IContentAppDefinition>
|
||||
public class ContentAppDefinitionCollectionBuilder : OrderedCollectionBuilderBase<ContentAppDefinitionCollectionBuilder, ContentAppDefinitionCollection, IContentAppFactory>
|
||||
{
|
||||
public ContentAppDefinitionCollectionBuilder(IServiceContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
protected override ContentAppDefinitionCollectionBuilder This => this;
|
||||
|
||||
@@ -25,14 +27,14 @@ namespace Umbraco.Web.ContentApps
|
||||
return new ContentAppDefinitionCollection(CreateItems(), logger);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IContentAppDefinition> CreateItems(params object[] args)
|
||||
protected override IEnumerable<IContentAppFactory> CreateItems(params object[] args)
|
||||
{
|
||||
// get the manifest parser just-in-time - injecting it in the ctor would mean that
|
||||
// simply getting the builder in order to configure the collection, would require
|
||||
// its dependencies too, and that can create cycles or other oddities
|
||||
var manifestParser = Container.GetInstance<ManifestParser>();
|
||||
|
||||
return base.CreateItems(args).Concat(manifestParser.Manifest.ContentApps);
|
||||
return base.CreateItems(args).Concat(manifestParser.Manifest.ContentApps.Select(x=>new ManifestContentAppFactory(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
internal class ContentEditorContentAppDefinition : IContentAppDefinition
|
||||
internal class ContentEditorContentAppFactory : IContentAppFactory
|
||||
{
|
||||
// see note on ContentApp
|
||||
private const int Weight = -100;
|
||||
+1
-1
@@ -6,7 +6,7 @@ using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
public class ContentInfoContentAppDefinition : IContentAppDefinition
|
||||
public class ContentInfoContentAppFactory : IContentAppFactory
|
||||
{
|
||||
// see note on ContentApp
|
||||
private const int Weight = +100;
|
||||
+2
-2
@@ -9,7 +9,7 @@ using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
internal class ListViewContentAppDefinition : IContentAppDefinition
|
||||
internal class ListViewContentAppFactory : IContentAppFactory
|
||||
{
|
||||
// see note on ContentApp
|
||||
private const int Weight = -666;
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Web.ContentApps
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
|
||||
public ListViewContentAppDefinition(IDataTypeService dataTypeService, PropertyEditorCollection propertyEditors)
|
||||
public ListViewContentAppFactory(IDataTypeService dataTypeService, PropertyEditorCollection propertyEditors)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_propertyEditors = propertyEditors;
|
||||
@@ -234,7 +234,7 @@ namespace Umbraco.Web.Editors
|
||||
public ContentItemDisplay GetRecycleBin()
|
||||
{
|
||||
var apps = new List<ContentApp>();
|
||||
apps.Add(ListViewContentAppDefinition.CreateContentApp(Services.DataTypeService, _propertyEditors, "recycleBin", "content", Core.Constants.DataTypes.DefaultMembersListView));
|
||||
apps.Add(ListViewContentAppFactory.CreateContentApp(Services.DataTypeService, _propertyEditors, "recycleBin", "content", Core.Constants.DataTypes.DefaultMembersListView));
|
||||
apps[0].Active = true;
|
||||
var display = new ContentItemDisplay
|
||||
{
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Umbraco.Web.Editors
|
||||
public MediaItemDisplay GetRecycleBin()
|
||||
{
|
||||
var apps = new List<ContentApp>();
|
||||
apps.Add(ListViewContentAppDefinition.CreateContentApp(Services.DataTypeService, _propertyEditors, "recycleBin", "media", Core.Constants.DataTypes.DefaultMediaListView));
|
||||
apps.Add(ListViewContentAppFactory.CreateContentApp(Services.DataTypeService, _propertyEditors, "recycleBin", "media", Core.Constants.DataTypes.DefaultMediaListView));
|
||||
apps[0].Active = true;
|
||||
var display = new MediaItemDisplay
|
||||
{
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Umbraco.Web.Editors
|
||||
var name = foundType != null ? foundType.Name : listName;
|
||||
|
||||
var apps = new List<ContentApp>();
|
||||
apps.Add(ListViewContentAppDefinition.CreateContentApp(Services.DataTypeService, _propertyEditors, listName, "member", Core.Constants.DataTypes.DefaultMembersListView));
|
||||
apps.Add(ListViewContentAppFactory.CreateContentApp(Services.DataTypeService, _propertyEditors, listName, "member", Core.Constants.DataTypes.DefaultMembersListView));
|
||||
apps[0].Active = true;
|
||||
|
||||
var display = new MemberListDisplay
|
||||
|
||||
@@ -207,9 +207,9 @@ namespace Umbraco.Web.Runtime
|
||||
|
||||
// register known content apps
|
||||
composition.Container.RegisterCollectionBuilder<ContentAppDefinitionCollectionBuilder>()
|
||||
.Append<ListViewContentAppDefinition>()
|
||||
.Append<ContentEditorContentAppDefinition>()
|
||||
.Append<ContentInfoContentAppDefinition>();
|
||||
.Append<ListViewContentAppFactory>()
|
||||
.Append<ContentEditorContentAppFactory>()
|
||||
.Append<ContentInfoContentAppFactory>();
|
||||
}
|
||||
|
||||
internal void Initialize(
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
<Compile Include="Cache\ContentCacheRefresher.cs" />
|
||||
<Compile Include="Cache\UserGroupCacheRefresher.cs" />
|
||||
<Compile Include="Components\BackOfficeUserAuditEventsComponent.cs" />
|
||||
<Compile Include="ContentApps\ListViewContentAppFactory.cs" />
|
||||
<Compile Include="Editors\BackOfficePreviewModel.cs" />
|
||||
<Compile Include="Logging\WebProfiler.cs" />
|
||||
<Compile Include="Logging\WebProfilerComponent.cs" />
|
||||
@@ -155,9 +156,8 @@
|
||||
<Compile Include="Models\Mapping\MappingOperationOptionsExtensions.cs" />
|
||||
<Compile Include="ContentApps\ContentAppDefinitionCollection.cs" />
|
||||
<Compile Include="ContentApps\ContentAppDefinitionCollectionBuilder.cs" />
|
||||
<Compile Include="ContentApps\ContentEditorContentAppDefinition.cs" />
|
||||
<Compile Include="ContentApps\ContentInfoContentAppDefinition.cs" />
|
||||
<Compile Include="ContentApps\ListViewContentAppDefinition.cs" />
|
||||
<Compile Include="ContentApps\ContentEditorContentAppFactory.cs" />
|
||||
<Compile Include="ContentApps\ContentInfoContentAppFactory.cs" />
|
||||
<Compile Include="Models\Mapping\ScheduledPublishDateResolver.cs" />
|
||||
<Compile Include="Security\ActiveDirectoryBackOfficeUserPasswordChecker.cs" />
|
||||
<Compile Include="Security\BackOfficeClaimsIdentityFactory.cs" />
|
||||
|
||||
Reference in New Issue
Block a user