diff --git a/src/Umbraco.Cms.ManagementApi/Controllers/ModelsBuilder/BuildModelsBuilderController.cs b/src/Umbraco.Cms.ManagementApi/Controllers/ModelsBuilder/BuildModelsBuilderController.cs index 7fcf5b5888..b1c29c64b5 100644 --- a/src/Umbraco.Cms.ManagementApi/Controllers/ModelsBuilder/BuildModelsBuilderController.cs +++ b/src/Umbraco.Cms.ManagementApi/Controllers/ModelsBuilder/BuildModelsBuilderController.cs @@ -1,9 +1,10 @@ -using System; -using System.Threading.Tasks; +using System.ComponentModel; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Infrastructure.ModelsBuilder; using Umbraco.Cms.Infrastructure.ModelsBuilder.Building; using Umbraco.Extensions; @@ -14,12 +15,37 @@ public class BuildModelsBuilderController : ModelsBuilderControllerBase { private ModelsBuilderSettings _modelsBuilderSettings; private readonly ModelsGenerationError _mbErrors; - private readonly ModelsGenerator _modelGenerator; + private readonly IModelsGenerator _modelGenerator; + // TODO: Remove in v13 + private readonly ModelsGenerator? _concreteModelGenerator; + + [Obsolete("This constructor is obsolete and will be removed in v13. Use the constructor with IModelsGenerator instead.")] + [Browsable(false)] public BuildModelsBuilderController( IOptionsMonitor modelsBuilderSettings, ModelsGenerationError mbErrors, ModelsGenerator modelGenerator) + : this(modelsBuilderSettings, mbErrors, StaticServiceProvider.Instance.GetRequiredService()) + { + } + + [Obsolete("This constructor is obsolete and will be removed in v13. Use the constructor with only IModelsGenerator instead.")] + [Browsable(false)] + public BuildModelsBuilderController( + IOptionsMonitor modelsBuilderSettings, + ModelsGenerationError mbErrors, + ModelsGenerator concreteModelGenerator, + IModelsGenerator modelGenerator) + : this(modelsBuilderSettings, mbErrors, modelGenerator) + { + } + + [ActivatorUtilitiesConstructor] + public BuildModelsBuilderController( + IOptionsMonitor modelsBuilderSettings, + ModelsGenerationError mbErrors, + IModelsGenerator modelGenerator) { _mbErrors = mbErrors; _modelGenerator = modelGenerator; diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/da.xml b/src/Umbraco.Core/EmbeddedResources/Lang/da.xml index 564f500b6b..50e4667078 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/da.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/da.xml @@ -2232,7 +2232,7 @@ Mange hilsner fra Umbraco robotten Vælg de forskellige antal kolonner denne blok må optage i layoutet. Dette forhindre ikke blokken i at optræde i et mindre område. TIlgængelige række-størrelser Vælg hvor mange rækker denne blok på optage i layoutet. - Tillad på rodniveay + Tillad på rodniveau Gør denne blok tilgængelig i layoutets rodniveau. Hvis dette ikke er valgt, kan denne blok kun bruges inden for andre blokkes definerede områder. Blok-områder Layout-kolonner @@ -2240,7 +2240,7 @@ Mange hilsner fra Umbraco robotten Opsætning af områder Hvis det skal være muligt at indsætte nye blokke indeni denne blok, skal der oprettes ét eller flere områder til at indsætte de nye blokke i. Ikke tilladt placering. - Standart layout stylesheet + Standardlayout stylesheet Ikke tilladt indhold blev afvist diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml b/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml index 3d89a94af1..ec52c0343c 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml @@ -134,7 +134,7 @@ Spara och skicka för godkännande Schemaläggning Välj - Förhandsgranska + Spara och förhandsgranska Förhandsgranskning är avstängt på grund av att det inte finns någon mall tilldelad Gör något annat Välj stil diff --git a/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs b/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs index 7ef1ce5f72..49eaf51eb5 100644 --- a/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs +++ b/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs @@ -13,6 +13,24 @@ public class MemberBasic : ContentItemBasic [DataMember(Name = "email")] public string? Email { get; set; } + [DataMember(Name = "failedPasswordAttempts")] + public int FailedPasswordAttempts { get; set; } + + [DataMember(Name = "approved")] + public bool Approved { get; set; } + + [DataMember(Name = "lockedOut")] + public bool LockedOut { get; set; } + + [DataMember(Name = "lastLockoutDate")] + public DateTime? LastLockoutDate { get; set; } + + [DataMember(Name = "lastLoginDate")] + public DateTime? LastLoginDate { get; set; } + + [DataMember(Name = "lastPasswordChangeDate")] + public DateTime? LastPasswordChangeDate { get; set; } + [DataMember(Name = "properties")] public override IEnumerable Properties { diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index 0206442897..c6fbe0557a 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -67,5 +67,8 @@ public class UmbracoPlan : MigrationPlan // To 11.3.0 To("{BB3889ED-E2DE-49F2-8F71-5FD8616A2661}"); + + // To 11.4.0 + To("{FFB6B9B0-F1A8-45E9-9CD7-25700577D1CA}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_11_4_0/AlterKeyValueDataType.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_11_4_0/AlterKeyValueDataType.cs new file mode 100644 index 0000000000..413711ad1d --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_11_4_0/AlterKeyValueDataType.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using NPoco; +using Umbraco.Cms.Infrastructure.Persistence; +using Umbraco.Cms.Infrastructure.Persistence.Dtos; + +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_11_4_0; + +public class AlterKeyValueDataType : MigrationBase +{ + private readonly IMigrationContext _context; + + public AlterKeyValueDataType(IMigrationContext context) + : base(context) => _context = context; + + protected override void Migrate() + { + // SQLite doesn't need this upgrade + if (_context.Database.DatabaseType.IsSqlite()) + { + return; + } + + string tableName = KeyValueDto.TableName; + string colName = "value"; + + // Determine the current datatype of the column within the database + string colDataType = Database.ExecuteScalar($"SELECT TOP(1) CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS" + + $" WHERE TABLE_NAME = '{tableName}' AND COLUMN_NAME = '{colName}'"); + + // 255 is the old length, -1 indicate MAX length + if (colDataType == "255") + { + // Upgrade to MAX length + Database.Execute($"ALTER TABLE {tableName} ALTER COLUMN {colName} nvarchar(MAX)"); + } + } +} diff --git a/src/Umbraco.Infrastructure/ModelsBuilder/AutoModelsNotificationHandler.cs b/src/Umbraco.Infrastructure/ModelsBuilder/AutoModelsNotificationHandler.cs index 5f7d018b67..d879306226 100644 --- a/src/Umbraco.Infrastructure/ModelsBuilder/AutoModelsNotificationHandler.cs +++ b/src/Umbraco.Infrastructure/ModelsBuilder/AutoModelsNotificationHandler.cs @@ -1,7 +1,10 @@ +using System.ComponentModel; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Runtime; @@ -26,7 +29,35 @@ public sealed class AutoModelsNotificationHandler : INotificationHandler _logger; private readonly IMainDom _mainDom; private readonly ModelsGenerationError _mbErrors; - private readonly ModelsGenerator _modelGenerator; + private readonly IModelsGenerator _modelGenerator; + + // TODO: Remove in v13 + private readonly ModelsGenerator? _concreteModelGenerator; + + [Obsolete("This constructor is obsolete and will be removed in v13. Use the constructor with IModelsGenerator instead.")] + [Browsable(false)] + public AutoModelsNotificationHandler( + ILogger logger, + IOptionsMonitor config, + ModelsGenerator modelGenerator, + ModelsGenerationError mbErrors, + IMainDom mainDom) + : this(logger, config, StaticServiceProvider.Instance.GetRequiredService(), mbErrors, mainDom) + { + } + + [Obsolete("This constructor is obsolete and will be removed in v13. Use the constructor with only IModelsGenerator instead.")] + [Browsable(false)] + public AutoModelsNotificationHandler( + ILogger logger, + IOptionsMonitor config, + ModelsGenerator concreteModelGenerator, + IModelsGenerator modelGenerator, + ModelsGenerationError mbErrors, + IMainDom mainDom) + : this(logger, config, modelGenerator, mbErrors, mainDom) + { + } /// /// Initializes a new instance of the class. @@ -34,7 +65,7 @@ public sealed class AutoModelsNotificationHandler : INotificationHandler logger, IOptionsMonitor config, - ModelsGenerator modelGenerator, + IModelsGenerator modelGenerator, ModelsGenerationError mbErrors, IMainDom mainDom) { diff --git a/src/Umbraco.Infrastructure/ModelsBuilder/Building/IModelsGenerator.cs b/src/Umbraco.Infrastructure/ModelsBuilder/Building/IModelsGenerator.cs new file mode 100644 index 0000000000..4bbaa19614 --- /dev/null +++ b/src/Umbraco.Infrastructure/ModelsBuilder/Building/IModelsGenerator.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Cms.Infrastructure.ModelsBuilder.Building +{ + public interface IModelsGenerator + { + void GenerateModels(); + } +} diff --git a/src/Umbraco.Infrastructure/ModelsBuilder/Building/ModelsGenerator.cs b/src/Umbraco.Infrastructure/ModelsBuilder/Building/ModelsGenerator.cs index 0b2997e994..0a668f2d45 100644 --- a/src/Umbraco.Infrastructure/ModelsBuilder/Building/ModelsGenerator.cs +++ b/src/Umbraco.Infrastructure/ModelsBuilder/Building/ModelsGenerator.cs @@ -6,7 +6,7 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.ModelsBuilder.Building; -public class ModelsGenerator +public class ModelsGenerator : IModelsGenerator { private readonly IHostingEnvironment _hostingEnvironment; private readonly OutOfDateModelsStatus _outOfDateModels; diff --git a/src/Umbraco.Infrastructure/Persistence/Dtos/KeyValueDto.cs b/src/Umbraco.Infrastructure/Persistence/Dtos/KeyValueDto.cs index 5576b5ca43..5c985a0174 100644 --- a/src/Umbraco.Infrastructure/Persistence/Dtos/KeyValueDto.cs +++ b/src/Umbraco.Infrastructure/Persistence/Dtos/KeyValueDto.cs @@ -11,12 +11,15 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Dtos; [ExplicitColumns] internal class KeyValueDto { + public const string TableName = Constants.DatabaseSchema.Tables.KeyValue; + [Column("key")] [Length(256)] [PrimaryKeyColumn(AutoIncrement = false, Clustered = true)] public string Key { get; set; } = null!; [Column("value")] + [SpecialDbType(SpecialDbTypes.NVARCHARMAX)] [NullSetting(NullSetting = NullSettings.Null)] public string? Value { get; set; } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs index 200af7ad70..c89344716f 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs @@ -280,6 +280,36 @@ public class MemberRepository : ContentRepositoryBase(x => x.Alias); } + if (ordering.OrderBy.InvariantEquals("failedPasswordAttempts")) + { + return SqlSyntax.GetFieldName(x => x.FailedPasswordAttempts); + } + + if (ordering.OrderBy.InvariantEquals("approved")) + { + return SqlSyntax.GetFieldName(x => x.IsApproved); + } + + if (ordering.OrderBy.InvariantEquals("lockedOut")) + { + return SqlSyntax.GetFieldName(x => x.IsLockedOut); + } + + if (ordering.OrderBy.InvariantEquals("lastLockoutDate")) + { + return SqlSyntax.GetFieldName(x => x.LastLockoutDate); + } + + if (ordering.OrderBy.InvariantEquals("lastLoginDate")) + { + return SqlSyntax.GetFieldName(x => x.LastLoginDate); + } + + if (ordering.OrderBy.InvariantEquals("lastPasswordChangeDate")) + { + return SqlSyntax.GetFieldName(x => x.LastPasswordChangeDate); + } + return base.ApplySystemOrdering(ref sql, ordering); } diff --git a/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs index 541c6f2710..7164974878 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs @@ -88,6 +88,12 @@ public class MemberMapDefinition : IMapDefinition target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); target.UpdateDate = source.UpdateDate; target.Username = source.Username; + target.FailedPasswordAttempts = source.FailedPasswordAttempts; + target.Approved = source.IsApproved; + target.LockedOut = source.IsLockedOut; + target.LastLockoutDate = source.LastLockoutDate; + target.LastLoginDate = source.LastLoginDate; + target.LastPasswordChangeDate = source.LastPasswordChangeDate; } // Umbraco.Code.MapAll -Icon -Trashed -ParentId -Alias diff --git a/src/Umbraco.Web.BackOffice/ModelsBuilder/ModelsBuilderDashboardController.cs b/src/Umbraco.Web.BackOffice/ModelsBuilder/ModelsBuilderDashboardController.cs index 1444307c2e..94d0919a4f 100644 --- a/src/Umbraco.Web.BackOffice/ModelsBuilder/ModelsBuilderDashboardController.cs +++ b/src/Umbraco.Web.BackOffice/ModelsBuilder/ModelsBuilderDashboardController.cs @@ -1,9 +1,12 @@ +using System.ComponentModel; using System.Runtime.Serialization; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Infrastructure.ModelsBuilder; using Umbraco.Cms.Infrastructure.ModelsBuilder.Building; using Umbraco.Cms.Web.BackOffice.Controllers; @@ -33,11 +36,40 @@ public class ModelsBuilderDashboardController : UmbracoAuthorizedJsonController private readonly ModelsBuilderSettings _config; private readonly DashboardReport _dashboardReport; private readonly ModelsGenerationError _mbErrors; - private readonly ModelsGenerator _modelGenerator; + private readonly IModelsGenerator _modelGenerator; private readonly OutOfDateModelsStatus _outOfDateModels; - public ModelsBuilderDashboardController(IOptions config, ModelsGenerator modelsGenerator, - OutOfDateModelsStatus outOfDateModels, ModelsGenerationError mbErrors) + // TODO: Remove in v13 + private readonly ModelsGenerator? _concreteModelGenerator; + + [Obsolete("This constructor is obsolete and will be removed in v13. Use the constructor with IModelsGenerator instead.")] + [Browsable(false)] + public ModelsBuilderDashboardController( + IOptions config, + ModelsGenerator modelsGenerator, + OutOfDateModelsStatus outOfDateModels, + ModelsGenerationError mbErrors) + : this(config, StaticServiceProvider.Instance.GetRequiredService(), outOfDateModels, mbErrors) + { + } + + [Obsolete("This constructor is obsolete and will be removed in v13. Use the constructor with only IModelsGenerator instead.")] + [Browsable(false)] + public ModelsBuilderDashboardController( + IOptions config, + ModelsGenerator concreteModelGenerator, + IModelsGenerator modelsGenerator, + OutOfDateModelsStatus outOfDateModels, + ModelsGenerationError mbErrors) + : this(config, modelsGenerator, outOfDateModels, mbErrors) + { + } + + [ActivatorUtilitiesConstructor] + public ModelsBuilderDashboardController(IOptions config, + IModelsGenerator modelsGenerator, + OutOfDateModelsStatus outOfDateModels, + ModelsGenerationError mbErrors) { _config = config.Value; _modelGenerator = modelsGenerator; diff --git a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs index 48a4478dc4..818e51aada 100644 --- a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs +++ b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs @@ -133,6 +133,8 @@ public static class UmbracoBuilderDependencyInjectionExtensions builder.Services.TryAddSingleton(); // Register required services for ModelsBuilderDashboardController + builder.Services.AddSingleton(); + // TODO: Remove in v13 - this is only here in case someone is already using this generator directly builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js index 2eced1f660..d3399a35e1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js @@ -10,42 +10,26 @@ function includePropsPreValsController($rootScope, $scope, localizationService, $scope.propertyAliases = []; $scope.selectedField = null; $scope.systemFields = [ - { value: "sortOrder" }, - { value: "updateDate" }, - { value: "updater" }, - { value: "createDate" }, - { value: "owner" }, - { value: "published"}, - { value: "contentTypeAlias" }, - { value: "email" }, - { value: "username" } + { value: "sortOrder", localizedKey: "general_sort" }, + { value: "updateDate", localizedKey: "content_updateDate" }, + { value: "updater", localizedKey: "content_updatedBy" }, + { value: "createDate", localizedKey: "content_createDate" }, + { value: "owner", localizedKey: "content_createBy" }, + { value: "published", localizedKey: "content_isPublished" }, + { value: "contentTypeAlias", localizedKey: "content_documentType" }, + { value: "email", localizedKey: "general_email" }, + { value: "username", localizedKey: "general_username" }, + { value: "failedPasswordAttempts", localizedKey: "user_failedPasswordAttempts" }, + { value: "approved", localizedKey: "user_stateApproved" }, + { value: "lockedOut", localizedKey: "user_stateLockedOut" }, + { value: "lastLockoutDate", localizedKey: "user_lastLockoutDate" }, + { value: "lastLoginDate", localizedKey: "user_lastLogin" }, + { value: "lastPasswordChangeDate", localizedKey: "user_lastPasswordChangeDate" } ]; - $scope.getLocalizedKey = function(alias) { - switch (alias) { - case "name": - return "general_name"; - case "sortOrder": - return "general_sort"; - case "updateDate": - return "content_updateDate"; - case "updater": - return "content_updatedBy"; - case "createDate": - return "content_createDate"; - case "owner": - return "content_createBy"; - case "published": - return "content_isPublished"; - case "contentTypeAlias": - //NOTE: This will just be 'Document' type even if it's for media/members since this is just a pre-val editor and we don't have a key for 'Content Type Alias' - return "content_documentType"; - case "email": - return "general_email"; - case "username": - return "general_username"; - } - return alias; + $scope.getLocalizedKey = function (alias) { + const translationKey = $scope.systemFields.find(x => x.value === alias)?.localizedKey; + return translationKey !== undefined ? translationKey : alias; } $scope.changeField = function () { @@ -65,16 +49,18 @@ function includePropsPreValsController($rootScope, $scope, localizationService, e.name = v; switch (e.value) { + case "published": case "updater": e.name += " (Content only)"; break; - case "published": - e.name += " (Content only)"; - break; - case "email": - e.name += " (Members only)"; - break; case "username": + case "email": + case "failedPasswordAttempts": + case "approved": + case "lockedOut": + case "lastLockoutDate": + case "lastLoginDate": + case "lastPasswordChangeDate": e.name += " (Members only)"; break; } @@ -174,4 +160,4 @@ function includePropsPreValsController($rootScope, $scope, localizationService, } -angular.module("umbraco").controller("Umbraco.PrevalueEditors.IncludePropertiesListViewController", includePropsPreValsController); \ No newline at end of file +angular.module("umbraco").controller("Umbraco.PrevalueEditors.IncludePropertiesListViewController", includePropsPreValsController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 98de0c4bfc..68075cb999 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -213,7 +213,13 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time e.alias === "email" || e.alias === "updateDate" || e.alias === "createDate" || - e.alias === "contentTypeAlias"; + e.alias === "contentTypeAlias" || + e.alias === "failedPasswordAttempts" || + e.alias === "approved" || + e.alias === "lockedOut" || + e.alias === "lastLockoutDate" || + e.alias === "lastLoginDate" || + e.alias === "lastPasswordChangeDate"; } if (e.isSystem) { @@ -815,6 +821,18 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time return "general_email"; case "username": return "general_username"; + case "failedPasswordAttempts": + return "user_failedPasswordAttempts"; + case "approved": + return "user_stateApproved"; + case "lockedOut": + return "user_stateLockedOut"; + case "lastLockoutDate": + return "user_lastLockoutDate"; + case "lastLoginDate": + return "user_lastLogin"; + case "lastPasswordChangeDate": + return "user_lastPasswordChangeDate"; } return alias; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js index 0a81bb40e2..dcc4a8ebec 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js @@ -53,7 +53,13 @@ function sortByPreValsController($rootScope, $scope, localizationService, editor { value: "ContentTypeAlias", key: "content_documentType" }, { value: "Published", key: "content_isPublished" }, { value: "Email", key: "general_email" }, - { value: "Username", key: "general_username" } + { value: "Username", key: "general_username" }, + { value: "failedPasswordAttempts", key: "user_failedPasswordAttempts" }, + { value: "approved", key: "user_stateApproved" }, + { value: "lockedOut", key: "user_stateLockedOut" }, + { value: "lastLockoutDate", key: "user_lastLockoutDate" }, + { value: "lastLoginDate", key: "user_lastLogin" }, + { value: "lastPasswordChangeDate", key: "user_lastPasswordChangeDate" } ]; _.each(systemFields, function (e) { localizationService.localize(e.key).then(function (v) {