Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c6671f7f8e | |||
| 44c966bd44 | |||
| 57e58c6cf7 | |||
| 34e45abcc7 | |||
| b3497011e8 | |||
| a398881fa1 | |||
| 2cf3a7831c | |||
| 0138091a6c | |||
| 6c0fb2f849 | |||
| e495faf83c | |||
| 8721423f40 | |||
| 49b3351c72 | |||
| faef449750 | |||
| 4a24064783 | |||
| 0ab84fc443 | |||
| fca74ad8d7 | |||
| 7bc7dba86d | |||
| ca75a25802 | |||
| ece31733a9 | |||
| 28a8027179 | |||
| a97604d6c4 | |||
| 308f929f7b | |||
| c8d7df1515 | |||
| 2c795662d2 | |||
| 8a43e3a87e | |||
| 210e43fcb0 | |||
| beb8c7ac7c | |||
| 2f8979bbc3 | |||
| a8ed7f2c17 | |||
| 1c6bf55e5d | |||
| c246044ac7 | |||
| 5126521d37 | |||
| 27223738c6 | |||
| 968463912a | |||
| 05c6b856f9 | |||
| 6fe3089207 | |||
| 06b136fdf6 | |||
| c6246b5404 | |||
| 3062f40ef5 | |||
| dcd0d38419 | |||
| c01a8f8f13 | |||
| da71a94c39 | |||
| f6413af3f4 | |||
| 440e649d6d | |||
| 47dcd37d1d | |||
| d60fc63e78 | |||
| b0c4042e87 | |||
| da525513a3 | |||
| 2ac5e61e44 | |||
| 101a8b6c78 | |||
| f7a10e3a15 | |||
| 4e0dd728a8 | |||
| 320ccf8105 | |||
| 62f924a757 | |||
| c47a08b553 | |||
| de9241bcf5 | |||
| 7c03fe3c1f | |||
| 82eb241119 | |||
| 1073e6257c | |||
| bc3e4847fe | |||
| 1a7251909c | |||
| 61a18297d9 | |||
| bdd413f9ee | |||
| fd8ca35e63 | |||
| fdd9aee773 | |||
| 3c2a92d3b6 | |||
| cf49e6160a | |||
| ec93030e21 | |||
| 1d49c8626e | |||
| 89bb94aa1a | |||
| 03a4b75176 | |||
| 943b54dcf7 | |||
| 39bd18ec1a | |||
| e93ddff46b | |||
| 3144b51c91 | |||
| e92f68d040 | |||
| 469054e9b3 | |||
| d17022d87d | |||
| 6865629090 | |||
| a4749f201d | |||
| ad90264ef1 | |||
| 9ba7e7742a | |||
| 6473f600c7 | |||
| 6329dfa629 | |||
| 2cd0173534 | |||
| a0bcfeddcc | |||
| c4b5483d8c | |||
| 7557c584d8 |
@@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue
|
||||
template below. The more details you can give us, the easier it will be for us
|
||||
to determine the cause of a problem.
|
||||
|
||||
See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md
|
||||
See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
|
||||
|
||||
-->
|
||||
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.1.1")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.1")]
|
||||
[assembly: AssemblyFileVersion("8.2.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.2.0")]
|
||||
|
||||
@@ -203,6 +203,24 @@ namespace Umbraco.Core
|
||||
/// <remarks>Must be a valid <see cref="ValueTypes"/> value.</remarks>
|
||||
public const string DataValueType = "umbracoDataValueType";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines Umbraco's built-in property editor groups.
|
||||
/// </summary>
|
||||
public static class Groups
|
||||
{
|
||||
public const string Common = "Common";
|
||||
|
||||
public const string Lists = "Lists";
|
||||
|
||||
public const string Media = "Media";
|
||||
|
||||
public const string People = "People";
|
||||
|
||||
public const string Pickers = "Pickers";
|
||||
|
||||
public const string RichContent = "Rich Content";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
class DropDownFlexiblePreValueMigrator : IPreValueMigrator
|
||||
{
|
||||
public bool CanMigrate(string editorAlias)
|
||||
=> editorAlias == "Umbraco.DropDown.Flexible";
|
||||
|
||||
public virtual string GetNewAlias(string editorAlias)
|
||||
=> null;
|
||||
|
||||
public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary<string, PreValueDto> preValues)
|
||||
{
|
||||
var config = new DropDownFlexibleConfiguration();
|
||||
foreach (var preValue in preValues.Values)
|
||||
{
|
||||
if (preValue.Alias == "multiple")
|
||||
{
|
||||
config.Multiple = (preValue.Value == "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
config.Items.Add(new ValueListConfiguration.ValueListItem { Id = preValue.Id, Value = preValue.Value });
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ public class PreValueMigratorComposer : ICoreComposer
|
||||
.Append<NestedContentPreValueMigrator>()
|
||||
.Append<DecimalPreValueMigrator>()
|
||||
.Append<ListViewPreValueMigrator>()
|
||||
.Append<DropDownFlexiblePreValueMigrator>()
|
||||
.Append<ValueListPreValueMigrator>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
private readonly string[] _editors =
|
||||
{
|
||||
"Umbraco.RadioButtonList",
|
||||
"Umbraco.CheckBoxList",
|
||||
"Umbraco.DropDown",
|
||||
"Umbraco.DropdownlistPublishingKeys",
|
||||
"Umbraco.DropDownMultiple",
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets of sets the alias of the property type.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Alias
|
||||
public virtual string Alias
|
||||
{
|
||||
get => _alias;
|
||||
set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, nameof(Alias));
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
// defaults
|
||||
Type = type;
|
||||
Icon = Constants.Icons.PropertyEditor;
|
||||
Group = "common";
|
||||
Group = Constants.PropertyEditors.Groups.Common;
|
||||
|
||||
// assign properties based on the attribute, if it is found
|
||||
Attribute = GetType().GetCustomAttribute<DataEditorAttribute>(false);
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// Gets or sets an optional group.
|
||||
/// </summary>
|
||||
/// <remarks>The group can be used for example to group the editors by category.</remarks>
|
||||
public string Group { get; set; } = "common";
|
||||
public string Group { get; set; } = Constants.PropertyEditors.Groups.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the value editor is deprecated.
|
||||
|
||||
@@ -5,7 +5,11 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a property editor for label properties.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Label, "Label", "readonlyvalue", Icon = "icon-readonly")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Label,
|
||||
"Label",
|
||||
"readonlyvalue",
|
||||
Icon = "icon-readonly")]
|
||||
public class LabelPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -241,6 +241,7 @@
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DefaultPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RenamingPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RichTextPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DropDownFlexiblePreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
|
||||
<Compile Include="Models\Entities\EntityExtensions.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorBase.cs" />
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Umbraco.Examine
|
||||
continue;
|
||||
case string strVal:
|
||||
{
|
||||
if (strVal.IsNullOrWhiteSpace()) return;
|
||||
if (strVal.IsNullOrWhiteSpace()) continue;
|
||||
var key = $"{keyVal.Key}{cultureSuffix}";
|
||||
if (values.TryGetValue(key, out var v))
|
||||
values[key] = new List<object>(v) { val }.ToArray();
|
||||
|
||||
@@ -48,6 +48,31 @@ namespace Umbraco.Examine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all index fields that are culture specific (suffixed) or invariant
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="culture"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> GetCultureAndInvariantFields(this IUmbracoIndex index, string culture)
|
||||
{
|
||||
var allFields = index.GetFields();
|
||||
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
foreach (var field in allFields)
|
||||
{
|
||||
var match = CultureIsoCodeFieldNameMatchExpression.Match(field);
|
||||
if (match.Success && match.Groups.Count == 3 && culture.InvariantEquals(match.Groups[2].Value))
|
||||
{
|
||||
yield return field; //matches this culture field
|
||||
}
|
||||
else if (!match.Success)
|
||||
{
|
||||
yield return field; //matches no culture field (invariant)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool TryParseLuceneQuery(string query)
|
||||
{
|
||||
// TODO: I'd assume there would be a more strict way to parse the query but not that i can find yet, for now we'll
|
||||
@@ -77,7 +102,7 @@ namespace Umbraco.Examine
|
||||
/// <remarks>
|
||||
/// This is not thread safe, use with care
|
||||
/// </remarks>
|
||||
internal static void UnlockLuceneIndexes(this IExamineManager examineManager, ILogger logger)
|
||||
internal static void ConfigureLuceneIndexes(this IExamineManager examineManager, ILogger logger, bool disableExamineIndexing)
|
||||
{
|
||||
foreach (var luceneIndexer in examineManager.Indexes.OfType<LuceneIndex>())
|
||||
{
|
||||
@@ -86,6 +111,8 @@ namespace Umbraco.Examine
|
||||
//that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
|
||||
luceneIndexer.WaitForIndexQueueOnShutdown = false;
|
||||
|
||||
if (disableExamineIndexing) continue; //exit if not enabled, we don't need to unlock them if we're not maindom
|
||||
|
||||
//we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that
|
||||
//the indexes are not operational unless MainDom is true
|
||||
var dir = luceneIndexer.GetLuceneDirectory();
|
||||
|
||||
@@ -81,6 +81,19 @@ namespace Umbraco.Tests.Routing
|
||||
Assert.AreEqual(expected, resolvedUrl);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Media_Url_Returns_Absolute_Url_If_Stored_Url_Is_Absolute()
|
||||
{
|
||||
const string expected = "http://localhost/media/rfeiw584/test.jpg";
|
||||
|
||||
var umbracoContext = GetUmbracoContext("http://localhost", mediaUrlProviders: new[] { _mediaUrlProvider });
|
||||
var publishedContent = CreatePublishedContent(Constants.PropertyEditors.Aliases.UploadField, expected, null);
|
||||
|
||||
var resolvedUrl = umbracoContext.UrlProvider.GetMediaUrl(publishedContent, UrlMode.Relative);
|
||||
|
||||
Assert.AreEqual(expected, resolvedUrl);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Media_Url_Returns_Empty_String_When_PropertyType_Is_Not_Supported()
|
||||
{
|
||||
|
||||
@@ -25,19 +25,23 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
|
||||
public async Task<Tuple<HttpResponseMessage, string>> Execute(string controllerName, string actionName, HttpMethod method,
|
||||
HttpContent content = null,
|
||||
MediaTypeWithQualityHeaderValue mediaTypeHeader = null,
|
||||
bool assertOkResponse = true)
|
||||
bool assertOkResponse = true, object routeDefaults = null, string url = null)
|
||||
{
|
||||
if (mediaTypeHeader == null)
|
||||
{
|
||||
mediaTypeHeader = new MediaTypeWithQualityHeaderValue("application/json");
|
||||
}
|
||||
if (routeDefaults == null)
|
||||
{
|
||||
routeDefaults = new { controller = controllerName, action = actionName, id = RouteParameter.Optional };
|
||||
}
|
||||
|
||||
var startup = new TestStartup(
|
||||
configuration =>
|
||||
{
|
||||
configuration.Routes.MapHttpRoute("Default",
|
||||
routeTemplate: "{controller}/{action}/{id}",
|
||||
defaults: new { controller = controllerName, action = actionName, id = RouteParameter.Optional });
|
||||
defaults: routeDefaults);
|
||||
},
|
||||
_controllerFactory);
|
||||
|
||||
@@ -45,7 +49,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
|
||||
{
|
||||
var request = new HttpRequestMessage
|
||||
{
|
||||
RequestUri = new Uri("https://testserver/"),
|
||||
RequestUri = new Uri("https://testserver/" + (url ?? "")),
|
||||
Method = method
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using Lucene.Net.Store;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Tests.TestHelpers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Used for tests with Lucene so that each RAM directory is unique
|
||||
/// </summary>
|
||||
public class RandomIdRAMDirectory : RAMDirectory
|
||||
{
|
||||
private readonly string _lockId = Guid.NewGuid().ToString();
|
||||
public override string GetLockId()
|
||||
{
|
||||
return _lockId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,7 @@
|
||||
<Compile Include="Services\MemberGroupServiceTests.cs" />
|
||||
<Compile Include="Services\MediaTypeServiceTests.cs" />
|
||||
<Compile Include="Services\PropertyValidationServiceTests.cs" />
|
||||
<Compile Include="TestHelpers\RandomIdRamDirectory.cs" />
|
||||
<Compile Include="Testing\Objects\TestDataSource.cs" />
|
||||
<Compile Include="Published\PublishedSnapshotTestObjects.cs" />
|
||||
<Compile Include="Published\ModelTypeTests.cs" />
|
||||
@@ -242,6 +243,7 @@
|
||||
<Compile Include="Cache\FullDataSetCachePolicyTests.cs" />
|
||||
<Compile Include="Cache\SingleItemsOnlyCachePolicyTests.cs" />
|
||||
<Compile Include="Collections\DeepCloneableListTests.cs" />
|
||||
<Compile Include="Web\Controllers\AuthenticationControllerTests.cs" />
|
||||
<Compile Include="Web\Controllers\BackOfficeControllerUnitTests.cs" />
|
||||
<Compile Include="CoreThings\DelegateExtensionsTests.cs" />
|
||||
<Compile Include="Web\Controllers\ContentControllerTests.cs" />
|
||||
@@ -268,6 +270,7 @@
|
||||
<Compile Include="Strings\StylesheetHelperTests.cs" />
|
||||
<Compile Include="Strings\StringValidationTests.cs" />
|
||||
<Compile Include="Web\Mvc\ValidateUmbracoFormRouteStringAttributeTests.cs" />
|
||||
<Compile Include="Web\PublishedContentQueryTests.cs" />
|
||||
<Compile Include="Web\UmbracoHelperTests.cs" />
|
||||
<Compile Include="Membership\MembershipProviderBaseTests.cs" />
|
||||
<Compile Include="Membership\UmbracoServiceMembershipProviderTests.cs" />
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Http;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.ControllerTesting;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Features;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using IUser = Umbraco.Core.Models.Membership.IUser;
|
||||
|
||||
namespace Umbraco.Tests.Web.Controllers
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.None)]
|
||||
public class AuthenticationControllerTests : TestWithDatabaseBase
|
||||
{
|
||||
protected override void ComposeApplication(bool withApplication)
|
||||
{
|
||||
base.ComposeApplication(withApplication);
|
||||
//if (!withApplication) return;
|
||||
|
||||
// replace the true IUserService implementation with a mock
|
||||
// so that each test can configure the service to their liking
|
||||
Composition.RegisterUnique(f => Mock.Of<IUserService>());
|
||||
|
||||
// kill the true IEntityService too
|
||||
Composition.RegisterUnique(f => Mock.Of<IEntityService>());
|
||||
|
||||
Composition.RegisterUnique<UmbracoFeatures>();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetCurrentUser_Fips()
|
||||
{
|
||||
ApiController CtrlFactory(HttpRequestMessage message, IUmbracoContextAccessor umbracoContextAccessor, UmbracoHelper helper)
|
||||
{
|
||||
//setup some mocks
|
||||
var userServiceMock = Mock.Get(Current.Services.UserService);
|
||||
userServiceMock.Setup(service => service.GetUserById(It.IsAny<int>()))
|
||||
.Returns(() => null);
|
||||
|
||||
if (Thread.GetDomain().GetData(".appPath") != null)
|
||||
{
|
||||
HttpContext.Current = new HttpContext(new SimpleWorkerRequest("", "", new StringWriter()));
|
||||
}
|
||||
else
|
||||
{
|
||||
var baseDir = IOHelper.MapPath("", false).TrimEnd(IOHelper.DirSepChar);
|
||||
HttpContext.Current = new HttpContext(new SimpleWorkerRequest("/", baseDir, "", "", new StringWriter()));
|
||||
}
|
||||
IOHelper.ForceNotHosted = true;
|
||||
var usersController = new AuthenticationController(
|
||||
Factory.GetInstance<IGlobalSettings>(),
|
||||
umbracoContextAccessor,
|
||||
Factory.GetInstance<ISqlContext>(),
|
||||
Factory.GetInstance<ServiceContext>(),
|
||||
Factory.GetInstance<AppCaches>(),
|
||||
Factory.GetInstance<IProfilingLogger>(),
|
||||
Factory.GetInstance<IRuntimeState>(),
|
||||
helper);
|
||||
return usersController;
|
||||
}
|
||||
|
||||
Mock.Get(Current.SqlContext)
|
||||
.Setup(x => x.Query<IUser>())
|
||||
.Returns(new Query<IUser>(Current.SqlContext));
|
||||
|
||||
var syntax = new SqlCeSyntaxProvider();
|
||||
|
||||
Mock.Get(Current.SqlContext)
|
||||
.Setup(x => x.SqlSyntax)
|
||||
.Returns(syntax);
|
||||
|
||||
var mappers = new MapperCollection(new[]
|
||||
{
|
||||
new UserMapper(new Lazy<ISqlContext>(() => Current.SqlContext), new ConcurrentDictionary<Type, ConcurrentDictionary<string, string>>())
|
||||
});
|
||||
|
||||
Mock.Get(Current.SqlContext)
|
||||
.Setup(x => x.Mappers)
|
||||
.Returns(mappers);
|
||||
|
||||
// Testing what happens if the system were configured to only use FIPS-compliant algorithms
|
||||
var typ = typeof(CryptoConfig);
|
||||
var flds = typ.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
||||
var haveFld = flds.FirstOrDefault(f => f.Name == "s_haveFipsAlgorithmPolicy");
|
||||
var isFld = flds.FirstOrDefault(f => f.Name == "s_fipsAlgorithmPolicy");
|
||||
var originalFipsValue = CryptoConfig.AllowOnlyFipsAlgorithms;
|
||||
|
||||
try
|
||||
{
|
||||
if (!originalFipsValue)
|
||||
{
|
||||
haveFld.SetValue(null, true);
|
||||
isFld.SetValue(null, true);
|
||||
}
|
||||
|
||||
var runner = new TestRunner(CtrlFactory);
|
||||
var response = await runner.Execute("Authentication", "GetCurrentUser", HttpMethod.Get);
|
||||
|
||||
var obj = JsonConvert.DeserializeObject<UserDetail>(response.Item2);
|
||||
Assert.AreEqual(-1, obj.UserId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!originalFipsValue)
|
||||
{
|
||||
haveFld.SetValue(null, false);
|
||||
isFld.SetValue(null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Web.Http;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
@@ -155,7 +157,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var runner = new TestRunner(CtrlFactory);
|
||||
var response = await runner.Execute("Users", "GetPagedUsers", HttpMethod.Get);
|
||||
|
||||
var obj = JsonConvert.DeserializeObject<PagedResult<UserDisplay>>(response.Item2);
|
||||
var obj = JsonConvert.DeserializeObject<PagedResult<UserBasic>>(response.Item2);
|
||||
Assert.AreEqual(0, obj.TotalItems);
|
||||
}
|
||||
|
||||
@@ -190,9 +192,100 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var runner = new TestRunner(CtrlFactory);
|
||||
var response = await runner.Execute("Users", "GetPagedUsers", HttpMethod.Get);
|
||||
|
||||
var obj = JsonConvert.DeserializeObject<PagedResult<UserDisplay>>(response.Item2);
|
||||
var obj = JsonConvert.DeserializeObject<PagedResult<UserBasic>>(response.Item2);
|
||||
Assert.AreEqual(10, obj.TotalItems);
|
||||
Assert.AreEqual(10, obj.Items.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetPagedUsers_Fips()
|
||||
{
|
||||
await RunFipsTest("GetPagedUsers", mock =>
|
||||
{
|
||||
var users = MockedUser.CreateMulipleUsers(10);
|
||||
long outVal = 10;
|
||||
mock.Setup(service => service.GetAll(
|
||||
It.IsAny<long>(), It.IsAny<int>(), out outVal, It.IsAny<string>(), It.IsAny<Direction>(),
|
||||
It.IsAny<UserState[]>(), It.IsAny<string[]>(), It.IsAny<string[]>(), It.IsAny<IQuery<IUser>>()))
|
||||
.Returns(() => users);
|
||||
}, response =>
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<PagedResult<UserBasic>>(response.Item2);
|
||||
Assert.AreEqual(10, obj.TotalItems);
|
||||
Assert.AreEqual(10, obj.Items.Count());
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetById_Fips()
|
||||
{
|
||||
const int mockUserId = 1234;
|
||||
var user = MockedUser.CreateUser();
|
||||
|
||||
await RunFipsTest("GetById", mock =>
|
||||
{
|
||||
mock.Setup(service => service.GetUserById(1234))
|
||||
.Returns((int i) => i == mockUserId ? user : null);
|
||||
}, response =>
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<UserDisplay>(response.Item2);
|
||||
Assert.AreEqual(user.Username, obj.Username);
|
||||
Assert.AreEqual(user.Email, obj.Email);
|
||||
}, new { controller = "Users", action = "GetById" }, $"Users/GetById/{mockUserId}");
|
||||
}
|
||||
|
||||
|
||||
private async System.Threading.Tasks.Task RunFipsTest(string action, Action<Mock<IUserService>> userServiceSetup,
|
||||
Action<Tuple<HttpResponseMessage, string>> verification,
|
||||
object routeDefaults = null, string url = null)
|
||||
{
|
||||
ApiController CtrlFactory(HttpRequestMessage message, IUmbracoContextAccessor umbracoContextAccessor, UmbracoHelper helper)
|
||||
{
|
||||
//setup some mocks
|
||||
var userServiceMock = Mock.Get(Current.Services.UserService);
|
||||
userServiceSetup(userServiceMock);
|
||||
|
||||
var usersController = new UsersController(
|
||||
Factory.GetInstance<IGlobalSettings>(),
|
||||
umbracoContextAccessor,
|
||||
Factory.GetInstance<ISqlContext>(),
|
||||
Factory.GetInstance<ServiceContext>(),
|
||||
Factory.GetInstance<AppCaches>(),
|
||||
Factory.GetInstance<IProfilingLogger>(),
|
||||
Factory.GetInstance<IRuntimeState>(),
|
||||
helper);
|
||||
return usersController;
|
||||
}
|
||||
|
||||
// Testing what happens if the system were configured to only use FIPS-compliant algorithms
|
||||
var typ = typeof(CryptoConfig);
|
||||
var flds = typ.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
|
||||
var haveFld = flds.FirstOrDefault(f => f.Name == "s_haveFipsAlgorithmPolicy");
|
||||
var isFld = flds.FirstOrDefault(f => f.Name == "s_fipsAlgorithmPolicy");
|
||||
var originalFipsValue = CryptoConfig.AllowOnlyFipsAlgorithms;
|
||||
|
||||
try
|
||||
{
|
||||
if (!originalFipsValue)
|
||||
{
|
||||
haveFld.SetValue(null, true);
|
||||
isFld.SetValue(null, true);
|
||||
}
|
||||
|
||||
MockForGetPagedUsers();
|
||||
|
||||
var runner = new TestRunner(CtrlFactory);
|
||||
var response = await runner.Execute("Users", action, HttpMethod.Get, routeDefaults: routeDefaults, url: url);
|
||||
verification(response);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!originalFipsValue)
|
||||
{
|
||||
haveFld.SetValue(null, false);
|
||||
isFld.SetValue(null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Examine;
|
||||
using Examine.LuceneEngine.Providers;
|
||||
using Lucene.Net.Store;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Tests.Web
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedContentQueryTests
|
||||
{
|
||||
|
||||
private class TestIndex : LuceneIndex, IUmbracoIndex
|
||||
{
|
||||
private readonly string[] _fieldNames;
|
||||
|
||||
public TestIndex(string name, Directory luceneDirectory, string[] fieldNames)
|
||||
: base(name, luceneDirectory, null, null, null, null)
|
||||
{
|
||||
_fieldNames = fieldNames;
|
||||
}
|
||||
public bool EnableDefaultEventHandler => throw new NotImplementedException();
|
||||
public bool PublishedValuesOnly => throw new NotImplementedException();
|
||||
public IEnumerable<string> GetFields() => _fieldNames;
|
||||
}
|
||||
|
||||
private TestIndex CreateTestIndex(Directory luceneDirectory, string[] fieldNames)
|
||||
{
|
||||
var indexer = new TestIndex("TestIndex", luceneDirectory, fieldNames);
|
||||
|
||||
using (indexer.ProcessNonAsync())
|
||||
{
|
||||
//populate with some test data
|
||||
indexer.IndexItem(new ValueSet("1", "content", new Dictionary<string, object>
|
||||
{
|
||||
[fieldNames[0]] = "Hello world, there are products here",
|
||||
[UmbracoContentIndex.VariesByCultureFieldName] = "n"
|
||||
}));
|
||||
indexer.IndexItem(new ValueSet("2", "content", new Dictionary<string, object>
|
||||
{
|
||||
[fieldNames[1]] = "Hello world, there are products here",
|
||||
[UmbracoContentIndex.VariesByCultureFieldName] = "y"
|
||||
}));
|
||||
indexer.IndexItem(new ValueSet("3", "content", new Dictionary<string, object>
|
||||
{
|
||||
[fieldNames[2]] = "Hello world, there are products here",
|
||||
[UmbracoContentIndex.VariesByCultureFieldName] = "y"
|
||||
}));
|
||||
}
|
||||
|
||||
return indexer;
|
||||
}
|
||||
|
||||
private PublishedContentQuery CreatePublishedContentQuery(IIndex indexer)
|
||||
{
|
||||
var examineManager = new Mock<IExamineManager>();
|
||||
IIndex outarg = indexer;
|
||||
examineManager.Setup(x => x.TryGetIndex("TestIndex", out outarg)).Returns(true);
|
||||
|
||||
var contentCache = new Mock<IPublishedContentCache>();
|
||||
contentCache.Setup(x => x.GetById(It.IsAny<int>())).Returns((int intId) => Mock.Of<IPublishedContent>(x => x.Id == intId));
|
||||
var snapshot = Mock.Of<IPublishedSnapshot>(x => x.Content == contentCache.Object);
|
||||
var variationContext = new VariationContext();
|
||||
var variationContextAccessor = Mock.Of<IVariationContextAccessor>(x => x.VariationContext == variationContext);
|
||||
|
||||
return new PublishedContentQuery(snapshot, variationContextAccessor, examineManager.Object);
|
||||
}
|
||||
|
||||
[TestCase("fr-fr", ExpectedResult = "1, 3", TestName = "Search Culture: fr-fr. Must return both fr-fr and invariant results")]
|
||||
[TestCase("en-us", ExpectedResult = "1, 2", TestName = "Search Culture: en-us. Must return both en-us and invariant results")]
|
||||
[TestCase("*", ExpectedResult = "1, 2, 3", TestName = "Search Culture: *. Must return all cultures and all invariant results")]
|
||||
[TestCase(null, ExpectedResult = "1", TestName = "Search Culture: null. Must return only invariant results")]
|
||||
public string Search(string culture)
|
||||
{
|
||||
using (var luceneDir = new RandomIdRAMDirectory())
|
||||
{
|
||||
var fieldNames = new[] { "title", "title_en-us", "title_fr-fr" };
|
||||
using (var indexer = CreateTestIndex(luceneDir, fieldNames))
|
||||
{
|
||||
var pcq = CreatePublishedContentQuery(indexer);
|
||||
|
||||
var results = pcq.Search("Products", culture, "TestIndex");
|
||||
|
||||
var ids = results.Select(x => x.Content.Id).ToArray();
|
||||
|
||||
return string.Join(", ", ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Examine.LuceneEngine;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Analysis.Standard;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
@@ -13,18 +16,19 @@ using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Tests.Web
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class UmbracoHelperTests
|
||||
{
|
||||
{
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Current.Reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ------- Int32 conversion tests
|
||||
[Test]
|
||||
public static void Converting_Boxed_34_To_An_Int_Returns_34()
|
||||
|
||||
@@ -23,7 +23,7 @@ module.exports = function(files, out) {
|
||||
// sort files in stream by path or any custom sort comparator
|
||||
task = task.pipe(babel())
|
||||
.pipe(sort())
|
||||
.pipe(embedTemplates({ basePath: "./src/" }))
|
||||
.pipe(embedTemplates({ basePath: "./src/", minimize:{ loose: true } }))
|
||||
.pipe(concat(out))
|
||||
.pipe(wrap('(function(){\n%= body %\n})();'))
|
||||
.pipe(gulp.dest(config.root + config.targets.js));
|
||||
|
||||
@@ -94,6 +94,10 @@
|
||||
content.apps[0].active = true;
|
||||
$scope.appChanged(content.apps[0]);
|
||||
}
|
||||
// otherwise make sure the save options are up to date with the current content state
|
||||
else {
|
||||
createButtons($scope.content);
|
||||
}
|
||||
|
||||
editorState.set(content);
|
||||
|
||||
|
||||
+6
-12
@@ -101,14 +101,14 @@ angular.module('umbraco.directives')
|
||||
var eventBindings = [];
|
||||
|
||||
function oneTimeClick(event) {
|
||||
// ignore clicks on button groups toggles (i.e. the save and publish button)
|
||||
var parents = $(event.target).closest("[data-element='button-group-toggle']");
|
||||
if (parents.length > 0) {
|
||||
return;
|
||||
}
|
||||
var el = event.target.nodeName;
|
||||
|
||||
//ignore link and button clicks
|
||||
var els = ["INPUT", "A", "BUTTON"];
|
||||
if (els.indexOf(el) >= 0) { return; }
|
||||
|
||||
// ignore clicks on new overlay
|
||||
parents = $(event.target).parents(".umb-overlay,.umb-tour");
|
||||
var parents = $(event.target).parents("a,button,.umb-overlay,.umb-tour");
|
||||
if (parents.length > 0) {
|
||||
return;
|
||||
}
|
||||
@@ -131,12 +131,6 @@ angular.module('umbraco.directives')
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore clicks on dialog actions
|
||||
var actions = $(event.target).parents(".umb-action");
|
||||
if (actions.length === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
//ignore clicks inside this element
|
||||
if ($(element).has($(event.target)).length > 0) {
|
||||
return;
|
||||
|
||||
@@ -14,6 +14,8 @@ angular.module("umbraco.directives")
|
||||
|
||||
// TODO: A lot of the code below should be shared between the grid rte and the normal rte
|
||||
|
||||
scope.isLoading = true;
|
||||
|
||||
var promises = [];
|
||||
|
||||
//To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias
|
||||
@@ -91,6 +93,10 @@ angular.module("umbraco.directives")
|
||||
//custom initialization for this editor within the grid
|
||||
editor.on('init', function (e) {
|
||||
|
||||
// Used this init event - as opposed to property init_instance_callback
|
||||
// to turn off the loader
|
||||
scope.isLoading = false;
|
||||
|
||||
//force overflow to hidden to prevent no needed scroll
|
||||
editor.getBody().style.overflow = "hidden";
|
||||
|
||||
|
||||
+82
-120
@@ -4,7 +4,7 @@
|
||||
@restrict A
|
||||
|
||||
@description
|
||||
Use this directive make an element sticky and follow the page when scrolling.
|
||||
Use this directive make an element sticky and follow the page when scrolling. `umb-sticky-bar--active` class is applied when the element is stuck
|
||||
|
||||
<h3>Markup example</h3>
|
||||
<pre>
|
||||
@@ -12,140 +12,102 @@ Use this directive make an element sticky and follow the page when scrolling.
|
||||
|
||||
<div
|
||||
class="my-sticky-bar"
|
||||
umb-sticky-bar
|
||||
scrollable-container=".container">
|
||||
umb-sticky-bar>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</pre>
|
||||
|
||||
<h3>CSS example</h3>
|
||||
<pre>
|
||||
.my-sticky-bar {
|
||||
padding: 15px 0;
|
||||
background: #000000;
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.my-sticky-bar.-umb-sticky-bar {
|
||||
top: 100px;
|
||||
}
|
||||
</pre>
|
||||
|
||||
@param {string} scrollableContainer Set the class (".element") or the id ("#element") of the scrollable container element.
|
||||
**/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function StickyBarDirective($rootScope) {
|
||||
function StickyBarDirective() {
|
||||
|
||||
/**
|
||||
On initial load, the intersector fires if the grid editor is in the viewport
|
||||
This flag is used to suppress the setClass behaviour on the initial load
|
||||
**/
|
||||
var initial = true;
|
||||
|
||||
/**
|
||||
Toggle `umb-sticky-bar--active` class on the sticky-bar element
|
||||
**/
|
||||
function setClass(addClass, current) {
|
||||
if (!initial) {
|
||||
current.classList.toggle('umb-sticky-bar--active', addClass);
|
||||
} else {
|
||||
initial = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Inserts two elements in the umbStickyBar parent element
|
||||
These are used by the IntersectionObserve to calculate scroll position
|
||||
**/
|
||||
function addSentinels(current) {
|
||||
['-top', '-bottom'].forEach(s => {
|
||||
const sentinel = document.createElement('div');
|
||||
sentinel.classList.add('umb-sticky-sentinel', s);
|
||||
current.parentElement.appendChild(sentinel);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
Calls into setClass when the footer sentinel enters/exits the bottom of the container
|
||||
Container is the parent element of the umbStickyBar element
|
||||
**/
|
||||
function observeFooter(current, container) {
|
||||
const observer = new IntersectionObserver((records, observer) => {
|
||||
let [target, rootBounds, intersected] = [records[0].boundingClientRect, records[0].rootBounds, records[0].intersectionRatio === 1];
|
||||
|
||||
if (target.bottom > rootBounds.top && intersected) {
|
||||
setClass(true, current);
|
||||
}
|
||||
if (target.top < rootBounds.top && target.bottom < rootBounds.bottom) {
|
||||
setClass(false, current);
|
||||
}
|
||||
}, {
|
||||
threshold: [1],
|
||||
root: container
|
||||
});
|
||||
|
||||
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-bottom'));
|
||||
}
|
||||
|
||||
/**
|
||||
Calls into setClass when the header sentinel enters/exits the top of the container
|
||||
Container is the parent element of the umbStickyBar element
|
||||
**/
|
||||
function observeHeader(current, container) {
|
||||
const observer = new IntersectionObserver((records, observer) => {
|
||||
let [target, rootBounds] = [records[0].boundingClientRect, records[0].rootBounds];
|
||||
|
||||
if (target.bottom < rootBounds.top) {
|
||||
setClass(true, current);
|
||||
}
|
||||
|
||||
if (target.bottom >= rootBounds.top && target.bottom < rootBounds.bottom) {
|
||||
setClass(false, current);
|
||||
}
|
||||
}, {
|
||||
threshold: [0],
|
||||
root: container
|
||||
});
|
||||
|
||||
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-top'));
|
||||
}
|
||||
|
||||
function link(scope, el, attr, ctrl) {
|
||||
|
||||
var bar = $(el);
|
||||
var scrollableContainer = null;
|
||||
var clonedBar = null;
|
||||
var cloneIsMade = false;
|
||||
let current = el[0];
|
||||
let container = current.closest('[data-element="editor-container"]');
|
||||
|
||||
function activate() {
|
||||
|
||||
if (bar.parents(".umb-property").length > 1) {
|
||||
bar.addClass("nested");
|
||||
return;
|
||||
}
|
||||
|
||||
if (attr.scrollableContainer) {
|
||||
scrollableContainer = bar.closest(attr.scrollableContainer);
|
||||
} else {
|
||||
scrollableContainer = $(window);
|
||||
}
|
||||
|
||||
scrollableContainer.on('scroll.umbStickyBar', determineVisibility).trigger("scroll");
|
||||
$(window).on('resize.umbStickyBar', determineVisibility);
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
scrollableContainer.off('.umbStickyBar');
|
||||
$(window).off('.umbStickyBar');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function determineVisibility() {
|
||||
|
||||
var barTop = bar[0].offsetTop;
|
||||
var scrollTop = scrollableContainer.scrollTop();
|
||||
|
||||
if (scrollTop > barTop) {
|
||||
|
||||
if (!cloneIsMade) {
|
||||
|
||||
createClone();
|
||||
|
||||
clonedBar.css({
|
||||
'visibility': 'visible'
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
calculateSize();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (cloneIsMade) {
|
||||
|
||||
//remove cloned element (switched places with original on creation)
|
||||
bar.remove();
|
||||
bar = clonedBar;
|
||||
clonedBar = null;
|
||||
|
||||
bar.removeClass('-umb-sticky-bar');
|
||||
bar.css({
|
||||
position: 'relative',
|
||||
'width': 'auto',
|
||||
'height': 'auto',
|
||||
'z-index': 'auto',
|
||||
'visibility': 'visible'
|
||||
});
|
||||
|
||||
cloneIsMade = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function calculateSize() {
|
||||
var width = bar.innerWidth();
|
||||
clonedBar.css({
|
||||
width: width + 10 // + 10 (5*2) because we need to add border to avoid seeing the shadow beneath. Look at the CSS.
|
||||
});
|
||||
}
|
||||
|
||||
function createClone() {
|
||||
//switch place with cloned element, to keep binding intact
|
||||
clonedBar = bar;
|
||||
bar = clonedBar.clone();
|
||||
clonedBar.after(bar);
|
||||
clonedBar.addClass('-umb-sticky-bar');
|
||||
clonedBar.css({
|
||||
'position': 'fixed',
|
||||
// if you change this z-index value, make sure the sticky editor sub headers do not
|
||||
// clash with umb-dropdown (e.g. the content actions dropdown in content list view)
|
||||
'z-index': 99,
|
||||
'visibility': 'hidden'
|
||||
});
|
||||
|
||||
cloneIsMade = true;
|
||||
calculateSize();
|
||||
|
||||
}
|
||||
|
||||
activate();
|
||||
addSentinels(current);
|
||||
|
||||
observeHeader(current, container);
|
||||
observeFooter(current, container);
|
||||
}
|
||||
|
||||
var directive = {
|
||||
|
||||
@@ -172,7 +172,7 @@ function entityResource($q, $http, umbRequestHelper) {
|
||||
umbRequestHelper.getApiUrl(
|
||||
"entityApiBaseUrl",
|
||||
"GetUrlAndAnchors",
|
||||
{ id: id })),
|
||||
[{ id: id }])),
|
||||
'Failed to retrieve url and anchors data for id ' + id);
|
||||
},
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ When building a custom infinite editor view you can use the same components as a
|
||||
*/
|
||||
unbindKeyboardShortcuts();
|
||||
|
||||
// set flag so we know when the editor is open in "infinie mode"
|
||||
// set flag so we know when the editor is open in "infinite mode"
|
||||
editor.infiniteMode = true;
|
||||
|
||||
editors.push(editor);
|
||||
|
||||
+23
-6
@@ -32,15 +32,32 @@
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.umb-editor-sub-header.-umb-sticky-bar {
|
||||
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
|
||||
[umb-sticky-bar] {
|
||||
transition: box-shadow 240ms;
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
top: calc(@appHeaderHeight + @editorHeaderHeight);
|
||||
position:sticky;
|
||||
z-index: 99;
|
||||
|
||||
.umb-editor--infinityMode & {
|
||||
top: calc(@editorHeaderHeight);
|
||||
&.umb-sticky-bar--active {
|
||||
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
|
||||
}
|
||||
}
|
||||
|
||||
.umb-sticky-sentinel {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
&.-top {
|
||||
top:0px;
|
||||
height:1px;
|
||||
}
|
||||
|
||||
&.-bottom {
|
||||
bottom:50px;
|
||||
height:10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
font-size: 14px;
|
||||
color: @black;
|
||||
margin-left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
small {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// --------------------------------------------------
|
||||
.umb-property-editor {
|
||||
width: 100%;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.umb-property-editor-tiny {
|
||||
@@ -165,8 +166,6 @@
|
||||
.sp-replacer {
|
||||
display: inline-flex;
|
||||
margin-right: 18px;
|
||||
border: solid 1px @gray-8;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
label {
|
||||
|
||||
+2
-2
@@ -59,10 +59,10 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController",
|
||||
if (dialogOptions.currentTarget) {
|
||||
// clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target
|
||||
$scope.model.target = angular.copy(dialogOptions.currentTarget);
|
||||
//if we have a node ID, we fetch the current node to build the form data
|
||||
// if we have a node ID, we fetch the current node to build the form data
|
||||
if ($scope.model.target.id || $scope.model.target.udi) {
|
||||
|
||||
//will be either a udi or an int
|
||||
// will be either a udi or an int
|
||||
var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id;
|
||||
|
||||
if ($scope.model.target.udi) {
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
<div
|
||||
class="umb-editor-sub-header umb-editor-sub-header--{{appearance}}"
|
||||
umb-sticky-bar
|
||||
scrollable-container=".umb-editor-container"
|
||||
ng-transclude>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<div class="umb-rte"
|
||||
id="{{textAreaHtmlId}}">
|
||||
<div>
|
||||
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
|
||||
<div class="umb-rte" id="{{textAreaHtmlId}}" ng-style="{ visibility : isLoading ? 'hidden' : 'visible' }"></div>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</div>
|
||||
|
||||
<div class="text-center" ng-if="(availableItems | compareArrays:selectedItems:'alias').length === 0">
|
||||
<small><localize key="general_all">Akk</localize> {{itemLabel}}s <localize key="grid_areAdded">are added</localize></small>
|
||||
<small><localize key="general_all">All</localize> {{itemLabel}}s <localize key="grid_areAdded">are added</localize></small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -94,6 +94,11 @@ function contentCreateController($scope,
|
||||
navigationService.hideDialog(showMenu);
|
||||
};
|
||||
|
||||
$scope.editContentType = function() {
|
||||
$location.path("/settings/documenttypes/edit/" + $scope.contentTypeId).search("view", "permissions");
|
||||
close();
|
||||
}
|
||||
|
||||
$scope.createBlank = createBlank;
|
||||
$scope.createOrSelectBlueprintIfAny = createOrSelectBlueprintIfAny;
|
||||
$scope.createFromBlueprint = createFromBlueprint;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<p class="abstract" ng-if="!hasSettingsAccess"><localize key="create_noDocumentTypesWithNoSettingsAccess"/></p>
|
||||
<div ng-if="hasSettingsAccess">
|
||||
<p class="abstract"><localize key="create_noDocumentTypes" /></p>
|
||||
<button class="btn umb-outline" href="#settings/documentTypes/edit/{{contentTypeId}}?view=permissions" ng-click="close()">
|
||||
<button class="btn umb-outline" ng-click="editContentType()">
|
||||
<localize key="create_noDocumentTypesEditPermissions"/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action" ng-repeat="documentType in vm.documentTypes | orderBy:'name':false">
|
||||
<a href="" class="umb-action-link" ng-click="vm.createBlueprint(documentType)" prevent-default>
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.createBlueprint(documentType)" prevent-default>
|
||||
<i class="large icon {{documentType.icon}}"></i>
|
||||
<span class="menu-label">
|
||||
{{documentType.name}}
|
||||
@@ -19,7 +19,7 @@
|
||||
{{documentType.description}}
|
||||
</small>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li data-element="action-data-type" class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="createDataType()" umb-auto-focus>
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="createDataType()" umb-auto-focus>
|
||||
<i class="large icon icon-autofill"></i>
|
||||
<span class="menu-label">
|
||||
<localize key="create_newDataType">New data type</localize>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li data-element="action-folder" class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label">
|
||||
<localize key="create_newFolder">New folder</localize>...
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -7,36 +7,36 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li data-element="action-documentType" class="umb-action" ng-hide="model.disableTemplates">
|
||||
<a href="" ng-click="createDocType()" class="umb-action-link" umb-auto-focus>
|
||||
<button href="" ng-click="createDocType()" class="umb-action-link umb-outline btn-reset" umb-auto-focus>
|
||||
<i class="large icon icon-item-arrangement"></i>
|
||||
<span class="menu-label">
|
||||
<localize key="content_documentType">Document type</localize>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li data-element="action-documentTypeWithoutTemplate" class="umb-action">
|
||||
<a href="" ng-click="createComponent()" class="umb-action-link">
|
||||
<button href="" ng-click="createComponent()" class="umb-action-link umb-outline btn-reset">
|
||||
<i class="large icon icon-item-arrangement"></i>
|
||||
<span class="menu-label">
|
||||
<localize ng-if="model.disableTemplates === false" key="create_documentTypeWithoutTemplate"></localize>
|
||||
<localize ng-if="model.disableTemplates === true" key="content_documentType">Document type></localize>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li data-element="action-documentTypeCollection" class="umb-action">
|
||||
<a href="" ng-click="showCreateDocTypeCollection()" class="umb-action-link">
|
||||
<button href="" ng-click="showCreateDocTypeCollection()" class="umb-action-link umb-outline btn-reset">
|
||||
<i class="large icon icon-thumbnail-list"></i>
|
||||
<span class="menu-label">
|
||||
Document Type Collection...
|
||||
<!-- <localize key="content_documentType_collection">Document Type Collection</localize>-->
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li data-element="action-folder" ng-if="model.allowCreateFolder" class="umb-action">
|
||||
<a href="" ng-click="showCreateFolder()" class="umb-action-link">
|
||||
<button href="" ng-click="showCreateFolder()" class="umb-action-link umb-outline btn-reset">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
vm.numberOfErrors = 0;
|
||||
vm.commonLogMessages = [];
|
||||
vm.commonLogMessagesCount = 10;
|
||||
vm.dateRangeLabel = "";
|
||||
|
||||
// ChartJS Options - for count/overview of log distribution
|
||||
vm.logTypeLabels = ["Info", "Debug", "Warning", "Error", "Critical"];
|
||||
vm.logTypeLabels = ["Debug", "Info", "Warning", "Error", "Fatal"];
|
||||
vm.logTypeData = [0, 0, 0, 0, 0];
|
||||
vm.logTypeColors = [ '#dcdcdc', '#97bbcd', '#46bfbd', '#fdb45c', '#f7464a'];
|
||||
vm.logTypeColors = ['#eaddd5', '#2bc37c', '#3544b1', '#ff9412', '#d42054'];
|
||||
vm.chartOptions = {
|
||||
legend: {
|
||||
display: true,
|
||||
@@ -23,35 +24,42 @@
|
||||
};
|
||||
|
||||
let querystring = $location.search();
|
||||
if(querystring.startDate){
|
||||
if (querystring.startDate) {
|
||||
vm.startDate = querystring.startDate;
|
||||
}else{
|
||||
vm.dateRangeLabel = getDateRangeLabel("Selected Time Period");
|
||||
} else {
|
||||
vm.startDate = new Date(Date.now());
|
||||
vm.startDate.setDate(vm.startDate.getDate()-1);
|
||||
vm.startDate.setDate(vm.startDate.getDate() - 1);
|
||||
vm.startDate = vm.startDate.toIsoDateString();
|
||||
vm.dateRangeLabel = getDateRangeLabel("Today");
|
||||
}
|
||||
|
||||
if(querystring.endDate){
|
||||
if (querystring.endDate) {
|
||||
vm.endDate = querystring.endDate;
|
||||
}else{
|
||||
|
||||
if (querystring.endDate === querystring.startDate) {
|
||||
vm.dateRangeLabel = getDateRangeLabel("Selected Date");
|
||||
}
|
||||
} else {
|
||||
vm.endDate = new Date(Date.now()).toIsoDateString();
|
||||
}
|
||||
vm.period = [vm.startDate, vm.endDate];
|
||||
|
||||
vm.period = [vm.startDate, vm.endDate];
|
||||
|
||||
//functions
|
||||
vm.searchLogQuery = searchLogQuery;
|
||||
vm.findMessageTemplate = findMessageTemplate;
|
||||
|
||||
vm.searchErrors = searchErrors;
|
||||
|
||||
function preFlightCheck(){
|
||||
vm.loading = true;
|
||||
//Do our pre-flight check (to see if we can view logs)
|
||||
//IE the log file is NOT too big such as 1GB & crash the site
|
||||
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function(result){
|
||||
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function (result) {
|
||||
vm.loading = false;
|
||||
vm.canLoadLogs = result;
|
||||
|
||||
if(result){
|
||||
if (result) {
|
||||
//Can view logs - so initalise
|
||||
init();
|
||||
}
|
||||
@@ -62,39 +70,39 @@
|
||||
function init() {
|
||||
|
||||
vm.loading = true;
|
||||
|
||||
|
||||
var savedSearches = logViewerResource.getSavedSearches().then(function (data) {
|
||||
vm.searches = data;
|
||||
},
|
||||
// fallback to some defaults if error from API response
|
||||
function () {
|
||||
vm.searches = [
|
||||
{
|
||||
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
vm.searches = data;
|
||||
},
|
||||
// fallback to some defaults if error from API response
|
||||
function () {
|
||||
vm.searches = [
|
||||
{
|
||||
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration'",
|
||||
"query": "Has(Duration)"
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration'",
|
||||
"query": "Has(Duration)"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
|
||||
"query": "Has(Duration) and Duration > 1000"
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
|
||||
"query": "Has(Duration) and Duration > 1000"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
|
||||
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
|
||||
{
|
||||
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
|
||||
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that use a specific log message template",
|
||||
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
|
||||
{
|
||||
"name": "Find all logs that use a specific log message template",
|
||||
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
var numOfErrors = logViewerResource.getNumberOfErrors(vm.startDate, vm.endDate).then(function (data) {
|
||||
vm.numberOfErrors = data;
|
||||
@@ -102,41 +110,56 @@
|
||||
|
||||
var logCounts = logViewerResource.getLogLevelCounts(vm.startDate, vm.endDate).then(function (data) {
|
||||
vm.logTypeData = [];
|
||||
vm.logTypeData.push(data.Information);
|
||||
vm.logTypeData.push(data.Debug);
|
||||
vm.logTypeData.push(data.Warning);
|
||||
vm.logTypeData.push(data.Error);
|
||||
vm.logTypeData.push(data.Fatal);
|
||||
|
||||
for (let [key, value] of Object.entries(data)) {
|
||||
const index = vm.logTypeLabels.findIndex(x => key.startsWith(x));
|
||||
if (index > -1) {
|
||||
vm.logTypeData[index] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function(data){
|
||||
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function (data) {
|
||||
vm.commonLogMessages = data;
|
||||
});
|
||||
|
||||
//Set loading indicatior to false when these 3 queries complete
|
||||
$q.all([savedSearches, numOfErrors, logCounts, commonMsgs]).then(function(data) {
|
||||
//Set loading indicator to false when these 3 queries complete
|
||||
$q.all([savedSearches, numOfErrors, logCounts, commonMsgs]).then(function () {
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
$timeout(function () {
|
||||
navigationService.syncTree({ tree: "logViewer", path: "-1" });
|
||||
navigationService.syncTree({
|
||||
tree: "logViewer",
|
||||
path: "-1"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function searchLogQuery(logQuery){
|
||||
$location.path("/settings/logViewer/search").search({lq: logQuery, startDate: vm.startDate, endDate: vm.endDate});
|
||||
function searchLogQuery(logQuery) {
|
||||
$location.path("/settings/logViewer/search").search({
|
||||
lq: logQuery,
|
||||
startDate: vm.startDate,
|
||||
endDate: vm.endDate
|
||||
});
|
||||
}
|
||||
|
||||
function findMessageTemplate(template){
|
||||
function findMessageTemplate(template) {
|
||||
var logQuery = "@MessageTemplate='" + template.MessageTemplate + "'";
|
||||
searchLogQuery(logQuery);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getDateRangeLabel(suffix) {
|
||||
return "Log Overview for " + suffix;
|
||||
}
|
||||
|
||||
function searchErrors(){
|
||||
var logQuery = "@Level='Fatal' or @Level='Error' or Has(@Exception)";
|
||||
searchLogQuery(logQuery);
|
||||
}
|
||||
|
||||
preFlightCheck();
|
||||
|
||||
|
||||
/////////////////////
|
||||
|
||||
vm.config = {
|
||||
@@ -147,20 +170,21 @@
|
||||
maxDate: "today",
|
||||
conjunction: " to "
|
||||
};
|
||||
|
||||
vm.dateRangeChange = function(selectedDates, dateStr, instance) {
|
||||
|
||||
if(selectedDates.length > 0){
|
||||
vm.startDate = selectedDates[0].toIsoDateString();
|
||||
vm.endDate = selectedDates[selectedDates.length-1].toIsoDateString(); // Take the last date as end
|
||||
|
||||
if(vm.startDate === vm.endDate){
|
||||
vm.period = [vm.startDate];
|
||||
}else{
|
||||
vm.period = [vm.startDate, vm.endDate];
|
||||
}
|
||||
|
||||
preFlightCheck();
|
||||
vm.dateRangeChange = function (selectedDates, dateStr, instance) {
|
||||
|
||||
if (selectedDates.length > 0) {
|
||||
|
||||
// Update view by re-requesting route with updated querystring.
|
||||
// By doing this we make sure the URL matches the selected time period, aiding sharing the link.
|
||||
// Also resolves a minor layout issue where the " to " conjunction between the selected dates
|
||||
// is collapsed to a comma.
|
||||
const startDate = selectedDates[0].toIsoDateString();
|
||||
const endDate = selectedDates[selectedDates.length - 1].toIsoDateString(); // Take the last date as end
|
||||
$location.path("/settings/logViewer/overview").search({
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<umb-editor-view footer="false">
|
||||
|
||||
<umb-editor-header
|
||||
name="'Log Overview for Today'"
|
||||
name="vm.dateRangeLabel"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
@@ -74,17 +74,16 @@
|
||||
<umb-box>
|
||||
<umb-box-header title="Time Period"></umb-box-header>
|
||||
|
||||
<umb-flatpickr
|
||||
class="datepicker"
|
||||
ng-model="vm.period"
|
||||
options="vm.config"
|
||||
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
|
||||
<umb-flatpickr class="datepicker"
|
||||
ng-model="vm.period"
|
||||
options="vm.config"
|
||||
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
|
||||
</umb-flatpickr>
|
||||
</umb-box>
|
||||
|
||||
<div ng-show=" vm.canLoadLogs">
|
||||
<!-- No of Errors -->
|
||||
<umb-box ng-click="vm.searchLogQuery('Has(@Exception)')" style="cursor:pointer;">
|
||||
<umb-box ng-click="vm.searchErrors()" style="cursor:pointer;">
|
||||
<umb-box-header title="Number of Errors"></umb-box-header>
|
||||
<umb-box-content class="block-form" style="font-size: 40px; font-weight:900; text-align:center; color:#fe6561;">
|
||||
{{ vm.numberOfErrors }}
|
||||
|
||||
@@ -11,26 +11,28 @@
|
||||
vm.showBackButton = true;
|
||||
vm.page = {};
|
||||
|
||||
// this array is also used to map the logTypeColor param onto the log items
|
||||
// in setLogTypeColors()
|
||||
vm.logLevels = [
|
||||
{
|
||||
name: 'Verbose',
|
||||
logTypeColor: 'gray'
|
||||
logTypeColor: ''
|
||||
},
|
||||
{
|
||||
name: 'Debug',
|
||||
logTypeColor: 'secondary'
|
||||
logTypeColor: 'gray'
|
||||
},
|
||||
{
|
||||
name: 'Information',
|
||||
logTypeColor: 'primary'
|
||||
logTypeColor: 'success'
|
||||
},
|
||||
{
|
||||
name: 'Warning',
|
||||
logTypeColor: 'warning'
|
||||
logTypeColor: 'primary'
|
||||
},
|
||||
{
|
||||
name: 'Error',
|
||||
logTypeColor: 'danger'
|
||||
logTypeColor: 'warning'
|
||||
},
|
||||
{
|
||||
name: 'Fatal',
|
||||
@@ -118,7 +120,7 @@
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
},
|
||||
{
|
||||
@@ -173,25 +175,8 @@
|
||||
}
|
||||
|
||||
function setLogTypeColor(logItems) {
|
||||
angular.forEach(logItems, function (log) {
|
||||
switch (log.Level) {
|
||||
case "Information":
|
||||
log.logTypeColor = "primary";
|
||||
break;
|
||||
case "Debug":
|
||||
log.logTypeColor = "secondary";
|
||||
break;
|
||||
case "Warning":
|
||||
log.logTypeColor = "warning";
|
||||
break;
|
||||
case "Fatal":
|
||||
case "Error":
|
||||
log.logTypeColor = "danger";
|
||||
break;
|
||||
default:
|
||||
log.logTypeColor = "gray";
|
||||
}
|
||||
});
|
||||
logItems.forEach(logItem =>
|
||||
logItem.logTypeColor = vm.logLevels.find(x => x.name === logItem.Level).logTypeColor);
|
||||
}
|
||||
|
||||
function getFilterName(array) {
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
|
||||
<li data-element="action-{{docType.alias}}" class="umb-action" ng-repeat="docType in allowedTypes">
|
||||
<a ng-href="" ng-click="createMediaItem(docType)" class="umb-action-link" prevent-default>
|
||||
<button ng-click="createMediaItem(docType)" class="umb-action-link umb-outline btn-reset" prevent-default>
|
||||
<i class="large icon {{docType.icon}}"></i>
|
||||
<span class="menu-label">
|
||||
{{docType.name}}
|
||||
<small>{{docType.description}}</small>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<!--
|
||||
<li class="add">
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="createMediaType()" umb-auto-focus>
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="createMediaType()" umb-auto-focus>
|
||||
<i class="large icon icon-item-arrangement"></i>
|
||||
<span class="menu-label">
|
||||
<localize key="general_new">New</localize>
|
||||
<localize key="content_mediatype">Media type</localize>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
|
||||
<li class="umb-action" ng-repeat="docType in allowedTypes">
|
||||
<a class="umb-action-link" href="#member/member/edit/{{currentNode.id}}?doctype={{docType.alias}}&create=true" ng-click="hideActions()">
|
||||
<button class="umb-action-link umb-outline btn-reset" href="#member/member/edit/{{currentNode.id}}?doctype={{docType.alias}}&create=true" ng-click="hideActions()">
|
||||
<i class="large icon {{docType.icon}}"></i>
|
||||
<span class="menu-label">
|
||||
{{docType.name}}
|
||||
<small>{{docType.description}}</small>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="createMemberType()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="createMemberType()">
|
||||
|
||||
<i class="large icon icon-item-arrangement"></i>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<localize key="content_memberType">Member type</localize>
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -11,28 +11,28 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.createFile()" umb-auto-focus>
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.createFile()" umb-auto-focus>
|
||||
<i class="large icon-article"></i>
|
||||
<span class="menu-label"><localize key="create_newPartialViewMacro">New partial view macro</localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.createFileWithoutMacro()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.createFileWithoutMacro()">
|
||||
<i class="large icon icon-article"></i>
|
||||
<span class="menu-label"><localize key="create_newPartialViewMacroNoMacro">New partial view macro (without macro)</localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.showCreateFromSnippet()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.showCreateFromSnippet()">
|
||||
<i class="large icon icon-article"></i>
|
||||
<span class="menu-label"><localize key="create_newPartialViewMacroFromSnippet">>New partial view macro from snippet</localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -44,10 +44,10 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action" ng-repeat="snippet in vm.snippets">
|
||||
<a href="" class="umb-action-link" ng-click="vm.createFileFromSnippet(snippet)" style="padding-top: 6px; padding-bottom: 6px;">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.createFileFromSnippet(snippet)" style="padding-top: 6px; padding-bottom: 6px;">
|
||||
<i class="icon-article icon" style="font-size: 20px;"></i>
|
||||
<span class="menu-label" style="margin-left: 0; padding-left: 5px;">{{ snippet.name }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -10,22 +10,22 @@
|
||||
<div ng-if="!vm.showSnippets">
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.createPartialView()" umb-auto-focus>
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.createPartialView()" umb-auto-focus>
|
||||
<i class="large icon icon-article"></i>
|
||||
<span class="menu-label"><localize key="create_newEmptyPartialView">New empty partial view</localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.showCreateFromSnippet()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.showCreateFromSnippet()">
|
||||
<i class="large icon icon-article"></i>
|
||||
<span class="menu-label"><localize key="create_newPartialViewFromSnippet">New partial view from snippet</localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -34,10 +34,10 @@
|
||||
<div ng-if="vm.showSnippets">
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action" ng-repeat="snippet in vm.snippets">
|
||||
<a href="" class="umb-action-link" ng-click="vm.createPartialView(snippet)" style="padding-top: 6px; padding-bottom: 6px;">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.createPartialView(snippet)" style="padding-top: 6px; padding-bottom: 6px;">
|
||||
<i class="icon-article icon" style="font-size: 20px;"></i>
|
||||
<span class="menu-label" style="margin-left: 0; padding-left: 5px;">{{ snippet.name }}</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -57,7 +57,10 @@ angular.module("umbraco")
|
||||
var baseLineConfigObj = {
|
||||
maxImageSize: editorConfig.maxImageSize,
|
||||
width: width,
|
||||
height: height
|
||||
height: height,
|
||||
init_instance_callback: function(editor){
|
||||
$scope.isLoading = false;
|
||||
}
|
||||
};
|
||||
|
||||
angular.extend(baseLineConfigObj, standardConfig);
|
||||
@@ -84,9 +87,6 @@ angular.module("umbraco")
|
||||
$timeout(function () {
|
||||
tinymce.DOM.events.domLoaded = true;
|
||||
tinymce.init(baseLineConfigObj);
|
||||
|
||||
$scope.isLoading = false;
|
||||
|
||||
}, 200);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" umb-auto-focus ng-click="vm.createFile()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" umb-auto-focus ng-click="vm.createFile()">
|
||||
<i class="large icon icon-script"></i>
|
||||
<span class="menu-label"><localize key="create_newJavascriptFile">New javascript file</localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@
|
||||
|
||||
<ul class="umb-actions umb-actions-child">
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" umb-auto-focus ng-click="vm.createFile()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" umb-auto-focus ng-click="vm.createFile()">
|
||||
<i class="large icon icon-script"></i>
|
||||
<span class="menu-label"><localize key="create_newStyleSheetFile">New style sheet file</localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" ng-click="vm.createRichtextStyle()" class="umb-action-link">
|
||||
<button href="" ng-click="vm.createRichtextStyle()" class="umb-action-link umb-outline btn-reset">
|
||||
<i class="large icon icon-script"></i>
|
||||
<span class="menu-label"><localize key="create_newRteStyleSheetFile">New richtext style sheet file</localize></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<li class="umb-action">
|
||||
<a href="" class="umb-action-link" ng-click="vm.showCreateFolder()">
|
||||
<button href="" class="umb-action-link umb-outline btn-reset" ng-click="vm.showCreateFolder()">
|
||||
<i class="large icon icon-folder"></i>
|
||||
<span class="menu-label"><localize key="general_folder"></localize>...</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
ng-repeat="node in model.user.startContentIds"
|
||||
icon="node.icon"
|
||||
name="node.name"
|
||||
allow-remove="true"
|
||||
on-remove="model.removeSelectedItem($index, model.user.startContentIds)">
|
||||
</umb-node-preview>
|
||||
|
||||
@@ -114,6 +115,7 @@
|
||||
ng-repeat="node in model.user.startMediaIds"
|
||||
icon="node.icon"
|
||||
name="node.name"
|
||||
allow-remove="true"
|
||||
on-remove="model.removeSelectedItem($index, model.user.startMediaIds)">
|
||||
</umb-node-preview>
|
||||
|
||||
|
||||
@@ -345,9 +345,9 @@
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>8110</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>8200</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:8110</IISUrl>
|
||||
<IISUrl>http://localhost:8200</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -26,12 +26,13 @@
|
||||
<add key="serilog:write-to:File.restrictedToMinimumLevel" value="Debug" />
|
||||
<add key="serilog:write-to:File.retainedFileCountLimit" value="32" />--> <!-- Number of log files to keep (or remove value to keep all files) -->
|
||||
<!--<add key="serilog:write-to:File.rollingInterval" value="Day" />--> <!-- Create a new log file every Minute/Hour/Day/Month/Year/infinite -->
|
||||
<!--<add key="serilog:write-to:File.outputTemplate" value="{Timestamp:yyyy-MM-dd HH:mm:ss,fff} [P{ProcessId}/D{AppDomainId}/T{ThreadId}] {Log4NetLevel} {SourceContext} - {Message:lj}{NewLine}{Exception}" /> -->
|
||||
|
||||
<!-- Filters all above sink's to use this expression -->
|
||||
<!-- Common use case is to include SourceType starting with your own namespace -->
|
||||
<!--
|
||||
<add key="serilog:using:FilterExpressions" value="Serilog.Filters.Expressions" />
|
||||
<add key="serilog:filter:ByIncluding.expression" value="StartsWith(SourceContext, 'Umbraco.Core')" />
|
||||
<add key="serilog:filter:ByIncludingOnly.expression" value="StartsWith(SourceContext, 'Umbraco.Core')" />
|
||||
-->
|
||||
|
||||
</appSettings>
|
||||
|
||||
@@ -74,6 +74,7 @@ namespace Umbraco.Web.Editors
|
||||
//id is passed in eventually we'll probably want to support GUID + Udi too
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPagedChildren", "id", typeof(int), typeof(string)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPath", "id", typeof(int), typeof(Guid), typeof(Udi)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetUrlAndAnchors", "id", typeof(int), typeof(Guid), typeof(Udi)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetById", "id", typeof(int), typeof(Guid), typeof(Udi)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetByIds", "ids", typeof(int[]), typeof(Guid[]), typeof(Udi[]))));
|
||||
}
|
||||
@@ -288,7 +289,16 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public UrlAndAnchors GetUrlAndAnchors([FromUri]int id, [FromUri]string culture = "*")
|
||||
public UrlAndAnchors GetUrlAndAnchors(Udi id, string culture = "*")
|
||||
{
|
||||
var intId = Services.EntityService.GetId(id);
|
||||
if (!intId.Success)
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
|
||||
return GetUrlAndAnchors(intId.Result, culture);
|
||||
}
|
||||
[HttpGet]
|
||||
public UrlAndAnchors GetUrlAndAnchors(int id, string culture = "*")
|
||||
{
|
||||
var url = UmbracoContext.UrlProvider.GetUrl(id);
|
||||
var anchorValues = Services.ContentService.GetAnchorValuesFromRTEs(id, culture);
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Umbraco.Web.Editors
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if the index has been rebuilt
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
private void Indexer_IndexOperationComplete(object sender, EventArgs e)
|
||||
{
|
||||
var indexer = (LuceneIndex)sender;
|
||||
var indexer = (IIndex)sender;
|
||||
|
||||
_logger.Debug<ExamineManagementController>("Logging operation completed for index {IndexName}", indexer.Name);
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
_logger
|
||||
.Info<ExamineManagementController
|
||||
>($"Rebuilding index '{indexer.Name}' done, {indexer.CommitCount} items committed (can differ from the number of items in the index)");
|
||||
>($"Rebuilding index '{indexer.Name}' done.");
|
||||
|
||||
var cacheKey = "temp_indexing_op_" + indexer.Name;
|
||||
_runtimeCache.Clear(cacheKey);
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace Umbraco.Web.Editors
|
||||
[PluginController("UmbracoApi")]
|
||||
public class LogViewerController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
private ILogViewer _logViewer;
|
||||
private readonly ILogViewer _logViewer;
|
||||
|
||||
public LogViewerController(ILogViewer logViewer)
|
||||
{
|
||||
_logViewer = logViewer;
|
||||
_logViewer = logViewer ?? throw new ArgumentNullException(nameof(logViewer));
|
||||
}
|
||||
|
||||
private bool CanViewLogs(LogTimePeriod logTimePeriod)
|
||||
@@ -91,8 +91,6 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
var direction = orderDirection == "Descending" ? Direction.Descending : Direction.Ascending;
|
||||
|
||||
|
||||
|
||||
return _logViewer.GetLogs(logTimePeriod, filterExpression: filterExpression, pageNumber: pageNumber, orderDirection: direction, logLevels: logLevels);
|
||||
}
|
||||
|
||||
|
||||
@@ -223,7 +223,6 @@ namespace Umbraco.Web
|
||||
_method = method;
|
||||
_controllerName = controllerName;
|
||||
_encryptedString = UrlHelperRenderExtensions.CreateEncryptedRouteString(controllerName, controllerAction, area, additionalRouteVals);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,10 +39,14 @@ namespace Umbraco.Web
|
||||
/// <param name="culture">Optional culture.</param>
|
||||
/// <param name="indexName">Optional index name.</param>
|
||||
/// <remarks>
|
||||
/// <para>When the <paramref name="culture"/> is not specified, all cultures are searched.</para>
|
||||
/// <para>
|
||||
/// When the <paramref name="culture"/> is not specified or is *, all cultures are searched.
|
||||
/// To search for only invariant documents and fields use null.
|
||||
/// When searching on a specific culture, all culture specific fields are searched for the provided culture and all invariant fields for all documents.
|
||||
/// </para>
|
||||
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
|
||||
/// </remarks>
|
||||
IEnumerable<PublishedSearchResult> Search(string term, string culture = null, string indexName = null);
|
||||
IEnumerable<PublishedSearchResult> Search(string term, string culture = "*", string indexName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Searches content.
|
||||
@@ -54,10 +58,14 @@ namespace Umbraco.Web
|
||||
/// <param name="culture">Optional culture.</param>
|
||||
/// <param name="indexName">Optional index name.</param>
|
||||
/// <remarks>
|
||||
/// <para>When the <paramref name="culture"/> is not specified, all cultures are searched.</para>
|
||||
/// <para>
|
||||
/// When the <paramref name="culture"/> is not specified or is *, all cultures are searched.
|
||||
/// To search for only invariant documents and fields use null.
|
||||
/// When searching on a specific culture, all culture specific fields are searched for the provided culture and all invariant fields for all documents.
|
||||
/// </para>
|
||||
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
|
||||
/// </remarks>
|
||||
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = null, string indexName = null);
|
||||
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes the query and converts the results to PublishedSearchResult.
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache);
|
||||
target.Culture = source.GetUserCulture(_textService, _globalSettings).ToString();
|
||||
target.Email = source.Email;
|
||||
target.EmailHash = source.Email.ToLowerInvariant().Trim().ToMd5();
|
||||
target.EmailHash = source.Email.ToLowerInvariant().Trim().GenerateHash();
|
||||
target.Id = source.Id;
|
||||
target.Key = source.Key;
|
||||
target.LastLoginDate = source.LastLoginDate == default ? null : (DateTime?) source.LastLoginDate;
|
||||
|
||||
+1
-11
@@ -12,7 +12,7 @@ namespace Umbraco.Web.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.2.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
@@ -50,15 +50,5 @@ namespace Umbraco.Web.Properties {
|
||||
return ((string)(this["test"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("https://our.umbraco.com/umbraco/webservices/api/repository.asmx")]
|
||||
public string umbraco_org_umbraco_our_Repository {
|
||||
get {
|
||||
return ((string)(this["umbraco_org_umbraco_our_Repository"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,5 @@
|
||||
<Setting Name="test" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">Something</Value>
|
||||
</Setting>
|
||||
<Setting Name="umbraco_org_umbraco_our_Repository" Type="(Web Service URL)" Scope="Application">
|
||||
<Value Profile="(Default)">https://our.umbraco.com/umbraco/webservices/api/repository.asmx</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -8,7 +8,12 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A property editor to allow multiple checkbox selection of pre-defined items.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.CheckBoxList, "Checkbox list", "checkboxlist", Icon="icon-bulleted-list", Group="lists")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.CheckBoxList,
|
||||
"Checkbox list",
|
||||
"checkboxlist",
|
||||
Icon = "icon-bulleted-list",
|
||||
Group = Constants.PropertyEditors.Groups.Lists)]
|
||||
public class CheckBoxListPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
@@ -4,7 +4,12 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.ColorPicker, "Color Picker", "colorpicker", Icon="icon-colorpicker", Group="Pickers")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.ColorPicker,
|
||||
"Color Picker",
|
||||
"colorpicker",
|
||||
Icon = "icon-colorpicker",
|
||||
Group = Constants.PropertyEditors.Groups.Pickers)]
|
||||
public class ColorPickerPropertyEditor : DataEditor
|
||||
{
|
||||
public ColorPickerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -8,7 +8,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Content property editor that stores UDI
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.ContentPicker, EditorType.PropertyValue | EditorType.MacroParameter, "Content Picker", "contentpicker", ValueType = ValueTypes.String, Group = "Pickers")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.ContentPicker,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Content Picker",
|
||||
"contentpicker",
|
||||
ValueType = ValueTypes.String,
|
||||
Group = Constants.PropertyEditors.Groups.Pickers)]
|
||||
public class ContentPickerPropertyEditor : DataEditor
|
||||
{
|
||||
public ContentPickerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -7,7 +7,12 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a date and time property editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.DateTime, "Date/Time", "datepicker", ValueType = ValueTypes.DateTime, Icon="icon-time")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.DateTime,
|
||||
"Date/Time",
|
||||
"datepicker",
|
||||
ValueType = ValueTypes.DateTime,
|
||||
Icon = "icon-time")]
|
||||
public class DateTimePropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -8,7 +8,12 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a decimal property and parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Decimal, EditorType.PropertyValue | EditorType.MacroParameter, "Decimal", "decimal", ValueType = ValueTypes.Decimal)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Decimal,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Decimal",
|
||||
"decimal",
|
||||
ValueType = ValueTypes.Decimal)]
|
||||
public class DecimalPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,7 +5,12 @@ using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.DropDownListFlexible, "Dropdown", "dropdownFlexible", Group = "lists", Icon = "icon-indent")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.DropDownListFlexible,
|
||||
"Dropdown",
|
||||
"dropdownFlexible",
|
||||
Group = Constants.PropertyEditors.Groups.Lists,
|
||||
Icon = "icon-indent")]
|
||||
public class DropDownFlexiblePropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
@@ -5,7 +5,12 @@ using Umbraco.Core.PropertyEditors.Validators;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.EmailAddress, EditorType.PropertyValue | EditorType.MacroParameter, "Email address", "email", Icon="icon-message")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.EmailAddress,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Email address",
|
||||
"email",
|
||||
Icon = "icon-message")]
|
||||
public class EmailAddressPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -12,7 +12,12 @@ using Umbraco.Web.Media;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.UploadField, "File upload", "fileupload", Icon = "icon-download-alt", Group = "media")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.UploadField,
|
||||
"File upload",
|
||||
"fileupload",
|
||||
Group = Constants.PropertyEditors.Groups.Media,
|
||||
Icon = "icon-download-alt")]
|
||||
public class FileUploadPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
|
||||
@@ -12,7 +12,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a grid property and parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Grid, "Grid layout", "grid", HideLabel = true, ValueType = ValueTypes.Json, Group="rich content", Icon="icon-layout")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Grid,
|
||||
"Grid layout",
|
||||
"grid",
|
||||
HideLabel = true,
|
||||
ValueType = ValueTypes.Json,
|
||||
Icon = "icon-layout",
|
||||
Group = Constants.PropertyEditors.Groups.RichContent)]
|
||||
public class GridPropertyEditor : DataEditor
|
||||
{
|
||||
public GridPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -19,7 +19,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents an image cropper property editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.ImageCropper, "Image Cropper", "imagecropper", ValueType = ValueTypes.Json, HideLabel = false, Group="media", Icon="icon-crop")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.ImageCropper,
|
||||
"Image Cropper",
|
||||
"imagecropper",
|
||||
ValueType = ValueTypes.Json,
|
||||
HideLabel = false,
|
||||
Group = Constants.PropertyEditors.Groups.Media,
|
||||
Icon = "icon-crop")]
|
||||
public class ImageCropperPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
|
||||
@@ -8,7 +8,12 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents an integer property and parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Integer, EditorType.PropertyValue | EditorType.MacroParameter, "Numeric", "integer", ValueType = ValueTypes.Integer)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Integer,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Numeric",
|
||||
"integer",
|
||||
ValueType = ValueTypes.Integer)]
|
||||
public class IntegerPropertyEditor : DataEditor
|
||||
{
|
||||
public IntegerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -8,7 +8,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a list-view editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.ListView, "List view", "listview", HideLabel = true, Group = "lists", Icon = Constants.Icons.ListView)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.ListView,
|
||||
"List view",
|
||||
"listview",
|
||||
HideLabel = true,
|
||||
Group = Constants.PropertyEditors.Groups.Lists,
|
||||
Icon = Constants.Icons.ListView)]
|
||||
public class ListViewPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,7 +5,14 @@ using Umbraco.Core.PropertyEditors;
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
// TODO: MacroContainerPropertyEditor is deprecated, but what's the alternative?
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MacroContainer, "(Obsolete) Macro Picker", "macrocontainer", ValueType = ValueTypes.Text, Group = "rich content", Icon = Constants.Icons.Macro, IsDeprecated = true)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MacroContainer,
|
||||
"(Obsolete) Macro Picker",
|
||||
"macrocontainer",
|
||||
ValueType = ValueTypes.Text,
|
||||
Group = Constants.PropertyEditors.Groups.RichContent,
|
||||
Icon = Constants.Icons.Macro,
|
||||
IsDeprecated = true)]
|
||||
public class MacroContainerPropertyEditor : DataEditor
|
||||
{
|
||||
public MacroContainerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -7,7 +7,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a markdown editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MarkdownEditor, "Markdown editor", "markdowneditor", ValueType = ValueTypes.Text, Icon="icon-code", Group="rich content")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MarkdownEditor,
|
||||
"Markdown editor",
|
||||
"markdowneditor",
|
||||
ValueType = ValueTypes.Text,
|
||||
Group = Constants.PropertyEditors.Groups.RichContent,
|
||||
Icon = "icon-code")]
|
||||
public class MarkdownPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -7,8 +7,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a media picker property editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MediaPicker, EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Media Picker", "mediapicker", ValueType = ValueTypes.Text, Group = "media", Icon = Constants.Icons.MediaImage)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MediaPicker,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Media Picker",
|
||||
"mediapicker",
|
||||
ValueType = ValueTypes.Text,
|
||||
Group = Constants.PropertyEditors.Groups.Media,
|
||||
Icon = Constants.Icons.MediaImage)]
|
||||
public class MediaPickerPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -4,7 +4,13 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MemberGroupPicker, "Member Group Picker", "membergrouppicker", ValueType = ValueTypes.Text, Group = "People", Icon = Constants.Icons.MemberGroup)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MemberGroupPicker,
|
||||
"Member Group Picker",
|
||||
"membergrouppicker",
|
||||
ValueType = ValueTypes.Text,
|
||||
Group = Constants.PropertyEditors.Groups.People,
|
||||
Icon = Constants.Icons.MemberGroup)]
|
||||
public class MemberGroupPickerPropertyEditor : DataEditor
|
||||
{
|
||||
public MemberGroupPickerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -4,7 +4,13 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MemberPicker, "Member Picker", "memberpicker", ValueType = ValueTypes.String, Group = "People", Icon = Constants.Icons.Member)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MemberPicker,
|
||||
"Member Picker",
|
||||
"memberpicker",
|
||||
ValueType = ValueTypes.String,
|
||||
Group = Constants.PropertyEditors.Groups.People,
|
||||
Icon = Constants.Icons.Member)]
|
||||
public class MemberPickerPropertyEditor : DataEditor
|
||||
{
|
||||
public MemberPickerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -4,7 +4,13 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MultiNodeTreePicker, "Multinode Treepicker", "contentpicker", ValueType = ValueTypes.Text, Group = "pickers", Icon = "icon-page-add")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MultiNodeTreePicker,
|
||||
"Multinode Treepicker",
|
||||
"contentpicker",
|
||||
ValueType = ValueTypes.Text,
|
||||
Group = Constants.PropertyEditors.Groups.Pickers,
|
||||
Icon = "icon-page-add")]
|
||||
public class MultiNodeTreePickerPropertyEditor : DataEditor
|
||||
{
|
||||
public MultiNodeTreePickerPropertyEditor(ILogger logger)
|
||||
|
||||
@@ -7,7 +7,14 @@ using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MultiUrlPicker, EditorType.PropertyValue, "Multi Url Picker", "multiurlpicker", ValueType = ValueTypes.Json, Group = "pickers", Icon = "icon-link")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MultiUrlPicker,
|
||||
EditorType.PropertyValue,
|
||||
"Multi Url Picker",
|
||||
"multiurlpicker",
|
||||
ValueType = ValueTypes.Json,
|
||||
Group = Constants.PropertyEditors.Groups.Pickers,
|
||||
Icon = "icon-link")]
|
||||
public class MultiUrlPickerPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly IEntityService _entityService;
|
||||
|
||||
@@ -13,7 +13,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a multiple text string property editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MultipleTextstring, "Repeatable textstrings", "multipletextbox", ValueType = ValueTypes.Text, Icon="icon-ordered-list", Group="lists")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MultipleTextstring,
|
||||
"Repeatable textstrings",
|
||||
"multipletextbox",
|
||||
ValueType = ValueTypes.Text,
|
||||
Group = Constants.PropertyEditors.Groups.Lists,
|
||||
Icon = "icon-ordered-list")]
|
||||
public class MultipleTextStringPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -18,7 +18,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a nested content property editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.NestedContent, "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.NestedContent,
|
||||
"Nested Content",
|
||||
"nestedcontent",
|
||||
ValueType = ValueTypes.Json,
|
||||
Group = Constants.PropertyEditors.Groups.Lists,
|
||||
Icon = "icon-thumbnail-list")]
|
||||
public class NestedContentPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly Lazy<PropertyEditorCollection> _propertyEditors;
|
||||
|
||||
@@ -6,7 +6,11 @@ namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
/// <summary>
|
||||
/// Represents a content type parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor("contentType", EditorType.MacroParameter, "Content Type Picker", "entitypicker")]
|
||||
[DataEditor(
|
||||
"contentType",
|
||||
EditorType.MacroParameter,
|
||||
"Content Type Picker",
|
||||
"entitypicker")]
|
||||
public class ContentTypeParameterEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
+5
-1
@@ -7,7 +7,11 @@ namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
/// <summary>
|
||||
/// Represents a parameter editor of some sort.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.MultiNodeTreePicker, EditorType.MacroParameter, "Multiple Content Picker", "contentpicker")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.MultiNodeTreePicker,
|
||||
EditorType.MacroParameter,
|
||||
"Multiple Content Picker",
|
||||
"contentpicker")]
|
||||
public class MultipleContentPickerParameterEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
+5
-1
@@ -3,7 +3,11 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
{
|
||||
[DataEditor("contentTypeMultiple", EditorType.MacroParameter, "Multiple Content Type Picker", "entitypicker")]
|
||||
[DataEditor(
|
||||
"contentTypeMultiple",
|
||||
EditorType.MacroParameter,
|
||||
"Multiple Content Type Picker",
|
||||
"entitypicker")]
|
||||
public class MultipleContentTypeParameterEditor : DataEditor
|
||||
{
|
||||
public MultipleContentTypeParameterEditor(ILogger logger)
|
||||
|
||||
+5
-1
@@ -3,7 +3,11 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
{
|
||||
[DataEditor("tabPickerMultiple", EditorType.MacroParameter, "Multiple Tab Picker", "entitypicker")]
|
||||
[DataEditor(
|
||||
"tabPickerMultiple",
|
||||
EditorType.MacroParameter,
|
||||
"Multiple Tab Picker",
|
||||
"entitypicker")]
|
||||
public class MultiplePropertyGroupParameterEditor : DataEditor
|
||||
{
|
||||
public MultiplePropertyGroupParameterEditor(ILogger logger)
|
||||
|
||||
+5
-1
@@ -3,7 +3,11 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
{
|
||||
[DataEditor("propertyTypePickerMultiple", EditorType.MacroParameter, "Multiple Property Type Picker", "entitypicker")]
|
||||
[DataEditor(
|
||||
"propertyTypePickerMultiple",
|
||||
EditorType.MacroParameter,
|
||||
"Multiple Property Type Picker",
|
||||
"entitypicker")]
|
||||
public class MultiplePropertyTypeParameterEditor : DataEditor
|
||||
{
|
||||
public MultiplePropertyTypeParameterEditor(ILogger logger)
|
||||
|
||||
@@ -3,7 +3,11 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
{
|
||||
[DataEditor("tabPicker", EditorType.MacroParameter, "Tab Picker", "entitypicker")]
|
||||
[DataEditor(
|
||||
"tabPicker",
|
||||
EditorType.MacroParameter,
|
||||
"Tab Picker",
|
||||
"entitypicker")]
|
||||
public class PropertyGroupParameterEditor : DataEditor
|
||||
{
|
||||
public PropertyGroupParameterEditor(ILogger logger)
|
||||
|
||||
@@ -3,7 +3,11 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ParameterEditors
|
||||
{
|
||||
[DataEditor("propertyTypePicker", EditorType.MacroParameter, "Property Type Picker", "entitypicker")]
|
||||
[DataEditor(
|
||||
"propertyTypePicker",
|
||||
EditorType.MacroParameter,
|
||||
"Property Type Picker",
|
||||
"entitypicker")]
|
||||
public class PropertyTypeParameterEditor : DataEditor
|
||||
{
|
||||
public PropertyTypeParameterEditor(ILogger logger)
|
||||
|
||||
@@ -8,7 +8,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A property editor to allow the individual selection of pre-defined items.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.RadioButtonList, "Radio button list", "radiobuttons", ValueType = ValueTypes.String, Group="lists", Icon="icon-target")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.RadioButtonList,
|
||||
"Radio button list",
|
||||
"radiobuttons",
|
||||
ValueType = ValueTypes.String,
|
||||
Group = Constants.PropertyEditors.Groups.Lists,
|
||||
Icon = "icon-target")]
|
||||
public class RadioButtonsPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
@@ -15,7 +15,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a rich text property editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.TinyMce, "Rich Text Editor", "rte", ValueType = ValueTypes.Text, HideLabel = false, Group="Rich Content", Icon="icon-browser-window")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.TinyMce,
|
||||
"Rich Text Editor",
|
||||
"rte",
|
||||
ValueType = ValueTypes.Text,
|
||||
HideLabel = false,
|
||||
Group = Constants.PropertyEditors.Groups.RichContent,
|
||||
Icon = "icon-browser-window")]
|
||||
public class RichTextPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -7,7 +7,11 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a slider editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Slider, "Slider", "slider", Icon = "icon-navigation-horizontal")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Slider,
|
||||
"Slider",
|
||||
"slider",
|
||||
Icon = "icon-navigation-horizontal")]
|
||||
public class SliderPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -14,7 +15,11 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// Represents a tags property editor.
|
||||
/// </summary>
|
||||
[TagsPropertyEditor]
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Tags, "Tags", "tags", Icon="icon-tags")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Tags,
|
||||
"Tags",
|
||||
"tags",
|
||||
Icon = "icon-tags")]
|
||||
public class TagsPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ManifestValueValidatorCollection _validators;
|
||||
@@ -38,9 +43,24 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <inheritdoc />
|
||||
public override object FromEditor(ContentPropertyData editorValue, object currentValue)
|
||||
{
|
||||
return editorValue.Value is JArray json
|
||||
? json.Select(x => x.Value<string>())
|
||||
: null;
|
||||
var value = editorValue?.Value?.ToString();
|
||||
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (editorValue.Value is JArray json)
|
||||
{
|
||||
return json.Select(x => x.Value<string>());
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(value) == false)
|
||||
{
|
||||
return value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -7,7 +7,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a textarea property and parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.TextArea, EditorType.PropertyValue | EditorType.MacroParameter, "Textarea", "textarea", ValueType = ValueTypes.Text, Icon="icon-application-window-alt")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.TextArea,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Textarea",
|
||||
"textarea",
|
||||
ValueType = ValueTypes.Text,
|
||||
Icon = "icon-application-window-alt")]
|
||||
public class TextAreaPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -7,7 +7,12 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a textbox property and parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.TextBox, EditorType.PropertyValue | EditorType.MacroParameter, "Textbox", "textbox", Group = "Common")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.TextBox,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Textbox",
|
||||
"textbox",
|
||||
Group = Constants.PropertyEditors.Groups.Common)]
|
||||
public class TextboxPropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -7,7 +7,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// Represents a checkbox property and parameter editor.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.Boolean, EditorType.PropertyValue | EditorType.MacroParameter, "Checkbox", "boolean", ValueType = ValueTypes.Integer, Group = "Common", Icon="icon-checkbox")]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.Boolean,
|
||||
EditorType.PropertyValue | EditorType.MacroParameter,
|
||||
"Checkbox",
|
||||
"boolean",
|
||||
ValueType = ValueTypes.Integer,
|
||||
Group = Constants.PropertyEditors.Groups.Common,
|
||||
Icon = "icon-checkbox")]
|
||||
public class TrueFalsePropertyEditor : DataEditor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -6,7 +6,13 @@ using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.UserPicker, "User picker", "entitypicker", ValueType = ValueTypes.Integer, Group = "People", Icon = Constants.Icons.User)]
|
||||
[DataEditor(
|
||||
Constants.PropertyEditors.Aliases.UserPicker,
|
||||
"User picker",
|
||||
"entitypicker",
|
||||
ValueType = ValueTypes.Integer,
|
||||
Group = Constants.PropertyEditors.Groups.People,
|
||||
Icon = Constants.Icons.User)]
|
||||
public class UserPickerPropertyEditor : DataEditor
|
||||
{
|
||||
public UserPickerPropertyEditor(ILogger logger)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user