Add data type editor UI aliases on upgrade (#16183)

This commit is contained in:
Kenn Jacobsen
2024-05-01 07:50:26 +02:00
committed by GitHub
parent d953a78ae6
commit 404cb28c59
5 changed files with 145 additions and 8 deletions

View File

@@ -17,7 +17,7 @@ public class DataTypeViewModelMapDefinition : IMapDefinition
target.Id = source.Key;
target.Name = source.Name ?? string.Empty;
target.EditorAlias = source.EditorAlias;
target.EditorUiAlias = source.EditorUiAlias;
target.EditorUiAlias = source.EditorUiAlias ?? source.EditorAlias;
target.IsDeletable = source.IsDeletableDataType();
target.CanIgnoreStartNodes = source.IsBuildInDataType() is false;

View File

@@ -32820,6 +32820,7 @@
"CreateDataTypeRequestModel": {
"required": [
"editorAlias",
"editorUiAlias",
"name",
"values"
],
@@ -32834,8 +32835,7 @@
"type": "string"
},
"editorUiAlias": {
"type": "string",
"nullable": true
"type": "string"
},
"values": {
"type": "array",
@@ -34622,6 +34622,7 @@
"required": [
"canIgnoreStartNodes",
"editorAlias",
"editorUiAlias",
"id",
"isDeletable",
"name",
@@ -34638,8 +34639,7 @@
"type": "string"
},
"editorUiAlias": {
"type": "string",
"nullable": true
"type": "string"
},
"values": {
"type": "array",
@@ -42047,6 +42047,7 @@
"UpdateDataTypeRequestModel": {
"required": [
"editorAlias",
"editorUiAlias",
"name",
"values"
],
@@ -42061,8 +42062,7 @@
"type": "string"
},
"editorUiAlias": {
"type": "string",
"nullable": true
"type": "string"
},
"values": {
"type": "array",

View File

@@ -10,7 +10,7 @@ public abstract class DataTypeModelBase
[Required]
public string EditorAlias { get; set; } = string.Empty;
public string? EditorUiAlias { get; set; }
public string EditorUiAlias { get; set; } = string.Empty;
public IEnumerable<DataTypePropertyPresentationModel> Values { get; set; } = Enumerable.Empty<DataTypePropertyPresentationModel>();
}

View File

@@ -80,5 +80,6 @@ public class UmbracoPlan : MigrationPlan
To<V_14_0_0.MigrateTours>("{302DE171-6D83-4B6B-B3C0-AC8808A16CA1}");
To<V_14_0_0.MigrateUserGroup2PermissionPermissionColumnType>("{8184E61D-ECBA-4AAA-B61B-D7A82EB82EB7}");
To<V_14_0_0.MigrateNotificationCharsToStrings>("{E261BF01-2C7F-4544-BAE7-49D545B21D68}");
To<V_14_0_0.AddEditorUiToDataType>("{5A2EF07D-37B4-49D5-8E9B-3ED01877263B}");
}
}

View File

@@ -0,0 +1,136 @@
using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_14_0_0;
public class AddEditorUiToDataType : MigrationBase
{
private readonly IKeyValueService _keyValueService;
private readonly IJsonSerializer _jsonSerializer;
private readonly ILogger<AddEditorUiToDataType> _logger;
public AddEditorUiToDataType(IMigrationContext context, IKeyValueService keyValueService, IJsonSerializer jsonSerializer, ILogger<AddEditorUiToDataType> logger)
: base(context)
{
_keyValueService = keyValueService;
_jsonSerializer = jsonSerializer;
_logger = logger;
}
protected override void Migrate()
{
var dataEditorSplitCollectionData = _keyValueService.GetValue("migrateDataEditorSplitCollectionData");
if (dataEditorSplitCollectionData.IsNullOrWhiteSpace())
{
return;
}
DataTypeEditorAliasMigrationData[]? migrationData = _jsonSerializer.Deserialize<DataTypeEditorAliasMigrationData[]>(dataEditorSplitCollectionData);
if (migrationData?.Any() is not true)
{
_logger.LogError("No migration data was found for the data editor split. Please make sure you're upgrading from the latest V13. Any data types based on custom property editors may not work correctly.");
return;
}
Sql<ISqlContext> sql = Sql()
.Select<DataTypeDto>()
.AndSelect<NodeDto>()
.From<DataTypeDto>()
.InnerJoin<NodeDto>()
.On<DataTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
.Where<DataTypeDto>(x => x.EditorUiAlias == null);
List<DataTypeDto> dataTypeDtos = Database.Fetch<DataTypeDto>(sql);
foreach (DataTypeDto dataTypeDto in dataTypeDtos)
{
dataTypeDto.EditorUiAlias = dataTypeDto.EditorAlias switch
{
Constants.PropertyEditors.Aliases.BlockList => "Umb.PropertyEditorUi.BlockList",
Constants.PropertyEditors.Aliases.BlockGrid => "Umb.PropertyEditorUi.BlockGrid",
Constants.PropertyEditors.Aliases.CheckBoxList => "Umb.PropertyEditorUi.CheckBoxList",
Constants.PropertyEditors.Aliases.ColorPicker => "Umb.PropertyEditorUi.ColorPicker",
Constants.PropertyEditors.Aliases.ColorPickerEyeDropper => "Umb.PropertyEditorUi.EyeDropper",
Constants.PropertyEditors.Aliases.ContentPicker => "Umb.PropertyEditorUi.DocumentPicker",
Constants.PropertyEditors.Aliases.DateTime => "Umb.PropertyEditorUi.DatePicker",
Constants.PropertyEditors.Aliases.DropDownListFlexible => "Umb.PropertyEditorUi.Dropdown",
Constants.PropertyEditors.Aliases.ImageCropper => "Umb.PropertyEditorUi.ImageCropper",
Constants.PropertyEditors.Aliases.Integer => "Umb.PropertyEditorUi.Integer",
Constants.PropertyEditors.Aliases.Decimal => "Umb.PropertyEditorUi.Decimal",
Constants.PropertyEditors.Aliases.ListView => "Umb.PropertyEditorUi.Collection",
Constants.PropertyEditors.Aliases.MediaPicker3 => "Umb.PropertyEditorUi.MediaPicker",
Constants.PropertyEditors.Aliases.MemberPicker => "Umb.PropertyEditorUi.MemberPicker",
Constants.PropertyEditors.Aliases.MemberGroupPicker => "Umb.PropertyEditorUi.MemberGroupPicker",
Constants.PropertyEditors.Aliases.MultiNodeTreePicker => "Umb.PropertyEditorUi.TreePicker",
Constants.PropertyEditors.Aliases.MultipleTextstring => "Umb.PropertyEditorUi.MultipleTextString",
Constants.PropertyEditors.Aliases.Label => "Umb.PropertyEditorUi.Label",
Constants.PropertyEditors.Aliases.RadioButtonList => "Umb.PropertyEditorUi.RadioButtonList",
Constants.PropertyEditors.Aliases.Slider => "Umb.PropertyEditorUi.Slider",
Constants.PropertyEditors.Aliases.Tags => "Umb.PropertyEditorUi.Tags",
Constants.PropertyEditors.Aliases.TextBox => "Umb.PropertyEditorUi.TextBox",
Constants.PropertyEditors.Aliases.TextArea => "Umb.PropertyEditorUi.TextArea",
Constants.PropertyEditors.Aliases.RichText => "Umb.PropertyEditorUi.TinyMCE",
Constants.PropertyEditors.Aliases.TinyMce => "Umb.PropertyEditorUi.TinyMCE",
Constants.PropertyEditors.Aliases.Boolean => "Umb.PropertyEditorUi.Toggle",
Constants.PropertyEditors.Aliases.MarkdownEditor => "Umb.PropertyEditorUi.MarkdownEditor",
Constants.PropertyEditors.Aliases.UserPicker => "Umb.PropertyEditorUi.UserPicker",
Constants.PropertyEditors.Aliases.UploadField => "Umb.PropertyEditorUi.UploadField",
Constants.PropertyEditors.Aliases.EmailAddress => "Umb.PropertyEditorUi.EmailAddress",
Constants.PropertyEditors.Aliases.MultiUrlPicker => "Umb.PropertyEditorUi.MultiUrlPicker",
_ => null
};
if (dataTypeDto.EditorUiAlias is null)
{
DataTypeEditorAliasMigrationData? dataTypeMigrationData = migrationData.FirstOrDefault(md => md.DataTypeId == dataTypeDto.NodeId);
if (dataTypeMigrationData is not null)
{
// the V13 "data type split data collector" works like this:
// - if .EditorUiAlias is set, the editor is based on manifests and should use one of the "Umbraco.Plain" options as .EditorAlias
// - if .EditorUiAlias is not set, the editor is based on code and should use its own alias as .EditorUiAlias
// unfortunately there is an issue with the migrator, in that it does not handle manifest based editors using valueType=TEXT,
// but with the above logic in mind, we can work around that :)
if (dataTypeMigrationData.EditorUiAlias.IsNullOrWhiteSpace())
{
// editor based on code
dataTypeDto.EditorUiAlias = dataTypeDto.EditorAlias;
}
else
{
// editor based on manifests
dataTypeDto.EditorUiAlias = dataTypeMigrationData.EditorUiAlias;
dataTypeDto.EditorAlias = dataTypeMigrationData.EditorAlias?.NullOrWhiteSpaceAsNull()
?? "Umbraco.Plain.String";
}
}
else
{
_logger.LogWarning("No migration data was found for the data editor split for data type {name} ({editorAlias} - {id}). Please make sure you're upgrading from the latest V13. The affected data type may not work correctly.", dataTypeDto.NodeDto.Text, dataTypeDto.EditorAlias, dataTypeDto.NodeId);
// we *need* an EditorUiAlias - default to the editor alias (let the client handle later)
dataTypeDto.EditorUiAlias = dataTypeDto.EditorAlias;
}
}
Database.Update(dataTypeDto);
}
}
private class DataTypeEditorAliasMigrationData
{
[JsonPropertyName("DataTypeId")]
public int DataTypeId { get; set; }
[JsonPropertyName("EditorUiAlias")]
public string? EditorUiAlias { get; init; }
[JsonPropertyName("EditorAlias")]
public string? EditorAlias { get; init; }
}
}