diff --git a/README.md b/README.md index b7ed1b7..7f1e8a4 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,14 @@ A simple backend management api for ASP.NET Core Web APIs - [x] Permission management - [x] Frontend dashboards +## 2.0 Todo list +- [x] 1.0 bug fixes +- [x] Code cleanup +- [x] Relations in database +- [ ] Generated Admin pages +- [ ] Pretty Login page for administration +- [ ] Clean documentation + # Usage There are two different versions of HopFrame, either the Web API version or the full Blazor web version. diff --git a/src/HopFrame.Web.Admin/Attributes/Classes/AdminUrlAttribute.cs b/src/HopFrame.Web.Admin/Attributes/Classes/AdminUrlAttribute.cs new file mode 100644 index 0000000..ab87a2e --- /dev/null +++ b/src/HopFrame.Web.Admin/Attributes/Classes/AdminUrlAttribute.cs @@ -0,0 +1,6 @@ +namespace HopFrame.Web.Admin.Attributes.Classes; + +[AttributeUsage(AttributeTargets.Class)] +public class AdminUrlAttribute(string url) : Attribute { + public string Url { get; set; } = url; +} \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs b/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs index c4f7c36..f9902fb 100644 --- a/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/IAdminPageGenerator.cs @@ -7,6 +7,7 @@ public interface IAdminPageGenerator { IAdminPageGenerator Title(string title); IAdminPageGenerator Description(string description); + IAdminPageGenerator Url(string url); IAdminPageGenerator ViewPermission(string permission); IAdminPageGenerator CreatePermission(string permission); diff --git a/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs b/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs index 26ab887..6596a2f 100644 --- a/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/Implementation/AdminContextGenerator.cs @@ -73,6 +73,11 @@ internal class AdminContextGenerator : IAdminContextGenerator { generator.Description(attribute?.Description); } + if (attributes.Any(a => a is AdminUrlAttribute)) { + var attribute = attributes.Single(a => a is AdminUrlAttribute) as AdminUrlAttribute; + generator.Url(attribute?.Url); + } + if (attributes.Any(a => a is AdminPermissionsAttribute)) { var attribute = attributes.Single(a => a is AdminPermissionsAttribute) as AdminPermissionsAttribute; generator.CreatePermission(attribute?.Permissions.Create); diff --git a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs index b114e34..bad320e 100644 --- a/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs +++ b/src/HopFrame.Web.Admin/Generators/Implementation/AdminPageGenerator.cs @@ -39,6 +39,7 @@ internal sealed class AdminPageGenerator : IAdminPageGenerator, public IAdminPageGenerator Title(string title) { _page.Title = title; + _page.Url ??= title.ToLower(); return this; } @@ -47,6 +48,11 @@ internal sealed class AdminPageGenerator : IAdminPageGenerator, return this; } + public IAdminPageGenerator Url(string url) { + _page.Url = url; + return this; + } + public IAdminPageGenerator ViewPermission(string permission) { _page.Permissions.View = permission; return this; diff --git a/src/HopFrame.Web.Admin/Models/AdminPage.cs b/src/HopFrame.Web.Admin/Models/AdminPage.cs index 5878e6f..241f69c 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPage.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPage.cs @@ -8,6 +8,7 @@ public sealed class AdminPage : AdminPage; public class AdminPage { public string Title { get; set; } public string Description { get; set; } + public string Url { get; set; } public AdminPagePermissions Permissions { get; set; } public IList Properties { get; set; } diff --git a/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor b/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor index e939548..9484d82 100644 --- a/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor +++ b/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor @@ -5,6 +5,7 @@ @using BlazorStrap @using HopFrame.Web.Pages.Administration.Layout @using BlazorStrap.V5 +@using HopFrame.Web.Admin.Providers @using HopFrame.Web.Components @using Microsoft.AspNetCore.Components.Web @layout AdminLayout @@ -13,15 +14,15 @@ - @foreach (var view in AdminMenu.Subpages) { - + @foreach (var adminPage in Pages.LoadRegisteredAdminPages()) { + - @view.Name - @view.Permission - @view.Description - Open + @adminPage.Title + @adminPage.Permissions.View + @adminPage.Description + Open @@ -31,3 +32,12 @@ @inject NavigationManager Navigator +@inject IAdminPagesProvider Pages + +@code { + + public void NavigateTo(string url) { + Navigator.NavigateTo("administration/" + url, true); + } + +} diff --git a/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor b/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor index a66f311..ae96859 100644 --- a/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor +++ b/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor @@ -3,10 +3,10 @@ @using BlazorStrap @using BlazorStrap.V5 @using HopFrame.Security.Claims +@using HopFrame.Web.Admin.Providers @using HopFrame.Web.Services @using static Microsoft.AspNetCore.Components.Web.RenderMode @using HopFrame.Web.Components.Administration -@using HopFrame.Web.Model @using HopFrame.Web.Components @@ -23,9 +23,9 @@ Dashboard - @foreach (var nav in Subpages) { - - @nav.Name + @foreach (var adminPage in Pages.LoadRegisteredAdminPages()) { + + @adminPage.Title } @@ -46,25 +46,11 @@ @inject NavigationManager Navigator @inject ITokenContext Context @inject IAuthService Auth +@inject IAdminPagesProvider Pages @code { - public static IList Subpages = new List { - new () { - Name = "Users", - Url = "administration/users", - Description = "On this page you can manage all user accounts.", - Permission = Security.AdminPermissions.ViewUsers - }, - new () { - Name = "Groups", - Url = "administration/groups", - Description = "On this page you can view, create, edit and delete permission groups.", - Permission = Security.AdminPermissions.ViewGroups - } - }; - private bool IsNavItemActive(string element) { - return Navigator.Uri.Contains(element); + return Navigator.Uri.TrimEnd('/').EndsWith(element); } private bool IsDashboardActive() { @@ -72,11 +58,11 @@ } private void NavigateToDashboard() { - Navigate("administration"); + Navigator.NavigateTo("administration", true); } private void Navigate(string url) { - Navigator.NavigateTo(url, true); + Navigator.NavigateTo("administration/" + url, true); } private void Logout() { diff --git a/test/FrontendTest/AdminContext.cs b/test/FrontendTest/AdminContext.cs new file mode 100644 index 0000000..016c488 --- /dev/null +++ b/test/FrontendTest/AdminContext.cs @@ -0,0 +1,12 @@ +using HopFrame.Web.Admin; +using HopFrame.Web.Admin.Models; +using RestApiTest.Models; + +namespace FrontendTest; + +public class AdminContext : AdminPagesContext { + + public AdminPage
Addresses { get; set; } + public AdminPage Employees { get; set; } + +} \ No newline at end of file diff --git a/test/FrontendTest/Models/Address.cs b/test/FrontendTest/Models/Address.cs new file mode 100644 index 0000000..386114d --- /dev/null +++ b/test/FrontendTest/Models/Address.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace RestApiTest.Models; + +public class Address { + [ForeignKey("Employee")] + public int AddressId { get; set; } + public string AddressDetails { get; set; } + public string City { get; set; } + public int ZipCode { get; set; } + public string State { get; set; } + public string Country { get; set; } + + [JsonIgnore] + public virtual Employee Employee { get; set; } +} \ No newline at end of file diff --git a/test/FrontendTest/Models/Employee.cs b/test/FrontendTest/Models/Employee.cs new file mode 100644 index 0000000..6f70edc --- /dev/null +++ b/test/FrontendTest/Models/Employee.cs @@ -0,0 +1,8 @@ +namespace RestApiTest.Models; + +public class Employee { + public int EmployeeId { get; set; } + public string Name { get; set; } + + public virtual Address Address { get; set; } +} \ No newline at end of file diff --git a/test/FrontendTest/Program.cs b/test/FrontendTest/Program.cs index 77989c6..7547722 100644 --- a/test/FrontendTest/Program.cs +++ b/test/FrontendTest/Program.cs @@ -7,6 +7,7 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(); builder.Services.AddHopFrame(); +builder.Services.AddAdminContext(); // Add services to the container. builder.Services.AddRazorComponents()