DX: Add BlockValue constructors to force correct property editor alias and layout item type (#16266)

* Improve getting and initializing new block value layouts

* Remove unnecessary generic type constraints

* Add and use new block value/layout item constructors in tests

* Removed GetLayouts that did not make sense

* Added constructor to BlockItemData to simplify explicit usages

---------

Co-authored-by: kjac <kja@umbraco.dk>
This commit is contained in:
Ronald Barendse
2024-05-14 13:34:54 +02:00
committed by GitHub
parent c7328bcbbc
commit cbf9781ae8
14 changed files with 281 additions and 286 deletions

View File

@@ -8,21 +8,10 @@ namespace Umbraco.Cms.Core.Models.Blocks;
/// </summary>
public class BlockEditorData<TValue, TLayout>
where TValue : BlockValue<TLayout>, new()
where TLayout : class, IBlockLayoutItem, new()
where TLayout : IBlockLayoutItem
{
private readonly string _propertyEditorAlias;
public BlockEditorData(
string propertyEditorAlias,
IEnumerable<ContentAndSettingsReference> references,
TValue blockValue)
public BlockEditorData(IEnumerable<ContentAndSettingsReference> references, TValue blockValue)
{
if (string.IsNullOrWhiteSpace(propertyEditorAlias))
{
throw new ArgumentException($"'{nameof(propertyEditorAlias)}' cannot be null or whitespace", nameof(propertyEditorAlias));
}
_propertyEditorAlias = propertyEditorAlias;
BlockValue = blockValue ?? throw new ArgumentNullException(nameof(blockValue));
References = references != null
? new List<ContentAndSettingsReference>(references)
@@ -30,17 +19,14 @@ public class BlockEditorData<TValue, TLayout>
}
private BlockEditorData()
{
_propertyEditorAlias = string.Empty;
BlockValue = new TValue();
}
=> BlockValue = new TValue();
public static BlockEditorData<TValue, TLayout> Empty { get; } = new();
/// <summary>
/// Returns the layout for this specific property editor
/// </summary>
public IEnumerable<TLayout>? Layout => BlockValue.GetLayouts(_propertyEditorAlias);
public IEnumerable<TLayout>? Layout => BlockValue.GetLayouts();
/// <summary>
/// Returns the reference to the original BlockValue

View File

@@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.Models.Blocks;
/// </summary>
public abstract class BlockEditorDataConverter<TValue, TLayout>
where TValue : BlockValue<TLayout>, new()
where TLayout : class, IBlockLayoutItem, new()
where TLayout : IBlockLayoutItem
{
private readonly IJsonSerializer _jsonSerializer;
@@ -42,7 +42,7 @@ public abstract class BlockEditorDataConverter<TValue, TLayout>
}
catch (Exception)
{
blockEditorData = null;
blockEditorData = default;
return false;
}
}
@@ -62,15 +62,13 @@ public abstract class BlockEditorDataConverter<TValue, TLayout>
public BlockEditorData<TValue, TLayout> Convert(TValue? value)
{
var propertyEditorAlias = new TValue().PropertyEditorAlias;
IEnumerable<TLayout>? layouts = value?.GetLayouts(propertyEditorAlias);
if (layouts is null)
if (value?.GetLayouts() is not IEnumerable<TLayout> layouts)
{
return BlockEditorData<TValue, TLayout>.Empty;
}
IEnumerable<ContentAndSettingsReference> references = GetBlockReferences(layouts);
return new BlockEditorData<TValue, TLayout>(propertyEditorAlias, references, value!);
return new BlockEditorData<TValue, TLayout>(references, value);
}
}

View File

@@ -1,8 +1,14 @@
namespace Umbraco.Cms.Core.Models.Blocks;
namespace Umbraco.Cms.Core.Models.Blocks;
public class BlockGridLayoutAreaItem
{
public Guid Key { get; set; } = Guid.Empty;
public BlockGridLayoutItem[] Items { get; set; } = Array.Empty<BlockGridLayoutItem>();
public BlockGridLayoutAreaItem()
{ }
public BlockGridLayoutAreaItem(Guid key)
=> Key = key;
}

View File

@@ -17,4 +17,14 @@ public class BlockGridLayoutItem : IBlockLayoutItem
public int? RowSpan { get; set; }
public BlockGridLayoutAreaItem[] Areas { get; set; } = Array.Empty<BlockGridLayoutAreaItem>();
public BlockGridLayoutItem()
{ }
public BlockGridLayoutItem(Udi contentUdi)
=> ContentUdi = contentUdi;
public BlockGridLayoutItem(Udi contentUdi, Udi settingsUdi)
: this(contentUdi)
=> SettingsUdi = settingsUdi;
}

View File

@@ -1,6 +1,23 @@
namespace Umbraco.Cms.Core.Models.Blocks;
namespace Umbraco.Cms.Core.Models.Blocks;
/// <summary>
/// Represents a block grid value.
/// </summary>
public class BlockGridValue : BlockValue<BlockGridLayoutItem>
{
/// <summary>
/// Initializes a new instance of the <see cref="BlockGridValue" /> class.
/// </summary>
public BlockGridValue()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="BlockGridValue" /> class.
/// </summary>
/// <param name="layouts">The layouts.</param>
public BlockGridValue(IEnumerable<BlockGridLayoutItem> layouts)
=> Layout[PropertyEditorAlias] = layouts;
/// <inheritdoc />
public override string PropertyEditorAlias => Constants.PropertyEditors.Aliases.BlockGrid;
}

