From 2503bef346dcd9bcb52315917e99ddd608aaec78 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Mon, 9 Jun 2025 23:29:51 +0200 Subject: [PATCH 01/14] Added sortorder to language --- src/Umbraco.Core/Models/ILanguage.cs | 8 ++++ src/Umbraco.Core/Models/Language.cs | 9 ++++ .../Migrations/Upgrade/UmbracoPlan.cs | 1 + .../V_16_0_0/AddSortOrderToLanguage.cs | 45 +++++++++++++++++++ .../Persistence/Dtos/DomainDto.cs | 3 ++ .../Persistence/Dtos/LanguageDto.cs | 6 +++ .../Persistence/Factories/LanguageFactory.cs | 1 + .../Persistence/Mappers/LanguageMapper.cs | 1 + 8 files changed, 74 insertions(+) create mode 100644 src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs diff --git a/src/Umbraco.Core/Models/ILanguage.cs b/src/Umbraco.Core/Models/ILanguage.cs index 5af66089cad8..f09076a2bfb0 100644 --- a/src/Umbraco.Core/Models/ILanguage.cs +++ b/src/Umbraco.Core/Models/ILanguage.cs @@ -57,4 +57,12 @@ public interface ILanguage : IEntity, IRememberBeingDirty /// [DataMember] public string? FallbackIsoCode { get; set; } + + /// + /// Gets or sets the sort order. + /// + /// + /// The sort order. + /// + int SortOrder { get; set; } } diff --git a/src/Umbraco.Core/Models/Language.cs b/src/Umbraco.Core/Models/Language.cs index efed3314dfd7..b503f4e94807 100644 --- a/src/Umbraco.Core/Models/Language.cs +++ b/src/Umbraco.Core/Models/Language.cs @@ -16,6 +16,7 @@ public class Language : EntityBase, ILanguage private bool _isDefaultVariantLanguage; private string _isoCode; private bool _mandatory; + private int _sortOrder; /// /// Initializes a new instance of the class. @@ -78,4 +79,12 @@ public string? FallbackIsoCode get => _fallbackLanguageIsoCode; set => SetPropertyValueAndDetectChanges(value, ref _fallbackLanguageIsoCode, nameof(FallbackIsoCode)); } + + /// + [DataMember] + public int SortOrder + { + get => _sortOrder; + set => SetPropertyValueAndDetectChanges(value, ref _sortOrder, nameof(SortOrder)); + } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index 21cfe558a688..7ac5f56fc878 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -119,5 +119,6 @@ protected virtual void DefinePlan() // To 16.0.0 To("{C6681435-584F-4BC8-BB8D-BC853966AF0B}"); To("{D1568C33-A697-455F-8D16-48060CB954A1}"); + To("{B1F2A6D3-4C8B-4E9F-8A5C-7D1B2E3F5A6B}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs new file mode 100644 index 000000000000..27f030ea72f6 --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs @@ -0,0 +1,45 @@ +using Microsoft.Extensions.Logging; +using NPoco; +using Umbraco.Cms.Core; +using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_3_0; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions; +using Umbraco.Cms.Infrastructure.Persistence.Dtos; +using Umbraco.Cms.Infrastructure.Scoping; + +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_16_0_0; + +public class AddSortOrderToLanguage : UnscopedMigrationBase +{ + private const string NewColumnName = "sortOrder"; + private readonly IScopeProvider _scopeProvider; + + public AddSortOrderToLanguage(IMigrationContext context, IScopeProvider scopeProvider) + : base(context) + => _scopeProvider = scopeProvider; + + protected override void Migrate() + { + Logger.LogDebug("Adding name and description columns to webhooks."); + + if (TableExists(Constants.DatabaseSchema.Tables.Language)) + { + var columns = Context.SqlContext.SqlSyntax.GetColumnsInSchema(Context.Database).ToList(); + + AddColumn(columns, "sortOrder"); + } + else + { + Logger.LogWarning($"Table {Constants.DatabaseSchema.Tables.Language} does not exist so the addition of the sortOrder column in migration {nameof(AddSortOrderToLanguage)} cannot be completed."); + } + } + + private void AddColumn(List columns, string column) + { + if (columns + .SingleOrDefault(x => x.TableName == Constants.DatabaseSchema.Tables.Language && x.ColumnName == column) is null) + { + AddColumn(Constants.DatabaseSchema.Tables.Language, column); + } + } +} diff --git a/src/Umbraco.Infrastructure/Persistence/Dtos/DomainDto.cs b/src/Umbraco.Infrastructure/Persistence/Dtos/DomainDto.cs index da5a8ad665fb..646f6f51d86e 100644 --- a/src/Umbraco.Infrastructure/Persistence/Dtos/DomainDto.cs +++ b/src/Umbraco.Infrastructure/Persistence/Dtos/DomainDto.cs @@ -33,6 +33,9 @@ internal class DomainDto [ResultColumn("languageISOCode")] public string IsoCode { get; set; } = null!; + /// + /// Gets or sets the sort order of the domain. + /// [Column("sortOrder")] public int SortOrder { get; set; } } diff --git a/src/Umbraco.Infrastructure/Persistence/Dtos/LanguageDto.cs b/src/Umbraco.Infrastructure/Persistence/Dtos/LanguageDto.cs index 3fe65f83229f..60de6437932d 100644 --- a/src/Umbraco.Infrastructure/Persistence/Dtos/LanguageDto.cs +++ b/src/Umbraco.Infrastructure/Persistence/Dtos/LanguageDto.cs @@ -60,4 +60,10 @@ internal class LanguageDto [Index(IndexTypes.NonClustered)] [NullSetting(NullSetting = NullSettings.Null)] public int? FallbackLanguageId { get; set; } + + /// + /// Gets or sets the sort order of the language. + /// + [Column("sortOrder")] + public int SortOrder { get; set; } } diff --git a/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs b/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs index 32b389296413..610f6a799724 100644 --- a/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs @@ -40,6 +40,7 @@ public static LanguageDto BuildDto(ILanguage entity, int? fallbackLanguageId) CultureName = entity.CultureName, IsDefault = entity.IsDefault, IsMandatory = entity.IsMandatory, + SortOrder = entity.SortOrder, FallbackLanguageId = fallbackLanguageId }; diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs index ed5ef6b2244b..d8b185f37afd 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/LanguageMapper.cs @@ -21,5 +21,6 @@ protected override void DefineMaps() DefineMap(nameof(Language.Id), nameof(LanguageDto.Id)); DefineMap(nameof(Language.IsoCode), nameof(LanguageDto.IsoCode)); DefineMap(nameof(Language.CultureName), nameof(LanguageDto.CultureName)); + DefineMap(nameof(Language.SortOrder), nameof(LanguageDto.SortOrder)); } } From f88dc7b8613e8c71579179622c1418ec1a4b182c Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Tue, 10 Jun 2025 00:01:41 +0200 Subject: [PATCH 02/14] Update logging --- .../Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs index 27f030ea72f6..95fdec10474b 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs @@ -20,7 +20,7 @@ public AddSortOrderToLanguage(IMigrationContext context, IScopeProvider scopePro protected override void Migrate() { - Logger.LogDebug("Adding name and description columns to webhooks."); + Logger.LogDebug("Adding sortOrder column to language."); if (TableExists(Constants.DatabaseSchema.Tables.Language)) { From 5a42d3b3c25ddb7b33d5719d0ccad40d5ce9ab2e Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 12 Jun 2025 00:06:20 +0200 Subject: [PATCH 03/14] Cleanup namespaces --- .../Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs index 95fdec10474b..14b738a82947 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs @@ -1,9 +1,5 @@ using Microsoft.Extensions.Logging; -using NPoco; using Umbraco.Cms.Core; -using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_3_0; -using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations; -using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Cms.Infrastructure.Scoping; From e1d8c5bc757f4b43a069ec0b1fe677c2e4a820c1 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 12 Jun 2025 00:10:11 +0200 Subject: [PATCH 04/14] Formatting --- src/Umbraco.Core/Models/Language.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/Models/Language.cs b/src/Umbraco.Core/Models/Language.cs index b503f4e94807..1c202d8c40d7 100644 --- a/src/Umbraco.Core/Models/Language.cs +++ b/src/Umbraco.Core/Models/Language.cs @@ -29,14 +29,14 @@ public Language(string isoCode, string cultureName) _cultureName = cultureName ?? throw new ArgumentNullException(nameof(cultureName)); } - /// - [DataMember] - public string IsoCode + /// + [DataMember] + public string IsoCode + { + get => _isoCode; + set { - get => _isoCode; - set - { - ArgumentNullException.ThrowIfNull(value); + ArgumentNullException.ThrowIfNull(value); SetPropertyValueAndDetectChanges(value, ref _isoCode!, nameof(IsoCode)); } From 9cc145f62932b0225411f7c3acca5e4126d26301 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 28 Jun 2025 15:56:42 +0200 Subject: [PATCH 05/14] Adjust migration --- .../Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs index 14b738a82947..050ac18c9a90 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs @@ -5,7 +5,7 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_16_0_0; -public class AddSortOrderToLanguage : UnscopedMigrationBase +public class AddSortOrderToLanguage : MigrationBase { private const string NewColumnName = "sortOrder"; private readonly IScopeProvider _scopeProvider; From 300edc88b61d3a423f56a27261f23d18cb6a92b9 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 28 Jun 2025 15:57:59 +0200 Subject: [PATCH 06/14] Map sort order --- .../Persistence/Factories/LanguageFactory.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs b/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs index 610f6a799724..eb2ce18c929a 100644 --- a/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/Factories/LanguageFactory.cs @@ -21,7 +21,8 @@ public static ILanguage BuildEntity(LanguageDto dto, string? fallbackIsoCode) Id = dto.Id, IsDefault = dto.IsDefault, IsMandatory = dto.IsMandatory, - FallbackIsoCode = fallbackIsoCode + SortOrder = dto.SortOrder, + FallbackIsoCode = fallbackIsoCode, }; // Reset dirty initial properties From b1077fd69e04d123e962dbd33ab52e4e492338b9 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 28 Jun 2025 16:04:05 +0200 Subject: [PATCH 07/14] Move migration --- src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs | 2 +- .../Upgrade/{V_16_0_0 => V_16_1_0}/AddSortOrderToLanguage.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/Umbraco.Infrastructure/Migrations/Upgrade/{V_16_0_0 => V_16_1_0}/AddSortOrderToLanguage.cs (95%) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index 7ac5f56fc878..e5773bc666fb 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -119,6 +119,6 @@ protected virtual void DefinePlan() // To 16.0.0 To("{C6681435-584F-4BC8-BB8D-BC853966AF0B}"); To("{D1568C33-A697-455F-8D16-48060CB954A1}"); - To("{B1F2A6D3-4C8B-4E9F-8A5C-7D1B2E3F5A6B}"); + To("{B1F2A6D3-4C8B-4E9F-8A5C-7D1B2E3F5A6B}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs similarity index 95% rename from src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs rename to src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs index 050ac18c9a90..088b8939a9d3 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_0_0/AddSortOrderToLanguage.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs @@ -3,7 +3,7 @@ using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Cms.Infrastructure.Scoping; -namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_16_0_0; +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_16_1_0; public class AddSortOrderToLanguage : MigrationBase { From 382951a1fa69791503d2bde662b1d8ffbd82e728 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 28 Jun 2025 17:02:52 +0200 Subject: [PATCH 08/14] Adjust migration --- .../V_16_1_0/AddSortOrderToLanguage.cs | 131 ++++++++++++++++-- 1 file changed, 117 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs index 088b8939a9d3..c7e4e6aee387 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs @@ -1,11 +1,12 @@ -using Microsoft.Extensions.Logging; +using NPoco; using Umbraco.Cms.Core; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Cms.Infrastructure.Scoping; namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_16_1_0; -public class AddSortOrderToLanguage : MigrationBase +public class AddSortOrderToLanguage : UnscopedMigrationBase { private const string NewColumnName = "sortOrder"; private readonly IScopeProvider _scopeProvider; @@ -16,26 +17,128 @@ public AddSortOrderToLanguage(IMigrationContext context, IScopeProvider scopePro protected override void Migrate() { - Logger.LogDebug("Adding sortOrder column to language."); - - if (TableExists(Constants.DatabaseSchema.Tables.Language)) + // If the new column already exists we'll do nothing. + if (ColumnExists(Constants.DatabaseSchema.Tables.Language, NewColumnName)) { - var columns = Context.SqlContext.SqlSyntax.GetColumnsInSchema(Context.Database).ToList(); - - AddColumn(columns, "sortOrder"); + Context.Complete(); + return; } - else + + using IScope scope = _scopeProvider.CreateScope(); + using IDisposable notificationSuppression = scope.Notifications.Suppress(); + ScopeDatabase(scope); + + // SQL server can simply add the column, but for SQLite this won't work, + // so we'll have to create a new table and copy over data. + if (DatabaseType != DatabaseType.SQLite) { - Logger.LogWarning($"Table {Constants.DatabaseSchema.Tables.Language} does not exist so the addition of the sortOrder column in migration {nameof(AddSortOrderToLanguage)} cannot be completed."); + MigrateSqlServer(); + Context.Complete(); + return; } + + MigrateSqlite(); + Context.Complete(); + } - private void AddColumn(List columns, string column) + private void MigrateSqlServer() { - if (columns - .SingleOrDefault(x => x.TableName == Constants.DatabaseSchema.Tables.Language && x.ColumnName == column) is null) + var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList(); + AddColumnIfNotExists(columns, NewColumnName); + } + + private void MigrateSqlite() + { + /* + * We commit the initial transaction started by the scope. This is required in order to disable the foreign keys. + * We then begin a new transaction, this transaction will be committed or rolled back by the scope, like normal. + * We don't have to worry about re-enabling the foreign keys, since these are enabled by default every time a connection is established. + * + * Ideally we'd want to do this with the unscoped database we get, however, this cannot be done, + * since our scoped database cannot share a connection with the unscoped database, so a new one will be created, which enables the foreign keys. + * Similarly we cannot use Database.CompleteTransaction(); since this also closes the connection, + * so starting a new transaction would re-enable foreign keys. + */ + Database.Execute("COMMIT;"); + Database.Execute("PRAGMA foreign_keys=off;"); + Database.Execute("BEGIN TRANSACTION;"); + + IEnumerable languages = Database.Fetch().Select(x => new LanguageDto { - AddColumn(Constants.DatabaseSchema.Tables.Language, column); + Id = x.Id, + IsoCode = x.IsoCode, + CultureName = x.CultureName, + IsDefault = x.IsDefault, + IsMandatory = x.IsMandatory, + FallbackLanguageId = x.FallbackLanguageId, + SortOrder = 0 + }); + + Delete.Table(Constants.DatabaseSchema.Tables.Language).Do(); + Create.Table().Do(); + + foreach (LanguageDto language in languages) + { + Database.Insert(Constants.DatabaseSchema.Tables.Language, "id", false, language); } } + + [TableName(TableName)] + [PrimaryKey("id")] + [ExplicitColumns] + internal class OldLanguageDto + { + public const string TableName = Constants.DatabaseSchema.Tables.Language; + + // Public constants to bind properties between DTOs + public const string IsoCodeColumnName = "languageISOCode"; + + /// + /// Gets or sets the identifier of the language. + /// + [Column("id")] + [PrimaryKeyColumn(IdentitySeed = 2)] + public short Id { get; set; } + + /// + /// Gets or sets the ISO code of the language. + /// + [Column(IsoCodeColumnName)] + [Index(IndexTypes.UniqueNonClustered)] + [NullSetting(NullSetting = NullSettings.Null)] + [Length(14)] + public string? IsoCode { get; set; } + + /// + /// Gets or sets the culture name of the language. + /// + [Column("languageCultureName")] + [NullSetting(NullSetting = NullSettings.Null)] + [Length(100)] + public string? CultureName { get; set; } + + /// + /// Gets or sets a value indicating whether the language is the default language. + /// + [Column("isDefaultVariantLang")] + [Constraint(Default = "0")] + public bool IsDefault { get; set; } + + /// + /// Gets or sets a value indicating whether the language is mandatory. + /// + [Column("mandatory")] + [Constraint(Default = "0")] + public bool IsMandatory { get; set; } + + /// + /// Gets or sets the identifier of a fallback language. + /// + [Column("fallbackLanguageId")] + [ForeignKey(typeof(LanguageDto), Column = "id")] + [Index(IndexTypes.NonClustered)] + [NullSetting(NullSetting = NullSettings.Null)] + public int? FallbackLanguageId { get; set; } + } } From e37717fab95899a1b3e7ea0c1745aa4744f013da Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 29 Jun 2025 16:53:45 +0200 Subject: [PATCH 09/14] Move to premigration plan --- .../Migrations/Upgrade/UmbracoPlan.cs | 1 - .../Migrations/Upgrade/UmbracoPremigrationPlan.cs | 1 + .../Upgrade/V_16_1_0/AddSortOrderToLanguage.cs | 9 +++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index e5773bc666fb..21cfe558a688 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -119,6 +119,5 @@ protected virtual void DefinePlan() // To 16.0.0 To("{C6681435-584F-4BC8-BB8D-BC853966AF0B}"); To("{D1568C33-A697-455F-8D16-48060CB954A1}"); - To("{B1F2A6D3-4C8B-4E9F-8A5C-7D1B2E3F5A6B}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs index d9774aa1ea7a..637c1cc941a0 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs @@ -67,5 +67,6 @@ protected virtual void DefinePlan() To("{B9133686-B758-404D-AF12-708AA80C7E44}"); To("{EEB1F012-B44D-4AB4-8756-F7FB547345B4}"); To("{0F49E1A4-AFD8-4673-A91B-F64E78C48174}"); + To("{B1F2A6D3-4C8B-4E9F-8A5C-7D1B2E3F5A6B}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs index c7e4e6aee387..4f0b8e643011 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_16_1_0/AddSortOrderToLanguage.cs @@ -33,13 +33,14 @@ protected override void Migrate() if (DatabaseType != DatabaseType.SQLite) { MigrateSqlServer(); - Context.Complete(); - return; + } + else + { + MigrateSqlite(); } - MigrateSqlite(); Context.Complete(); - + scope.Complete(); } private void MigrateSqlServer() From fb854368e0cfa0b3c96ed1e4ed6e1e4b36c915ed Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 29 Jun 2025 17:04:32 +0200 Subject: [PATCH 10/14] Add sort order --- .../table/language-table-collection-view.element.ts | 11 ++++++++++- .../src/packages/language/types.ts | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/collection/views/table/language-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/language/collection/views/table/language-table-collection-view.element.ts index b347db3e8196..6841735a620e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/collection/views/table/language-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/collection/views/table/language-table-collection-view.element.ts @@ -38,6 +38,10 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { name: 'Fallback', alias: 'fallbackLanguage', }, + { + name: 'Sort Order', + alias: 'sortOrder', + }, { name: '', alias: 'entityActions', @@ -94,6 +98,10 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { columnAlias: 'fallbackLanguage', value: languages.find((x) => x.unique === language.fallbackIsoCode)?.name, }, + { + columnAlias: 'sortOrder', + value: language.sortOrder, + }, { columnAlias: 'entityActions', value: html` + + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/types.ts b/src/Umbraco.Web.UI.Client/src/packages/language/types.ts index c3686bfe9d49..07dc5e89569e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/types.ts @@ -9,6 +9,7 @@ export interface UmbLanguageDetailModel { entityType: UmbLanguageEntityType; unique: string; name: string; + sortOrder: number; isDefault: boolean; isMandatory: boolean; fallbackIsoCode: string | null; From 540ccb7854794c271feceb5447f985e9a2c0d71d Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 29 Jun 2025 18:00:25 +0200 Subject: [PATCH 11/14] Add sort order --- .../language/views/language-details-workspace-view.element.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/workspace/language/views/language-details-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/language/workspace/language/views/language-details-workspace-view.element.ts index b5e2674a886c..1f4e1de49e0b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/workspace/language/views/language-details-workspace-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/workspace/language/views/language-details-workspace-view.element.ts @@ -123,6 +123,10 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement implem
${this._language?.unique}
+ +
${this._language?.sortOrder}
+
+
Date: Sun, 29 Jun 2025 18:43:07 +0200 Subject: [PATCH 12/14] Sort order property --- .../src/packages/core/backend-api/types.gen.ts | 5 +++-- .../publishing/unpublish/entity-action/unpublish.action.ts | 1 + .../repository/language-collection.server.data-source.ts | 1 + .../repository/detail/language-detail.server.data-source.ts | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts index cf958d9ab757..6fe1146b61fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts @@ -1140,14 +1140,15 @@ export type ItemSortingRequestModel = { export type LanguageItemResponseModel = { name: string; - isoCode: string; + isoCode: string; }; export type LanguageResponseModel = { name: string; isDefault: boolean; isMandatory: boolean; - fallbackIsoCode?: string | null; + fallbackIsoCode?: string | null; + sortOrder: number; isoCode: string; }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/entity-action/unpublish.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/entity-action/unpublish.action.ts index 667fb4dbebc1..a954e65b9fb7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/entity-action/unpublish.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/entity-action/unpublish.action.ts @@ -58,6 +58,7 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase name: appCulture!, entityType: 'language', fallbackIsoCode: null, + sortOrder: 0, isDefault: true, isMandatory: false, unique: appCulture!, diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts index 4130781beb23..0e337c142a28 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/collection/repository/language-collection.server.data-source.ts @@ -41,6 +41,7 @@ export class UmbLanguageCollectionServerDataSource implements UmbCollectionDataS isDefault: item.isDefault, isMandatory: item.isMandatory, fallbackIsoCode: item.fallbackIsoCode || null, + sortOrder: item.sortOrder }; return model; diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/repository/detail/language-detail.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/language/repository/detail/language-detail.server.data-source.ts index da721cf0b182..3e01b8627795 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/repository/detail/language-detail.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/repository/detail/language-detail.server.data-source.ts @@ -38,6 +38,7 @@ export class UmbLanguageServerDataSource implements UmbDetailDataSource Date: Sun, 29 Jun 2025 18:46:51 +0200 Subject: [PATCH 13/14] Map sort order --- .../Mapping/Language/LanguageViewModelsMapDefinition.cs | 3 +++ .../ViewModels/Language/LanguageModelBase.cs | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Cms.Api.Management/Mapping/Language/LanguageViewModelsMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/Language/LanguageViewModelsMapDefinition.cs index 4fceb353fc8d..ce756fa0c426 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/Language/LanguageViewModelsMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/Language/LanguageViewModelsMapDefinition.cs @@ -21,6 +21,7 @@ private static void Map(ILanguage source, LanguageResponseModel target, MapperCo target.Name = source.CultureName; target.IsDefault = source.IsDefault; target.IsMandatory = source.IsMandatory; + target.SortOrder = source.SortOrder; } // Umbraco.Code.MapAll -Id -Key @@ -37,6 +38,7 @@ private static void Map(CreateLanguageRequestModel source, ILanguage target, Map target.IsoCode = source.IsoCode; target.UpdateDate = default; target.FallbackIsoCode = source.FallbackIsoCode; + target.SortOrder = source.SortOrder; } // Umbraco.Code.MapAll -Id -Key -IsoCode -CreateDate @@ -51,5 +53,6 @@ private static void Map(UpdateLanguageRequestModel source, ILanguage target, Map target.IsMandatory = source.IsMandatory; target.UpdateDate = default; target.FallbackIsoCode = source.FallbackIsoCode; + target.SortOrder = source.SortOrder; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Language/LanguageModelBase.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Language/LanguageModelBase.cs index db288316a19d..3f82a7861dcd 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Language/LanguageModelBase.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Language/LanguageModelBase.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace Umbraco.Cms.Api.Management.ViewModels.Language; @@ -12,4 +12,6 @@ public class LanguageModelBase public bool IsMandatory { get; set; } public string? FallbackIsoCode { get; set; } + + public int SortOrder { get; set; } } From d2422e37c37a3f638f29d899e45275ecd2d9ea22 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 29 Jun 2025 22:43:26 +0200 Subject: [PATCH 14/14] Set sort order --- .../documents/publishing/publish/entity-action/publish.action.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/entity-action/publish.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/entity-action/publish.action.ts index cba68820a77e..cf8354bd8b6d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/entity-action/publish.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/entity-action/publish.action.ts @@ -55,6 +55,7 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase { name: appCulture!, entityType: 'language', fallbackIsoCode: null, + sortOrder: 0, isDefault: true, isMandatory: false, unique: appCulture!,