improved admin page
Added the logic for a more modular admin page, where every feature can add cards and components with just a call of a function
This commit is contained in:
parent
45e81c98bf
commit
3270039a6a
7 changed files with 155 additions and 55 deletions
|
@ -15,6 +15,7 @@ using Moonlight.Core.Models.Abstractions.Feature;
|
||||||
using Moonlight.Core.Models.Enums;
|
using Moonlight.Core.Models.Enums;
|
||||||
using Moonlight.Core.Repositories;
|
using Moonlight.Core.Repositories;
|
||||||
using Moonlight.Core.Services;
|
using Moonlight.Core.Services;
|
||||||
|
using Moonlight.Core.UI.Components.Cards;
|
||||||
|
|
||||||
namespace Moonlight.Core;
|
namespace Moonlight.Core;
|
||||||
|
|
||||||
|
@ -207,6 +208,8 @@ public class CoreFeature : MoonlightFeature
|
||||||
context.AddSidebarItem("Users", "bxs-group", "/admin/users", needsExactMatch: false, isAdmin: true);
|
context.AddSidebarItem("Users", "bxs-group", "/admin/users", needsExactMatch: false, isAdmin: true);
|
||||||
context.AddSidebarItem("System", "bxs-component", "/admin/sys", needsExactMatch: false, isAdmin: true);
|
context.AddSidebarItem("System", "bxs-component", "/admin/sys", needsExactMatch: false, isAdmin: true);
|
||||||
|
|
||||||
|
context.AddAdminCard<AdminUserCard>(index: int.MinValue);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
Moonlight/Core/Models/Abstractions/Feature/AdminComponent.cs
Normal file
12
Moonlight/Core/Models/Abstractions/Feature/AdminComponent.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Models.Abstractions.Feature;
|
||||||
|
|
||||||
|
public class AdminComponent
|
||||||
|
{
|
||||||
|
public RenderFragment Component { get; set; }
|
||||||
|
|
||||||
|
public int Index { get; set; }
|
||||||
|
|
||||||
|
public int RequiredPermissionLevel { get; set; }
|
||||||
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
using System.Reflection;
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Moonlight.Core.UI.Components.Partials;
|
||||||
|
using IComponent = Microsoft.AspNetCore.Components.IComponent;
|
||||||
|
|
||||||
namespace Moonlight.Core.Models.Abstractions.Feature;
|
namespace Moonlight.Core.Models.Abstractions.Feature;
|
||||||
|
|
||||||
|
@ -6,6 +11,8 @@ public class UiInitContext
|
||||||
{
|
{
|
||||||
public List<SidebarItem> SidebarItems { get; set; } = new();
|
public List<SidebarItem> SidebarItems { get; set; } = new();
|
||||||
public List<Assembly> RouteAssemblies { get; set; } = new();
|
public List<Assembly> RouteAssemblies { get; set; } = new();
|
||||||
|
public List<AdminComponent> AdminPageComponents { get; set; } = new();
|
||||||
|
public List<AdminComponent> AdminPageCards { get; set; } = new();
|
||||||
|
|
||||||
public void EnablePages<T>()
|
public void EnablePages<T>()
|
||||||
{
|
{
|
||||||
|
@ -15,6 +22,38 @@ public class UiInitContext
|
||||||
RouteAssemblies.Add(assembly);
|
RouteAssemblies.Add(assembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddAdminComponent<T>(int index = 0, int requiredPermissionLevel = 0) where T : IComponent
|
||||||
|
{
|
||||||
|
AdminPageComponents.Add(
|
||||||
|
new AdminComponent()
|
||||||
|
{
|
||||||
|
Component = builder =>
|
||||||
|
{
|
||||||
|
builder.OpenComponent<T>(0);
|
||||||
|
builder.CloseComponent();
|
||||||
|
},
|
||||||
|
Index = index,
|
||||||
|
RequiredPermissionLevel = requiredPermissionLevel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAdminCard<T>(int index = 0, int requiredPermissionLevel = 0) where T : IComponent
|
||||||
|
{
|
||||||
|
AdminPageCards.Add(
|
||||||
|
new AdminComponent()
|
||||||
|
{
|
||||||
|
Component = builder =>
|
||||||
|
{
|
||||||
|
builder.OpenComponent<T>(0);
|
||||||
|
builder.CloseComponent();
|
||||||
|
},
|
||||||
|
Index = index,
|
||||||
|
RequiredPermissionLevel = requiredPermissionLevel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public void AddSidebarItem(string name, string icon, string target, bool isAdmin = false, bool needsExactMatch = false, int index = 0)
|
public void AddSidebarItem(string name, string icon, string target, bool isAdmin = false, bool needsExactMatch = false, int index = 0)
|
||||||
{
|
{
|
||||||
SidebarItems.Add(new SidebarItem()
|
SidebarItems.Add(new SidebarItem()
|
||||||
|
|
35
Moonlight/Core/UI/Components/Cards/AdminUserCard.razor
Normal file
35
Moonlight/Core/UI/Components/Cards/AdminUserCard.razor
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
@using MoonCore.Abstractions
|
||||||
|
@using Moonlight.Core.Database.Entities
|
||||||
|
|
||||||
|
@inject Repository<User> UserRepository
|
||||||
|
|
||||||
|
<a class="mt-4 card" href="/admin/servers">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center gx-0">
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="text-uppercase text-muted mb-2">
|
||||||
|
Users
|
||||||
|
</h6>
|
||||||
|
<span class="h2 mb-0">
|
||||||
|
@UserCount
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<span class="h2 text-muted mb-0">
|
||||||
|
<i class="text-primary bx bxs-group bx-lg"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
private int UserCount;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
UserCount = UserRepository.Get().Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,73 +1,46 @@
|
||||||
@page "/admin"
|
@page "/admin"
|
||||||
@using MoonCore.Abstractions
|
@using MoonCore.Abstractions
|
||||||
@using Moonlight.Core.Database.Entities
|
@using Moonlight.Core.Database.Entities
|
||||||
|
@using Moonlight.Core.Services
|
||||||
@using Moonlight.Features.Servers.Entities
|
@using Moonlight.Features.Servers.Entities
|
||||||
|
|
||||||
@inject Repository<Server> ServerRepository
|
@inject Repository<Server> ServerRepository
|
||||||
@inject Repository<User> UserRepository
|
|
||||||
|
@inject FeatureService FeatureService
|
||||||
|
@inject IdentityService IdentityService
|
||||||
|
|
||||||
@attribute [RequirePermission(999)]
|
@attribute [RequirePermission(999)]
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader Load="Load">
|
||||||
<div class="row">
|
<div class="row mb-4">
|
||||||
|
@foreach (var adminCard in FeatureService.UiContext.AdminPageCards.OrderBy(x => x.Index).ToArray())
|
||||||
|
{
|
||||||
|
if (IdentityService.CurrentUser.Permissions >= adminCard.RequiredPermissionLevel)
|
||||||
|
{
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
<a class="mt-4 card" href="/admin/servers">
|
@adminCard.Component
|
||||||
<div class="card-body">
|
|
||||||
<div class="row align-items-center gx-0">
|
|
||||||
<div class="col">
|
|
||||||
<h6 class="text-uppercase text-muted mb-2">
|
|
||||||
Users
|
|
||||||
</h6>
|
|
||||||
<span class="h2 mb-0">
|
|
||||||
@UserCount
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
}
|
||||||
<span class="h2 text-muted mb-0">
|
}
|
||||||
<i class="text-primary bx bxs-group bx-lg"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
|
||||||
<a class="mt-4 card" href="/admin/users">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row align-items-center gx-0">
|
|
||||||
<div class="col">
|
|
||||||
<h6 class="text-uppercase text-muted mb-2">
|
|
||||||
Servers
|
|
||||||
</h6>
|
|
||||||
<span class="h2 mb-0">
|
|
||||||
@ServerCount
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<span class="h2 text-muted mb-0">
|
|
||||||
<i class="text-primary bx bx-server bx-lg"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@foreach (var adminComponent in FeatureService.UiContext.AdminPageComponents.OrderBy(x => x.Index).ToArray())
|
||||||
|
{
|
||||||
|
if (IdentityService.CurrentUser.Permissions >= adminComponent.RequiredPermissionLevel)
|
||||||
|
{
|
||||||
|
<div class="mb-4">
|
||||||
|
@adminComponent
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
</LazyLoader>
|
</LazyLoader>
|
||||||
|
|
||||||
@* This is just the start of this admin page, there will still be added more during the developement process *@
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private int ServerCount;
|
|
||||||
private int UserCount;
|
|
||||||
|
|
||||||
private async Task Load(LazyLoader arg)
|
private async Task Load(LazyLoader arg)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await arg.SetText("Loading Information...");
|
||||||
{
|
|
||||||
arg.SetText("Loading Information...");
|
|
||||||
ServerCount = ServerRepository.Get().Count();
|
|
||||||
UserCount = UserRepository.Get().Count();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ using Moonlight.Features.Servers.Http.Middleware;
|
||||||
using Moonlight.Features.Servers.Implementations.Diagnose;
|
using Moonlight.Features.Servers.Implementations.Diagnose;
|
||||||
using Moonlight.Features.Servers.Models.Enums;
|
using Moonlight.Features.Servers.Models.Enums;
|
||||||
using Moonlight.Features.Servers.Services;
|
using Moonlight.Features.Servers.Services;
|
||||||
|
using Moonlight.Features.Servers.UI.Components.Cards;
|
||||||
|
|
||||||
namespace Moonlight.Features.Servers;
|
namespace Moonlight.Features.Servers;
|
||||||
|
|
||||||
|
@ -104,6 +105,8 @@ public class ServersFeature : MoonlightFeature
|
||||||
context.AddSidebarItem("Servers", "bx-server", "/servers", isAdmin: false, needsExactMatch: false);
|
context.AddSidebarItem("Servers", "bx-server", "/servers", isAdmin: false, needsExactMatch: false);
|
||||||
context.AddSidebarItem("Servers", "bx-server", "/admin/servers", isAdmin: true, needsExactMatch: false);
|
context.AddSidebarItem("Servers", "bx-server", "/admin/servers", isAdmin: true, needsExactMatch: false);
|
||||||
|
|
||||||
|
context.AddAdminCard<AdminServersCard>();
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
@using MoonCore.Abstractions
|
||||||
|
@using Moonlight.Features.Servers.Entities
|
||||||
|
|
||||||
|
@inject Repository<Server> ServerRepository
|
||||||
|
|
||||||
|
<a class="mt-4 card" href="/admin/users">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center gx-0">
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="text-uppercase text-muted mb-2">
|
||||||
|
Servers
|
||||||
|
</h6>
|
||||||
|
<span class="h2 mb-0">
|
||||||
|
@ServerCount
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<span class="h2 text-muted mb-0">
|
||||||
|
<i class="text-primary bx bx-server bx-lg"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
private int ServerCount;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
ServerCount = ServerRepository.Get().Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue