From 9cf818c55d6e5656205ff3f1d1d2acf73f46ad48 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Sat, 5 Oct 2024 12:18:32 +0200 Subject: [PATCH] Created static object provider + added some properties --- .../HopFrame.Database.csproj | 4 -- .../Models/PermissionGroup.cs | 9 +-- src/HopFrame.Database/Models/User.cs | 10 +--- src/HopFrame.Web.Admin/AdminPagesContext.cs | 2 +- .../Attributes/AdminDescriptionAttribute.cs | 2 +- .../Attributes/AdminNameAttribute.cs | 2 +- .../Classes/AdminButtonConfigAttribute.cs | 2 +- .../Classes/AdminPermissionsAttribute.cs | 9 ++- .../Attributes/Members/AdminBoldAttribute.cs | 2 +- .../Members/AdminHideValueAttribute.cs | 2 +- .../Members/AdminIgnoreAttribute.cs | 2 +- .../Members/AdminPrefixAttribute.cs | 6 ++ .../Members/AdminUneditableAttribute.cs | 2 +- .../Members/AdminUnsortableAttribute.cs | 2 +- .../Generators/IAdminPropertyGenerator.cs | 2 + .../Implementation/AdminContextGenerator.cs | 14 ++++- .../Implementation/AdminPageGenerator.cs | 14 +++-- .../Implementation/AdminPropertyGenerator.cs | 11 ++++ src/HopFrame.Web.Admin/Models/AdminPage.cs | 7 ++- .../Models/AdminPagePermissions.cs | 2 +- .../Models/AdminPageProperty.cs | 4 +- .../Providers/IAdminPagesProvider.cs | 11 ++++ .../Implementation/AdminPagesProvider.cs | 19 +++++++ .../ServiceCollectionExtensions.cs | 20 +++++-- src/HopFrame.Web/HopAdminContext.cs | 55 +++++++++++++++++++ .../ServiceCollectionExtensions.cs | 2 + .../Components/Pages/Counter.razor | 11 ++++ test/RestApiTest/AdminContext.cs | 26 --------- .../RestApiTest/Controllers/TestController.cs | 7 +-- test/RestApiTest/Program.cs | 2 - 30 files changed, 186 insertions(+), 77 deletions(-) create mode 100644 src/HopFrame.Web.Admin/Attributes/Members/AdminPrefixAttribute.cs create mode 100644 src/HopFrame.Web.Admin/Providers/IAdminPagesProvider.cs create mode 100644 src/HopFrame.Web.Admin/Providers/Implementation/AdminPagesProvider.cs create mode 100644 src/HopFrame.Web/HopAdminContext.cs delete mode 100644 test/RestApiTest/AdminContext.cs diff --git a/src/HopFrame.Database/HopFrame.Database.csproj b/src/HopFrame.Database/HopFrame.Database.csproj index 1216958..f2bcba7 100644 --- a/src/HopFrame.Database/HopFrame.Database.csproj +++ b/src/HopFrame.Database/HopFrame.Database.csproj @@ -22,8 +22,4 @@ - - - - diff --git a/src/HopFrame.Database/Models/PermissionGroup.cs b/src/HopFrame.Database/Models/PermissionGroup.cs index 0a0c669..7a70ebd 100644 --- a/src/HopFrame.Database/Models/PermissionGroup.cs +++ b/src/HopFrame.Database/Models/PermissionGroup.cs @@ -1,27 +1,22 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using HopFrame.Web.Admin.Attributes; -using HopFrame.Web.Admin.Attributes.Members; namespace HopFrame.Database.Models; -[AdminName("Groups")] -[AdminDescription("On this page you can view, create, edit and delete permission groups.")] public class PermissionGroup : IPermissionOwner { [Key, Required, MaxLength(50)] public string Name { get; init; } - [Required, DefaultValue(false), AdminUnsortable] + [Required, DefaultValue(false)] public bool IsDefaultGroup { get; set; } [MaxLength(500)] public string Description { get; set; } - [Required, AdminUneditable] + [Required] public DateTime CreatedAt { get; set; } - [AdminIgnore(onlyForListing: true)] public virtual IList Permissions { get; set; } } \ No newline at end of file diff --git a/src/HopFrame.Database/Models/User.cs b/src/HopFrame.Database/Models/User.cs index ab944f0..971d899 100644 --- a/src/HopFrame.Database/Models/User.cs +++ b/src/HopFrame.Database/Models/User.cs @@ -1,11 +1,8 @@ using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; -using HopFrame.Web.Admin.Attributes; -using HopFrame.Web.Admin.Attributes.Members; namespace HopFrame.Database.Models; -[AdminDescription("On this page you can manage all user accounts.")] public class User : IPermissionOwner { [Key, Required, MinLength(36), MaxLength(36)] @@ -17,16 +14,15 @@ public class User : IPermissionOwner { [Required, MaxLength(50), EmailAddress] public string Email { get; set; } - [Required, MinLength(8), MaxLength(255), JsonIgnore, AdminIgnore(onlyForListing: true), AdminHideValue] + [Required, MinLength(8), MaxLength(255), JsonIgnore] public string Password { get; set; } - [Required, AdminUneditable] + [Required] public DateTime CreatedAt { get; set; } - [AdminIgnore(onlyForListing: true)] public virtual IList Permissions { get; set; } - [JsonIgnore, AdminIgnore] + [JsonIgnore] public virtual IList Tokens { get; set; } } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/AdminPagesContext.cs b/src/HopFrame.Web.Admin/AdminPagesContext.cs index 7be251e..39b769c 100644 --- a/src/HopFrame.Web.Admin/AdminPagesContext.cs +++ b/src/HopFrame.Web.Admin/AdminPagesContext.cs @@ -4,6 +4,6 @@ namespace HopFrame.Web.Admin; public abstract class AdminPagesContext { - public abstract void OnModelCreating(IAdminContextGenerator generator); + public virtual void OnModelCreating(IAdminContextGenerator generator) {} } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Attributes/AdminDescriptionAttribute.cs b/src/HopFrame.Web.Admin/Attributes/AdminDescriptionAttribute.cs index 843f250..92e3fe3 100644 --- a/src/HopFrame.Web.Admin/Attributes/AdminDescriptionAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/AdminDescriptionAttribute.cs @@ -1,6 +1,6 @@ namespace HopFrame.Web.Admin.Attributes; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] -public class AdminDescriptionAttribute(string description) : Attribute { +public sealed class AdminDescriptionAttribute(string description) : Attribute { public string Description { get; set; } = description; } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Attributes/AdminNameAttribute.cs b/src/HopFrame.Web.Admin/Attributes/AdminNameAttribute.cs index aaa8bac..90821c3 100644 --- a/src/HopFrame.Web.Admin/Attributes/AdminNameAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/AdminNameAttribute.cs @@ -1,6 +1,6 @@ namespace HopFrame.Web.Admin.Attributes; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] -public class AdminNameAttribute(string name) : Attribute { +public sealed class AdminNameAttribute(string name) : Attribute { public string Name { get; set; } = name; } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Attributes/Classes/AdminButtonConfigAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Classes/AdminButtonConfigAttribute.cs index 2995164..ccd3c8f 100644 --- a/src/HopFrame.Web.Admin/Attributes/Classes/AdminButtonConfigAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Classes/AdminButtonConfigAttribute.cs @@ -1,7 +1,7 @@ namespace HopFrame.Web.Admin.Attributes.Classes; [AttributeUsage(AttributeTargets.Class)] -public class AdminButtonConfigAttribute(bool showCreateButton = true, bool showDeleteButton = true, bool showUpdateButton = true) : Attribute { +public sealed class AdminButtonConfigAttribute(bool showCreateButton = true, bool showDeleteButton = true, bool showUpdateButton = true) : Attribute { public bool ShowCreateButton { get; set; } = showCreateButton; public bool ShowDeleteButton { get; set; } = showDeleteButton; public bool ShowUpdateButton { get; set; } = showUpdateButton; diff --git a/src/HopFrame.Web.Admin/Attributes/Classes/AdminPermissionsAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Classes/AdminPermissionsAttribute.cs index 59b0747..7d68eab 100644 --- a/src/HopFrame.Web.Admin/Attributes/Classes/AdminPermissionsAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Classes/AdminPermissionsAttribute.cs @@ -3,6 +3,11 @@ using HopFrame.Web.Admin.Models; namespace HopFrame.Web.Admin.Attributes.Classes; [AttributeUsage(AttributeTargets.Class)] -public class AdminPermissionsAttribute(AdminPagePermissions permissions) : Attribute { - public AdminPagePermissions Permissions { get; set; } = permissions; +public sealed class AdminPermissionsAttribute(string view = null, string create = null, string update = null, string delete = null) : Attribute { + public AdminPagePermissions Permissions { get; set; } = new() { + Create = create, + Update = update, + Delete = delete, + View = view + }; } diff --git a/src/HopFrame.Web.Admin/Attributes/Members/AdminBoldAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Members/AdminBoldAttribute.cs index 70fa63e..68311b2 100644 --- a/src/HopFrame.Web.Admin/Attributes/Members/AdminBoldAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Members/AdminBoldAttribute.cs @@ -1,4 +1,4 @@ namespace HopFrame.Web.Admin.Attributes.Members; [AttributeUsage(AttributeTargets.Property)] -public class AdminBoldAttribute : Attribute; +public sealed class AdminBoldAttribute : Attribute; diff --git a/src/HopFrame.Web.Admin/Attributes/Members/AdminHideValueAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Members/AdminHideValueAttribute.cs index c40288d..deb8092 100644 --- a/src/HopFrame.Web.Admin/Attributes/Members/AdminHideValueAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Members/AdminHideValueAttribute.cs @@ -1,4 +1,4 @@ namespace HopFrame.Web.Admin.Attributes.Members; [AttributeUsage(AttributeTargets.Property)] -public class AdminHideValueAttribute : Attribute; +public sealed class AdminHideValueAttribute : Attribute; diff --git a/src/HopFrame.Web.Admin/Attributes/Members/AdminIgnoreAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Members/AdminIgnoreAttribute.cs index 6022cf3..7b33e04 100644 --- a/src/HopFrame.Web.Admin/Attributes/Members/AdminIgnoreAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Members/AdminIgnoreAttribute.cs @@ -1,6 +1,6 @@ namespace HopFrame.Web.Admin.Attributes.Members; [AttributeUsage(AttributeTargets.Property)] -public class AdminIgnoreAttribute(bool onlyForListing = false) : Attribute { +public sealed class AdminIgnoreAttribute(bool onlyForListing = false) : Attribute { public bool OnlyForListing { get; set; } = onlyForListing; } diff --git a/src/HopFrame.Web.Admin/Attributes/Members/AdminPrefixAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Members/AdminPrefixAttribute.cs new file mode 100644 index 0000000..a5247db --- /dev/null +++ b/src/HopFrame.Web.Admin/Attributes/Members/AdminPrefixAttribute.cs @@ -0,0 +1,6 @@ +namespace HopFrame.Web.Admin.Attributes.Members; + +[AttributeUsage(AttributeTargets.Property)] +public sealed class AdminPrefixAttribute(string prefix) : Attribute { + public string Prefix { get; set; } = prefix; +} \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Attributes/Members/AdminUneditableAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Members/AdminUneditableAttribute.cs index f29e575..78eb491 100644 --- a/src/HopFrame.Web.Admin/Attributes/Members/AdminUneditableAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Members/AdminUneditableAttribute.cs @@ -1,4 +1,4 @@ namespace HopFrame.Web.Admin.Attributes.Members; [AttributeUsage(AttributeTargets.Property)] -public class AdminUneditableAttribute : Attribute; +public sealed class AdminUneditableAttribute : Attribute; diff --git a/src/HopFrame.Web.Admin/Attributes/Members/AdminUnsortableAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Members/AdminUnsortableAttribute.cs index 6ddb865..37935b2 100644 --- a/src/HopFrame.Web.Admin/Attributes/Members/AdminUnsortableAttribute.cs +++ b/src/HopFrame.Web.Admin/Attributes/Members/AdminUnsortableAttribute.cs @@ -1,4 +1,4 @@ namespace HopFrame.Web.Admin.Attributes.Members; [AttributeUsage(AttributeTargets.Property)] -public class AdminUnsortableAttribute : Attribute; +public sealed class AdminUnsortableAttribute : Attribute; diff --git a/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs b/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs index d6b644d..45802bb 100644 --- a/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/IAdminPropertyGenerator.cs @@ -7,8 +7,10 @@ public interface IAdminPropertyGenerator { IAdminPropertyGenerator DisplayValueWhileEditing(bool display); IAdminPropertyGenerator DisplayInListing(bool display = true); IAdminPropertyGenerator Bold(bool isBold = true); + IAdminPropertyGenerator Ignore(bool ignore = true); IAdminPropertyGenerator DisplayName(string displayName); IAdminPropertyGenerator Description(string description); + IAdminPropertyGenerator Prefix(string prefix); } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs b/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs index 314c490..26ab887 100644 --- a/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs @@ -2,6 +2,7 @@ using System.Reflection; using HopFrame.Web.Admin.Attributes; using HopFrame.Web.Admin.Attributes.Classes; using HopFrame.Web.Admin.Models; +using HopFrame.Web.Admin.Providers; namespace HopFrame.Web.Admin.Generators.Implementation; @@ -40,7 +41,7 @@ internal class AdminContextGenerator : IAdminContextGenerator { foreach (var property in properties) { var propertyType = property.PropertyType.GenericTypeArguments[0]; var pageGeneratorType = typeof(AdminPageGenerator<>).MakeGenericType(propertyType); - var generatorInstance = Activator.CreateInstance(pageGeneratorType, [propertyType.Name]); + var generatorInstance = Activator.CreateInstance(pageGeneratorType, [property.Name]); // Calls constructor with title attribute var populatorMethod = typeof(AdminContextGenerator) .GetMethod(nameof(ApplyConfigurationFromAttributes))? @@ -88,4 +89,15 @@ internal class AdminContextGenerator : IAdminContextGenerator { } } + public static void RegisterPages(AdminPagesContext context, IAdminPagesProvider provider) { + var properties = context.GetType().GetProperties(); + + foreach (var property in properties) { + var page = property.GetValue(context) as AdminPage; + if (page is null) continue; + + provider.RegisterAdminPage(page.Title.ToLower(), page); + } + } + } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs index a2219ce..b114e34 100644 --- a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs @@ -24,9 +24,6 @@ internal sealed class AdminPageGenerator : IAdminPageGenerator, foreach (var property in properties) { var attributes = property.GetCustomAttributes(false); - var ignoreProperty = attributes - .SingleOrDefault(a => a is AdminIgnoreAttribute) as AdminIgnoreAttribute; - if (ignoreProperty?.OnlyForListing == false) continue; var generator = Activator.CreateInstance(typeof(AdminPropertyGenerator), [property.Name, property.PropertyType]) as AdminPropertyGenerator; @@ -139,8 +136,12 @@ internal sealed class AdminPageGenerator : IAdminPageGenerator, if (attributes.Any(a => a is AdminBoldAttribute)) generator.Bold(); - if (attributes.Any(a => a is AdminIgnoreAttribute)) + if (attributes.Any(a => a is AdminIgnoreAttribute)) { + var attribute = attributes.Single(a => a is AdminIgnoreAttribute) as AdminIgnoreAttribute; generator.DisplayInListing(false); + generator.Sortable(false); + generator.Ignore(attribute?.OnlyForListing == false); + } if (attributes.Any(a => a is AdminHideValueAttribute)) generator.DisplayValueWhileEditing(false); @@ -154,6 +155,11 @@ internal sealed class AdminPageGenerator : IAdminPageGenerator, var attribute = attributes.Single(a => a is AdminDescriptionAttribute) as AdminDescriptionAttribute; generator.Description(attribute?.Description); } + + if (attributes.Any(a => a is AdminPrefixAttribute)) { + var attribute = attributes.Single(a => a is AdminPrefixAttribute) as AdminPrefixAttribute; + generator.Prefix(attribute?.Prefix); + } } private static PropertyInfo GetPropertyInfo(Expression> propertyLambda) { diff --git a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs index f37cd80..cab1b2d 100644 --- a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPropertyGenerator.cs @@ -26,6 +26,7 @@ internal sealed class AdminPropertyGenerator(string name, Type type) : IAdminPro public IAdminPropertyGenerator DisplayInListing(bool display = true) { _property.DisplayInListing = display; + _property.Sortable = false; return this; } @@ -34,6 +35,11 @@ internal sealed class AdminPropertyGenerator(string name, Type type) : IAdminPro return this; } + public IAdminPropertyGenerator Ignore(bool ignore = false) { + _property.Ignore = ignore; + return this; + } + public IAdminPropertyGenerator DisplayName(string displayName) { _property.DisplayName = displayName; return this; @@ -44,6 +50,11 @@ internal sealed class AdminPropertyGenerator(string name, Type type) : IAdminPro return this; } + public IAdminPropertyGenerator Prefix(string prefix) { + _property.Prefix = prefix; + return this; + } + public AdminPageProperty Compile() { _property.DisplayName ??= _property.Name; diff --git a/src/HopFrame.Web.Admin/Models/AdminPage.cs b/src/HopFrame.Web.Admin/Models/AdminPage.cs index bea528f..5878e6f 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPage.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPage.cs @@ -3,11 +3,14 @@ using System.Text.Json.Serialization; namespace HopFrame.Web.Admin.Models; -public class AdminPage : IAdminPageEntry { +public sealed class AdminPage : AdminPage; + +public class AdminPage { public string Title { get; set; } public string Description { get; set; } public AdminPagePermissions Permissions { get; set; } public IList Properties { get; set; } + [JsonIgnore] public Type RepositoryProvider { get; set; } @@ -18,5 +21,3 @@ public class AdminPage : IAdminPageEntry { public bool ShowDeleteButton { get; set; } = true; public bool ShowUpdateButton { get; set; } = true; } - -public interface IAdminPageEntry; diff --git a/src/HopFrame.Web.Admin/Models/AdminPagePermissions.cs b/src/HopFrame.Web.Admin/Models/AdminPagePermissions.cs index fc99101..e9629a6 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPagePermissions.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPagePermissions.cs @@ -1,6 +1,6 @@ namespace HopFrame.Web.Admin.Models; -public class AdminPagePermissions { +public sealed class AdminPagePermissions { public string View { get; set; } public string Create { get; set; } public string Update { get; set; } diff --git a/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs b/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs index 5444fae..daaab90 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs @@ -2,16 +2,18 @@ using System.Text.Json.Serialization; namespace HopFrame.Web.Admin.Models; -public class AdminPageProperty { +public sealed class AdminPageProperty { public string Name { get; set; } public string DisplayName { get; set; } public string Description { get; set; } + public string Prefix { get; set; } public bool DisplayInListing { get; set; } = true; public bool Sortable { get; set; } = true; public bool Editable { get; set; } = true; public bool EditDisplayValue { get; set; } = true; public bool Bold { get; set; } + public bool Ignore { get; set; } [JsonIgnore] public Type Type { get; set; } } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Providers/IAdminPagesProvider.cs b/src/HopFrame.Web.Admin/Providers/IAdminPagesProvider.cs new file mode 100644 index 0000000..d20c66c --- /dev/null +++ b/src/HopFrame.Web.Admin/Providers/IAdminPagesProvider.cs @@ -0,0 +1,11 @@ +using HopFrame.Web.Admin.Models; + +namespace HopFrame.Web.Admin.Providers; + +public interface IAdminPagesProvider { + + internal void RegisterAdminPage(string url, AdminPage page); + AdminPage LoadAdminPage(string url); + IList LoadRegisteredAdminPages(); + +} \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Providers/Implementation/AdminPagesProvider.cs b/src/HopFrame.Web.Admin/Providers/Implementation/AdminPagesProvider.cs new file mode 100644 index 0000000..d68a5ae --- /dev/null +++ b/src/HopFrame.Web.Admin/Providers/Implementation/AdminPagesProvider.cs @@ -0,0 +1,19 @@ +using HopFrame.Web.Admin.Models; + +namespace HopFrame.Web.Admin.Providers.Implementation; + +public class AdminPagesProvider : IAdminPagesProvider { + private readonly IDictionary _pages = new Dictionary(); + + public void RegisterAdminPage(string url, AdminPage page) { + _pages.Add(url, page); + } + + public AdminPage LoadAdminPage(string url) { + return _pages.TryGetValue(url, out var page) ? page : null; + } + + public IList LoadRegisteredAdminPages() { + return _pages.Values.ToList(); + } +} \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/ServiceCollectionExtensions.cs b/src/HopFrame.Web.Admin/ServiceCollectionExtensions.cs index 4b3c007..b8ee37e 100644 --- a/src/HopFrame.Web.Admin/ServiceCollectionExtensions.cs +++ b/src/HopFrame.Web.Admin/ServiceCollectionExtensions.cs @@ -1,17 +1,29 @@ using HopFrame.Web.Admin.Generators.Implementation; +using HopFrame.Web.Admin.Providers; +using HopFrame.Web.Admin.Providers.Implementation; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace HopFrame.Web.Admin; public static class ServiceCollectionExtensions { + private static IAdminPagesProvider _provider; + public static IServiceCollection AddAdminContext(this IServiceCollection services) where TContext : AdminPagesContext { - services.AddSingleton(_ => { - var generator = new AdminContextGenerator(); - return generator.CompileContext(); - }); + var provider = GetProvider(); + services.TryAddSingleton(provider); + + var generator = new AdminContextGenerator(); + var context = generator.CompileContext(); + AdminContextGenerator.RegisterPages(context, provider); + services.AddSingleton(context); return services; } + + private static IAdminPagesProvider GetProvider() { + return _provider ??= new AdminPagesProvider(); + } } \ No newline at end of file diff --git a/src/HopFrame.Web/HopAdminContext.cs b/src/HopFrame.Web/HopAdminContext.cs new file mode 100644 index 0000000..3a5c067 --- /dev/null +++ b/src/HopFrame.Web/HopAdminContext.cs @@ -0,0 +1,55 @@ +using HopFrame.Database.Models; +using HopFrame.Security; +using HopFrame.Web.Admin; +using HopFrame.Web.Admin.Generators; +using HopFrame.Web.Admin.Models; + +namespace HopFrame.Web; + +public class HopAdminContext : AdminPagesContext { + + public AdminPage Users { get; set; } + public AdminPage Groups { get; set; } + + public override void OnModelCreating(IAdminContextGenerator generator) { + generator.Page() + .Description("On this page you can manage all user accounts.") + .ViewPermission(AdminPermissions.ViewUsers) + .CreatePermission(AdminPermissions.AddUser) + .UpdatePermission(AdminPermissions.EditUser) + .DeletePermission(AdminPermissions.DeleteUser); + + generator.Page().Property(u => u.Password) + .DisplayInListing(false) + .DisplayValueWhileEditing(false); + + generator.Page().Property(u => u.CreatedAt) + .Editable(false); + + generator.Page().Property(u => u.Permissions) + .DisplayInListing(false); + + generator.Page().Property(u => u.Tokens) + .Ignore(); + + + generator.Page() + .Description("On this page you can view, create, edit and delete permission groups.") + .ViewPermission(AdminPermissions.ViewGroups) + .CreatePermission(AdminPermissions.AddGroup) + .UpdatePermission(AdminPermissions.EditGroup) + .DeletePermission(AdminPermissions.DeleteGroup); + + generator.Page().Property(g => g.Name) + .Prefix("group."); + + generator.Page().Property(g => g.IsDefaultGroup) + .Sortable(false); + + generator.Page().Property(g => g.CreatedAt) + .Editable(false); + + generator.Page().Property(g => g.Permissions) + .DisplayInListing(false); + } +} \ No newline at end of file diff --git a/src/HopFrame.Web/ServiceCollectionExtensions.cs b/src/HopFrame.Web/ServiceCollectionExtensions.cs index a9ab84e..548e2e9 100644 --- a/src/HopFrame.Web/ServiceCollectionExtensions.cs +++ b/src/HopFrame.Web/ServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ using BlazorStrap; using CurrieTechnologies.Razor.SweetAlert2; using HopFrame.Database; using HopFrame.Security.Authentication; +using HopFrame.Web.Admin; using HopFrame.Web.Services; using HopFrame.Web.Services.Implementation; using Microsoft.AspNetCore.Builder; @@ -15,6 +16,7 @@ public static class ServiceCollectionExtensions { services.AddHopFrameRepositories(); services.AddScoped(); services.AddTransient(); + services.AddAdminContext(); // Component library's services.AddSweetAlert2(); diff --git a/test/FrontendTest/Components/Pages/Counter.razor b/test/FrontendTest/Components/Pages/Counter.razor index 4fdbec5..4ac3989 100644 --- a/test/FrontendTest/Components/Pages/Counter.razor +++ b/test/FrontendTest/Components/Pages/Counter.razor @@ -1,4 +1,7 @@ @page "/counter" +@using System.Text.Json +@using HopFrame.Web +@using HopFrame.Web.Admin.Providers @rendermode InteractiveServer Counter @@ -9,12 +12,20 @@ +@inject IAdminPagesProvider Provider + @code { private int currentCount = 0; private string[] permissions = ["web.counter"]; private void IncrementCount() { currentCount++; + + string json = JsonSerializer.Serialize(Provider.LoadRegisteredAdminPages(), new JsonSerializerOptions { + WriteIndented = true + }); + + Console.WriteLine(json); } } \ No newline at end of file diff --git a/test/RestApiTest/AdminContext.cs b/test/RestApiTest/AdminContext.cs deleted file mode 100644 index 00bf00e..0000000 --- a/test/RestApiTest/AdminContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.ComponentModel; -using HopFrame.Database.Models; -using HopFrame.Web.Admin; -using HopFrame.Web.Admin.Generators; -using HopFrame.Web.Admin.Models; - -namespace RestApiTest; - -public class AdminContext : AdminPagesContext { - - public AdminPage Users { get; set; } - public AdminPage Groups { get; set; } - - public override void OnModelCreating(IAdminContextGenerator generator) { - - /*generator.Page() - .Title("Users") - .Description("On this page you can manage all user accounts.") - .UpdatePermission("update") - .ViewPermission("view") - .DeletePermission("delete") - .CreatePermission("create") - .DefaultSort(u => u.Id, ListSortDirection.Descending);*/ - - } -} \ No newline at end of file diff --git a/test/RestApiTest/Controllers/TestController.cs b/test/RestApiTest/Controllers/TestController.cs index 0d5a1f6..092784f 100644 --- a/test/RestApiTest/Controllers/TestController.cs +++ b/test/RestApiTest/Controllers/TestController.cs @@ -10,7 +10,7 @@ namespace RestApiTest.Controllers; [ApiController] [Route("test")] -public class TestController(ITokenContext userContext, DatabaseContext context, AdminContext adminContext) : ControllerBase { +public class TestController(ITokenContext userContext, DatabaseContext context) : ControllerBase { [HttpGet("permissions"), Authorized] public ActionResult> Permissions() { @@ -50,10 +50,5 @@ public class TestController(ITokenContext userContext, DatabaseContext context, public async Task>> GetAddresses() { return LogicResult>.Ok(await context.Addresses.Include(e => e.Employee).ToListAsync()); } - - [HttpGet("adminContext")] - public ActionResult GetAdminContext() { - return LogicResult.Ok(adminContext); - } } \ No newline at end of file diff --git a/test/RestApiTest/Program.cs b/test/RestApiTest/Program.cs index 632e62f..bfcbc38 100644 --- a/test/RestApiTest/Program.cs +++ b/test/RestApiTest/Program.cs @@ -1,6 +1,5 @@ using RestApiTest; using HopFrame.Api.Extensions; -using HopFrame.Web.Admin; using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); @@ -14,7 +13,6 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddDbContext(); -builder.Services.AddAdminContext(); builder.Services.AddSwaggerGen(c => { c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {