using System.ComponentModel.DataAnnotations;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Validation;
using Umbraco.Cms.Core.PropertyEditors.Validation;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.PropertyEditors;
///
/// Represents an entity data picker property editor.
///
[DataEditor(
Constants.PropertyEditors.Aliases.EntityDataPicker,
ValueType = ValueTypes.Json,
ValueEditorIsReusable = true)]
internal sealed class EntityDataPickerPropertyEditor : DataEditor
{
private readonly IIOHelper _ioHelper;
///
/// Initializes a new instance of the class.
///
public EntityDataPickerPropertyEditor(IDataValueEditorFactory dataValueEditorFactory, IIOHelper ioHelper)
: base(dataValueEditorFactory)
{
_ioHelper = ioHelper;
SupportsReadOnly = true;
}
///
public override IPropertyIndexValueFactory PropertyIndexValueFactory { get; } = new NoopPropertyIndexValueFactory();
///
protected override IDataValueEditor CreateValueEditor()
=> DataValueEditorFactory.Create(Attribute!);
///
protected override IConfigurationEditor CreateConfigurationEditor() => new EntityDataPickerConfigurationEditor(_ioHelper);
///
/// Defines the value editor for the entity data picker property editor.
///
internal sealed class EntityDataPickerPropertyValueEditor : DataValueEditor
{
///
/// Initializes a new instance of the class.
///
public EntityDataPickerPropertyValueEditor(
IShortStringHelper shortStringHelper,
IJsonSerializer jsonSerializer,
IIOHelper ioHelper,
DataEditorAttribute attribute,
ILocalizedTextService localizedTextService)
: base(shortStringHelper, jsonSerializer, ioHelper, attribute)
{
var validators = new TypedJsonValidatorRunner(
jsonSerializer,
new MinMaxValidator(localizedTextService));
Validators.Add(validators);
}
///
/// Validates the min/max configuration for the entity data picker property editor.
///
internal sealed class MinMaxValidator : ITypedJsonValidator
{
private readonly ILocalizedTextService _localizedTextService;
///
/// Initializes a new instance of the class.
///
public MinMaxValidator(ILocalizedTextService localizedTextService) =>
_localizedTextService = localizedTextService;
///
public IEnumerable Validate(
EntityDataPickerDto? data,
EntityDataPickerConfiguration? configuration,
string? valueType,
PropertyValidationContext validationContext)
{
var validationResults = new List();
if (data is null || configuration is null)
{
return validationResults;
}
if (configuration.ValidationLimit.Min is not null
&& data.Ids.Length < configuration.ValidationLimit.Min)
{
validationResults.Add(new ValidationResult(
_localizedTextService.Localize(
"validation",
"entriesShort",
[configuration.ValidationLimit.Min.ToString(), (configuration.ValidationLimit.Min - data.Ids.Length).ToString()]),
["value"]));
}
if (configuration.ValidationLimit.Max is not null
&& data.Ids.Length > configuration.ValidationLimit.Max)
{
validationResults.Add(new ValidationResult(
_localizedTextService.Localize(
"validation",
"entriesExceed",
[configuration.ValidationLimit.Max.ToString(), (data.Ids.Length - configuration.ValidationLimit.Max).ToString()
]),
["value"]));
}
return validationResults;
}
}
}
internal sealed class EntityDataPickerDto
{
public string[] Ids { get; set; } = [];
}
}