View File

@@ -10,6 +10,17 @@ namespace Umbraco.Cms.Core.Models.Blocks;
/// </summary>
public class BlockItemData
{
public BlockItemData()
{
}
public BlockItemData(Udi udi, Guid contentTypeKey, string contentTypeAlias)
{
ContentTypeAlias = contentTypeAlias;
Udi = udi;
ContentTypeKey = contentTypeKey;
}
public Guid ContentTypeKey { get; set; }
/// <summary>

View File

@@ -11,4 +11,14 @@ public class BlockListLayoutItem : IBlockLayoutItem
public Udi? ContentUdi { get; set; }
public Udi? SettingsUdi { get; set; }
public BlockListLayoutItem()
{ }
public BlockListLayoutItem(Udi contentUdi)
=> ContentUdi = contentUdi;
public BlockListLayoutItem(Udi contentUdi, Udi settingsUdi)
: this(contentUdi)
=> SettingsUdi = settingsUdi;
}

View File

@@ -1,6 +1,23 @@
namespace Umbraco.Cms.Core.Models.Blocks;
namespace Umbraco.Cms.Core.Models.Blocks;
/// <summary>
/// Represents a block list value.
/// </summary>
public class BlockListValue : BlockValue<BlockListLayoutItem>
{
/// <summary>
/// Initializes a new instance of the <see cref="BlockListValue" /> class.
/// </summary>
public BlockListValue()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="BlockListValue" /> class.
/// </summary>
/// <param name="layouts">The layouts.</param>
public BlockListValue(IEnumerable<BlockListLayoutItem> layouts)
=> Layout[PropertyEditorAlias] = layouts;
/// <inheritdoc />
public override string PropertyEditorAlias => Constants.PropertyEditors.Aliases.BlockList;
}

View File

@@ -3,22 +3,56 @@
namespace Umbraco.Cms.Core.Models.Blocks;
/// <summary>
/// Represents a block value.
/// </summary>
public abstract class BlockValue
{
/// <summary>
/// Gets or sets the layout for specific property editors.
/// </summary>
/// <value>
/// The layout.
/// </value>
public IDictionary<string, IEnumerable<IBlockLayoutItem>> Layout { get; set; } = new Dictionary<string, IEnumerable<IBlockLayoutItem>>();
/// <summary>
/// Gets or sets the content data.
/// </summary>
/// <value>
/// The content data.
/// </value>
public List<BlockItemData> ContentData { get; set; } = [];
/// <summary>
/// Gets or sets the settings data.
/// </summary>
/// <value>
/// The settings data.
/// </value>
public List<BlockItemData> SettingsData { get; set; } = [];
/// <summary>
/// Gets the property editor alias of the current layout.
/// </summary>
/// <value>
/// The property editor alias of the current layout.
/// </value>
public abstract string PropertyEditorAlias { get; }
}
/// <inheritdoc />
public abstract class BlockValue<TLayout> : BlockValue
where TLayout : IBlockLayoutItem
{
public IEnumerable<TLayout>? GetLayouts(string propertyEditorAlias)
=> Layout.TryGetValue(propertyEditorAlias, out IEnumerable<IBlockLayoutItem>? layouts) is true
/// <summary>
/// Gets the layouts of the current property editor.
/// </summary>
/// <returns>
/// The layouts.
/// </returns>
public IEnumerable<TLayout>? GetLayouts()
=> Layout.TryGetValue(PropertyEditorAlias, out IEnumerable<IBlockLayoutItem>? layouts)
? layouts.OfType<TLayout>()
: null;
}
public abstract class BlockValue
{
public IDictionary<string, IEnumerable<IBlockLayoutItem>> Layout { get; set; } = new Dictionary<string, IEnumerable<IBlockLayoutItem>>();
public List<BlockItemData> ContentData { get; set; } = new();
public List<BlockItemData> SettingsData { get; set; } = new();
public abstract string PropertyEditorAlias { get; }
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
namespace Umbraco.Cms.Core.Models.Blocks;
@@ -11,4 +11,14 @@ public class RichTextBlockLayoutItem : IBlockLayoutItem
public Udi? ContentUdi { get; set; }
public Udi? SettingsUdi { get; set; }
public RichTextBlockLayoutItem()
{ }
public RichTextBlockLayoutItem(Udi contentUdi)
=> ContentUdi = contentUdi;
public RichTextBlockLayoutItem(Udi contentUdi, Udi settingsUdi)
: this(contentUdi)
=> SettingsUdi = settingsUdi;
}

View File

@@ -1,6 +1,23 @@
namespace Umbraco.Cms.Core.Models.Blocks;
/// <summary>
/// Represents a rich text block value.
/// </summary>
public class RichTextBlockValue : BlockValue<RichTextBlockLayoutItem>
{
/// <summary>
/// Initializes a new instance of the <see cref="RichTextBlockValue" /> class.
/// </summary>
public RichTextBlockValue()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="RichTextBlockValue" /> class.
/// </summary>
/// <param name="layouts">The layouts.</param>
public RichTextBlockValue(IEnumerable<RichTextBlockLayoutItem> layouts)
=> Layout[PropertyEditorAlias] = layouts;
/// <inheritdoc />
public override string PropertyEditorAlias => Constants.PropertyEditors.Aliases.TinyMce;
}