Improved developer experience for AdminContext's
This commit is contained in:
@@ -22,7 +22,7 @@ public interface IAdminPageGenerator<TModel> {
|
||||
|
||||
IAdminPageGenerator<TModel> ConfigureRepository<TRepository>() where TRepository : ModelRepository<TModel>;
|
||||
|
||||
IAdminPropertyGenerator<TProperty> Property<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Property<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression);
|
||||
IAdminPageGenerator<TModel> ListingProperty<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,28 +2,27 @@ using System.Linq.Expressions;
|
||||
|
||||
namespace HopFrame.Web.Admin.Generators;
|
||||
|
||||
public interface IAdminPropertyGenerator<TProperty> {
|
||||
public interface IAdminPropertyGenerator<TProperty, TModel> {
|
||||
|
||||
IAdminPropertyGenerator<TProperty> Sortable(bool sortable);
|
||||
IAdminPropertyGenerator<TProperty> Editable(bool editable);
|
||||
IAdminPropertyGenerator<TProperty> DisplayValueWhileEditing(bool display);
|
||||
IAdminPropertyGenerator<TProperty> DisplayInListing(bool display = true);
|
||||
IAdminPropertyGenerator<TProperty> Ignore(bool ignore = true);
|
||||
IAdminPropertyGenerator<TProperty> Generated(bool generated = true);
|
||||
IAdminPropertyGenerator<TProperty> Bold(bool bold = true);
|
||||
IAdminPropertyGenerator<TProperty> Unique(bool unique = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Sortable(bool sortable);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Editable(bool editable);
|
||||
IAdminPropertyGenerator<TProperty, TModel> DisplayValueWhileEditing(bool display);
|
||||
IAdminPropertyGenerator<TProperty, TModel> DisplayInListing(bool display = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Ignore(bool ignore = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Generated(bool generated = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Bold(bool bold = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Unique(bool unique = true);
|
||||
|
||||
IAdminPropertyGenerator<TProperty> DisplayName(string displayName);
|
||||
IAdminPropertyGenerator<TProperty> Description(string description);
|
||||
IAdminPropertyGenerator<TProperty> Prefix(string prefix);
|
||||
IAdminPropertyGenerator<TProperty> Validator(Func<TProperty, string> validator);
|
||||
IAdminPropertyGenerator<TProperty> IsSelector(bool selector = true);
|
||||
IAdminPropertyGenerator<TProperty> IsSelector<TSelectorType>(bool selector = true);
|
||||
IAdminPropertyGenerator<TProperty> Parser<TModel>(Func<TModel, string, TProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty> Parser<TModel, TInput>(Func<TModel, TInput, TProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty> ParserForListType<TModel, TInnerProperty>(Func<TModel, string, TInnerProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty> ParserForListType<TModel, TInnerProperty, TInput>(Func<TModel, TInput, TInnerProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty> DisplayProperty<TListingProperty>(Expression<Func<TProperty, TListingProperty>> propertyExpression);
|
||||
IAdminPropertyGenerator<TProperty> DisplayPropertyForListType<TInnerProperty>(Expression<Func<TInnerProperty, object>> propertyExpression);
|
||||
IAdminPropertyGenerator<TProperty, TModel> DisplayName(string displayName);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Description(string description);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Prefix(string prefix);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Validator(Func<TProperty, string> validator);
|
||||
IAdminPropertyGenerator<TProperty, TModel> IsSelector(bool selector = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> IsSelector<TSelectorType>(bool selector = true);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Parser(Func<TModel, string, TProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Parser<TInput>(Func<TModel, TInput, TProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty, TModel> Parser<TInput, TInnerProperty>(Func<TModel, TInput, TInnerProperty> parser);
|
||||
IAdminPropertyGenerator<TProperty, TModel> DisplayProperty(Expression<Func<TProperty, object>> propertyExpression);
|
||||
IAdminPropertyGenerator<TProperty, TModel> DisplayProperty<TInnerProperty>(Expression<Func<TInnerProperty, object>> propertyExpression);
|
||||
|
||||
}
|
||||
@@ -21,16 +21,16 @@ internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>,
|
||||
|
||||
var type = typeof(TModel);
|
||||
var properties = type.GetProperties();
|
||||
var generatorType = typeof(AdminPropertyGenerator<>);
|
||||
var generatorType = typeof(AdminPropertyGenerator<,>);
|
||||
|
||||
foreach (var property in properties) {
|
||||
var attributes = property.GetCustomAttributes(false);
|
||||
var genericType = generatorType.MakeGenericType(property.PropertyType);
|
||||
var genericType = generatorType.MakeGenericType(property.PropertyType, type);
|
||||
|
||||
var generator = Activator.CreateInstance(genericType, [property.Name, property.PropertyType]);
|
||||
|
||||
var method = genericType
|
||||
.GetMethod(nameof(AdminPropertyGenerator<object>.ApplyConfigurationFromAttributes))?
|
||||
.GetMethod(nameof(AdminPropertyGenerator<object, object>.ApplyConfigurationFromAttributes))?
|
||||
.MakeGenericMethod(type);
|
||||
method?.Invoke(generator, [this, attributes, property]);
|
||||
|
||||
@@ -102,13 +102,13 @@ internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>,
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Property<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Property<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression) {
|
||||
var property = GetPropertyInfo(propertyExpression);
|
||||
|
||||
if (_propertyGenerators.TryGetValue(property.Name, out var propertyGenerator))
|
||||
return propertyGenerator as AdminPropertyGenerator<TProperty>;
|
||||
return propertyGenerator as AdminPropertyGenerator<TProperty, TModel>;
|
||||
|
||||
var generator = Activator.CreateInstance(typeof(AdminPropertyGenerator<TProperty>), new { property.Name, property.PropertyType }) as AdminPropertyGenerator<TProperty>;
|
||||
var generator = Activator.CreateInstance(typeof(AdminPropertyGenerator<TProperty, TModel>), new { property.Name, property.PropertyType }) as AdminPropertyGenerator<TProperty, TModel>;
|
||||
generator?.ApplyConfigurationFromAttributes(this, property.GetCustomAttributes(false), property);
|
||||
_propertyGenerators.Add(property.Name, generator);
|
||||
|
||||
@@ -125,7 +125,7 @@ internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>,
|
||||
var properties = new List<AdminPageProperty>();
|
||||
|
||||
foreach (var generator in _propertyGenerators.Values) {
|
||||
var method = generator.GetType().GetMethod(nameof(AdminPropertyGenerator<object>.Compile));
|
||||
var method = generator.GetType().GetMethod(nameof(AdminPropertyGenerator<object, object>.Compile));
|
||||
var prop = method?.Invoke(generator, []) as AdminPageProperty;
|
||||
properties.Add(prop);
|
||||
}
|
||||
|
||||
@@ -8,112 +8,107 @@ using HopFrame.Web.Admin.Models;
|
||||
|
||||
namespace HopFrame.Web.Admin.Generators.Implementation;
|
||||
|
||||
internal sealed class AdminPropertyGenerator<TProperty>(string name, Type type) : IAdminPropertyGenerator<TProperty>, IGenerator<AdminPageProperty> {
|
||||
internal sealed class AdminPropertyGenerator<TProperty, TModel>(string name, Type type) : IAdminPropertyGenerator<TProperty, TModel>, IGenerator<AdminPageProperty> {
|
||||
|
||||
private readonly AdminPageProperty _property = new() {
|
||||
Name = name,
|
||||
Type = type
|
||||
};
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Sortable(bool sortable) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Sortable(bool sortable) {
|
||||
_property.Sortable = sortable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Editable(bool editable) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Editable(bool editable) {
|
||||
_property.Editable = editable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayValueWhileEditing(bool display) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> DisplayValueWhileEditing(bool display) {
|
||||
_property.EditDisplayValue = display;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayInListing(bool display = true) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> DisplayInListing(bool display = true) {
|
||||
_property.DisplayInListing = display;
|
||||
_property.Sortable = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Ignore(bool ignore = false) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Ignore(bool ignore = false) {
|
||||
_property.Ignore = ignore;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Generated(bool generated = true) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Generated(bool generated = true) {
|
||||
_property.Generated = generated;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Bold(bool bold = true) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Bold(bool bold = true) {
|
||||
_property.Bold = bold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Unique(bool unique = true) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Unique(bool unique = true) {
|
||||
_property.Unique = unique;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayName(string displayName) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> DisplayName(string displayName) {
|
||||
_property.DisplayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Description(string description) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Description(string description) {
|
||||
_property.Description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Prefix(string prefix) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Prefix(string prefix) {
|
||||
_property.Prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Validator(Func<TProperty, string> validator) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Validator(Func<TProperty, string> validator) {
|
||||
_property.Validator = o => validator.Invoke((TProperty)o);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> IsSelector(bool selector = true) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> IsSelector(bool selector = true) {
|
||||
_property.Selector = selector;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> IsSelector<TSelectorType>(bool selector = true) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> IsSelector<TSelectorType>(bool selector = true) {
|
||||
_property.Selector = true;
|
||||
_property.SelectorType = typeof(TSelectorType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Parser<TModel>(Func<TModel, string, TProperty> parser) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Parser(Func<TModel, string, TProperty> parser) {
|
||||
_property.Parser = (o, s) => parser.Invoke((TModel)o, s.ToString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> Parser<TModel, TInput>(Func<TModel, TInput, TProperty> parser) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Parser<TInput>(Func<TModel, TInput, TProperty> parser) {
|
||||
_property.Parser = (o, s) => parser.Invoke((TModel)o, (TInput)s);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> ParserForListType<TModel, TInnerProperty>(Func<TModel, string, TInnerProperty> parser) {
|
||||
_property.Parser = (o, s) => parser.Invoke((TModel)o, s.ToString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> ParserForListType<TModel, TInnerProperty, TInput>(Func<TModel, TInput, TInnerProperty> parser) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> Parser<TInput, TInnerProperty>(Func<TModel, TInput, TInnerProperty> parser) {
|
||||
_property.Parser = (o, s) => parser.Invoke((TModel)o, (TInput)s);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayProperty<TListingProperty>(Expression<Func<TProperty, TListingProperty>> propertyExpression) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> DisplayProperty(Expression<Func<TProperty, object>> propertyExpression) {
|
||||
var property = AdminPageGenerator<object>.GetPropertyInfo(propertyExpression);
|
||||
_property.DisplayPropertyName = property.Name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayPropertyForListType<TInnerProperty>(Expression<Func<TInnerProperty, object>> propertyExpression) {
|
||||
public IAdminPropertyGenerator<TProperty, TModel> DisplayProperty<TInnerProperty>(Expression<Func<TInnerProperty, object>> propertyExpression) {
|
||||
var property = AdminPageGenerator<object>.GetPropertyInfo(propertyExpression);
|
||||
_property.DisplayPropertyName = property.Name;
|
||||
return this;
|
||||
|
||||
@@ -40,8 +40,8 @@ public class HopAdminContext : AdminPagesContext {
|
||||
|
||||
generator.Page<User>().Property(u => u.Permissions)
|
||||
.DisplayInListing(false)
|
||||
.DisplayPropertyForListType<Permission>(p => p.PermissionName)
|
||||
.ParserForListType<User, Permission>((user, perm) => new Permission {
|
||||
.DisplayProperty<Permission>(p => p.PermissionName)
|
||||
.Parser<string, Permission>((user, perm) => new Permission {
|
||||
GrantedAt = DateTime.Now,
|
||||
PermissionName = perm,
|
||||
User = user
|
||||
@@ -78,8 +78,8 @@ public class HopAdminContext : AdminPagesContext {
|
||||
|
||||
generator.Page<PermissionGroup>().Property(g => g.Permissions)
|
||||
.DisplayInListing(false)
|
||||
.DisplayPropertyForListType<Permission>(p => p.PermissionName)
|
||||
.ParserForListType<PermissionGroup, Permission>((group, perm) => new Permission {
|
||||
.DisplayProperty<Permission>(p => p.PermissionName)
|
||||
.Parser<string, Permission>((group, perm) => new Permission {
|
||||
GrantedAt = DateTime.Now,
|
||||
PermissionName = perm,
|
||||
Group = group
|
||||
|
||||
@@ -25,7 +25,7 @@ public class AdminContext : AdminPagesContext {
|
||||
generator.Page<Address>()
|
||||
.Property(a => a.AddressId)
|
||||
.IsSelector<Employee>()
|
||||
.Parser<Address, Employee>((model, e) => model.AddressId = e.EmployeeId);
|
||||
.Parser<Employee>((model, e) => model.AddressId = e.EmployeeId);
|
||||
|
||||
generator.Page<Employee>()
|
||||
.ConfigureRepository<EmployeeProvider>()
|
||||
|
||||
Reference in New Issue
Block a user