From ddc922a583e24582d9c1918667d50d91a7e5921b Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Tue, 8 Sep 2020 12:08:27 +0200 Subject: [PATCH] 8.7RC Add generic BlockListItem classes (#8841) (cherry picked from commit 5faa9ae22fbf0f7f0a41a4bbe7fef243d2171fc0) --- .../Models/Blocks/BlockListItem.cs | 111 ++++++++++++++++-- .../Models/Blocks/BlockListModel.cs | 77 ++++++------ .../Blocks/ContentAndSettingsReference.cs | 26 ++-- .../Models/Blocks/IBlockReference.cs | 41 ++++--- .../BlockListPropertyValueConverter.cs | 4 +- 5 files changed, 173 insertions(+), 86 deletions(-) diff --git a/src/Umbraco.Core/Models/Blocks/BlockListItem.cs b/src/Umbraco.Core/Models/Blocks/BlockListItem.cs index f4b5c489e7..620c3d9fe0 100644 --- a/src/Umbraco.Core/Models/Blocks/BlockListItem.cs +++ b/src/Umbraco.Core/Models/Blocks/BlockListItem.cs @@ -5,41 +5,126 @@ using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Core.Models.Blocks { /// - /// Represents a layout item for the Block List editor + /// Represents a layout item for the Block List editor. /// + /// [DataContract(Name = "block", Namespace = "")] public class BlockListItem : IBlockReference { + /// + /// Initializes a new instance of the class. + /// + /// The content UDI. + /// The content. + /// The settings UDI. + /// The settings. + /// contentUdi + /// or + /// content public BlockListItem(Udi contentUdi, IPublishedElement content, Udi settingsUdi, IPublishedElement settings) { - ContentUdi = contentUdi ?? throw new ArgumentNullException(nameof(contentUdi)); + ContentUdi = contentUdi ?? throw new ArgumentNullException(nameof(contentUdi)); Content = content ?? throw new ArgumentNullException(nameof(content)); - Settings = settings; // can be null - SettingsUdi = settingsUdi; // can be null + SettingsUdi = settingsUdi; + Settings = settings; } /// - /// The Id of the content data item + /// Gets the content UDI. /// + /// + /// The content UDI. + /// [DataMember(Name = "contentUdi")] public Udi ContentUdi { get; } /// - /// The Id of the settings data item - /// - [DataMember(Name = "settingsUdi")] - public Udi SettingsUdi { get; } - - /// - /// The content data item referenced + /// Gets the content. /// + /// + /// The content. + /// [DataMember(Name = "content")] public IPublishedElement Content { get; } /// - /// The settings data item referenced + /// Gets the settings UDI. /// + /// + /// The settings UDI. + /// + [DataMember(Name = "settingsUdi")] + public Udi SettingsUdi { get; } + + /// + /// Gets the settings. + /// + /// + /// The settings. + /// [DataMember(Name = "settings")] public IPublishedElement Settings { get; } } + + /// + /// Represents a layout item with a generic content type for the Block List editor. + /// + /// The type of the content. + /// + public class BlockListItem : BlockListItem + where T : IPublishedElement + { + /// + /// Initializes a new instance of the class. + /// + /// The content UDI. + /// The content. + /// The settings UDI. + /// The settings. + public BlockListItem(Udi contentUdi, T content, Udi settingsUdi, IPublishedElement settings) + : base(contentUdi, content, settingsUdi, settings) + { + Content = content; + } + + /// + /// Gets the content. + /// + /// + /// The content. + /// + public new T Content { get; } + } + + /// + /// Represents a layout item with generic content and settings types for the Block List editor. + /// + /// The type of the content. + /// The type of the settings. + /// + public class BlockListItem : BlockListItem + where TContent : IPublishedElement + where TSettings : IPublishedElement + { + /// + /// Initializes a new instance of the class. + /// + /// The content udi. + /// The content. + /// The settings udi. + /// The settings. + public BlockListItem(Udi contentUdi, TContent content, Udi settingsUdi, TSettings settings) + : base(contentUdi, content, settingsUdi, settings) + { + Settings = settings; + } + + /// + /// Gets the settings. + /// + /// + /// The settings. + /// + public new TSettings Settings { get; } + } } diff --git a/src/Umbraco.Core/Models/Blocks/BlockListModel.cs b/src/Umbraco.Core/Models/Blocks/BlockListModel.cs index 9a5a3af22a..9a3a26ab30 100644 --- a/src/Umbraco.Core/Models/Blocks/BlockListModel.cs +++ b/src/Umbraco.Core/Models/Blocks/BlockListModel.cs @@ -1,64 +1,63 @@ using System; -using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Runtime.Serialization; -using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Core.Models.Blocks { /// - /// The strongly typed model for the Block List editor + /// The strongly typed model for the Block List editor. /// + /// [DataContract(Name = "blockList", Namespace = "")] - public class BlockListModel : IReadOnlyList + public class BlockListModel : ReadOnlyCollection { - private readonly IReadOnlyList _layout = new List(); - + /// + /// Gets the empty . + /// + /// + /// The empty . + /// public static BlockListModel Empty { get; } = new BlockListModel(); + /// + /// Prevents a default instance of the class from being created. + /// private BlockListModel() - { - } - - public BlockListModel(IEnumerable layout) - { - _layout = layout.ToList(); - } - - public int Count => _layout.Count; + : this(new List()) + { } /// - /// Get the block by index + /// Initializes a new instance of the class. /// - /// - /// - public BlockListItem this[int index] => _layout[index]; + /// The list to wrap. + public BlockListModel(IList list) + : base(list) + { } /// - /// Get the block by content Guid + /// Gets the with the specified content key. /// - /// - /// - public BlockListItem this[Guid contentKey] => _layout.FirstOrDefault(x => x.Content.Key == contentKey); + /// + /// The . + /// + /// The content key. + /// + /// The with the specified content key. + /// + public BlockListItem this[Guid contentKey] => this.FirstOrDefault(x => x.Content.Key == contentKey); /// - /// Get the block by content element Udi + /// Gets the with the specified content UDI. /// - /// - /// - public BlockListItem this[Udi contentUdi] - { - get - { - if (!(contentUdi is GuidUdi guidUdi)) return null; - return _layout.FirstOrDefault(x => x.Content.Key == guidUdi.Guid); - } - } - - public IEnumerator GetEnumerator() => _layout.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - + /// + /// The . + /// + /// The content UDI. + /// + /// The with the specified content UDI. + /// + public BlockListItem this[Udi contentUdi] => contentUdi is GuidUdi guidUdi ? this.FirstOrDefault(x => x.Content.Key == guidUdi.Guid) : null; } } diff --git a/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs b/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs index 523a964c7b..f7222fe140 100644 --- a/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs +++ b/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using System; +using System; +using System.Collections.Generic; namespace Umbraco.Core.Models.Blocks { @@ -12,26 +12,16 @@ namespace Umbraco.Core.Models.Blocks } public Udi ContentUdi { get; } + public Udi SettingsUdi { get; } - public override bool Equals(object obj) - { - return obj is ContentAndSettingsReference reference && Equals(reference); - } + public override bool Equals(object obj) => obj is ContentAndSettingsReference reference && Equals(reference); - public bool Equals(ContentAndSettingsReference other) - { - return EqualityComparer.Default.Equals(ContentUdi, other.ContentUdi) && - EqualityComparer.Default.Equals(SettingsUdi, other.SettingsUdi); - } + public bool Equals(ContentAndSettingsReference other) => other != null + && EqualityComparer.Default.Equals(ContentUdi, other.ContentUdi) + && EqualityComparer.Default.Equals(SettingsUdi, other.SettingsUdi); - public override int GetHashCode() - { - var hashCode = 272556606; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ContentUdi); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(SettingsUdi); - return hashCode; - } + public override int GetHashCode() => (ContentUdi, SettingsUdi).GetHashCode(); public static bool operator ==(ContentAndSettingsReference left, ContentAndSettingsReference right) { diff --git a/src/Umbraco.Core/Models/Blocks/IBlockReference.cs b/src/Umbraco.Core/Models/Blocks/IBlockReference.cs index 8d8ddd47f0..7f5c835b3c 100644 --- a/src/Umbraco.Core/Models/Blocks/IBlockReference.cs +++ b/src/Umbraco.Core/Models/Blocks/IBlockReference.cs @@ -1,26 +1,37 @@ namespace Umbraco.Core.Models.Blocks { - /// - /// Represents a data item reference for a Block editor implementation - /// - /// - /// - /// see: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed - /// - public interface IBlockReference : IBlockReference - { - TSettings Settings { get; } - } - - /// - /// Represents a data item reference for a Block Editor implementation + /// Represents a data item reference for a Block Editor implementation. /// /// - /// see: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed + /// See: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed /// public interface IBlockReference { + /// + /// Gets the content UDI. + /// + /// + /// The content UDI. + /// Udi ContentUdi { get; } } + + /// + /// Represents a data item reference with settings for a Block editor implementation. + /// + /// The type of the settings. + /// + /// See: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed + /// + public interface IBlockReference : IBlockReference + { + /// + /// Gets the settings. + /// + /// + /// The settings. + /// + TSettings Settings { get; } + } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs index 0c90a41fbd..f46c118174 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs @@ -120,7 +120,9 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters settingsData = null; } - var layoutRef = new BlockListItem(contentGuidUdi, contentData, settingGuidUdi, settingsData); + var layoutType = typeof(BlockListItem<,>).MakeGenericType(contentData.GetType(), settingsData?.GetType() ?? typeof(IPublishedElement)); + var layoutRef = (BlockListItem)Activator.CreateInstance(layoutType, contentGuidUdi, contentData, settingGuidUdi, settingsData); + layout.Add(layoutRef); }