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