Final admin Page

Added Admin System To be as Modular as masu wants it to be
This commit is contained in:
Moritz 2024-05-18 22:11:58 +02:00
parent 7225db0bf1
commit 56184a8254
12 changed files with 90 additions and 114 deletions

View file

@ -7,6 +7,7 @@ using MoonCoreUI.Services;
using Moonlight.Core.Configuration;
using Moonlight.Core.Database;
using Moonlight.Core.Database.Entities;
using Moonlight.Core.Implementations.AdminColumns;
using Moonlight.Core.Implementations.Diagnose;
using Moonlight.Core.Interfaces;
using Moonlight.Core.Models;
@ -156,6 +157,9 @@ public class CoreFeature : MoonlightFeature
await pluginService.RegisterImplementation<IDiagnoseAction>(new FeatureDiagnoseAction());
await pluginService.RegisterImplementation<IDiagnoseAction>(new LogDiagnoseAction());
//Admin Page
await pluginService.RegisterImplementation<IAdminDashboardColumn>(new UserCount());
// Startup job services
var startupJobService = app.Services.GetRequiredService<StartupJobService>();
@ -208,13 +212,6 @@ public class CoreFeature : MoonlightFeature
context.AddSidebarItem("Users", "bxs-group", "/admin/users", needsExactMatch: false, isAdmin: true);
context.AddSidebarItem("System", "bxs-component", "/admin/sys", needsExactMatch: false, isAdmin: true);
// With this function, you can add an Admin Card to the Admin Page
// It references the Admin Card, which is a Razor component.
context.AddAdminCard<AdminUserCard>(index: int.MinValue);
// Same Thing could be used with the context.AddAdminComponent Function, which then renders the component
// under the cards, for fast informations
return Task.CompletedTask;
}

View file

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Components;
using MoonCoreUI.Helpers;
using Moonlight.Core.Interfaces;
using Moonlight.Core.UI.Components.Cards;
namespace Moonlight.Core.Implementations.AdminColumns;
public class UserCount : IAdminDashboardColumn
{
public Task<RenderFragment> Get()
{
var res = ComponentHelper.FromType<AdminUserCard>();
return Task.FromResult(res);
}
}

View file

@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Components;
namespace Moonlight.Core.Interfaces;
public interface IAdminDashboardColumn
{
public Task<RenderFragment> Get();
}

View file

@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Components;
namespace Moonlight.Core.Interfaces;
public interface IAdminDashboardComponent
{
public Task<RenderFragment> Get();
}

View file

@ -1,12 +0,0 @@
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; }
}

View file

@ -22,40 +22,6 @@ public class UiInitContext
RouteAssemblies.Add(assembly);
}
public void AddAdminComponent<T>(int index = 0, int requiredPermissionLevel = 0) where T : IComponent
{
// Loads the Component into a List of AdminComponents, with lots of more information for the Admin Page to render
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
{
// Loads the Card into a List of AdminComponents, with lots of more information for the Admin Page to render
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)
{
SidebarItems.Add(new SidebarItem()

View file

@ -3,24 +3,8 @@
@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 href="/admin/servers">
<StatCard Value="@UserCount.ToString()" Description="Users" Icon="bxs-group"></StatCard>
</a>
@code {

View file

@ -1,47 +1,54 @@
@page "/admin"
@using MoonCore.Abstractions
@using Moonlight.Core.Database.Entities
@using Moonlight.Core.Interfaces
@using Moonlight.Core.Services
@using Moonlight.Features.Servers.Entities
@inject Repository<Server> ServerRepository
@inject FeatureService FeatureService
@inject IdentityService IdentityService
@inject PluginService PluginService
@attribute [RequirePermission(999)]
<LazyLoader Load="Load">
<div class="row mb-4">
@foreach (var adminCard in FeatureService.UiContext.AdminPageCards.OrderBy(x => x.Index).ToArray())
<div class="row mb-8">
@foreach(var column in Columns)
{
// basically renders the component if the permissions of the viewed item is lower or equal
// to the users permission, -> better developer experience for feature devs
if (IdentityService.CurrentUser.Permissions >= adminCard.RequiredPermissionLevel)
{
<div class="col-12 col-lg-6 col-xl">
@adminCard.Component
</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 class="col-12 col-lg-6 col-xl">
@column
</div>
}
</div>
@foreach (var component in Components)
{
<div class="mb-4">
@component
</div>
}
</LazyLoader>
@code {
private List<RenderFragment> Columns = new();
private List<RenderFragment> Components = new();
private async Task Load(LazyLoader arg)
{
await arg.SetText("Loading Information...");
var componentImplementations = await PluginService.GetImplementations<IAdminDashboardComponent>();
foreach (var implementation in componentImplementations)
{
Components.Add(await implementation.Get());
}
var columnImplementations = await PluginService.GetImplementations<IAdminDashboardColumn>();
foreach (var implementation in columnImplementations)
{
Columns.Add(await implementation.Get());
}
}
}

View file

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Components;
using MoonCoreUI.Helpers;
using Moonlight.Core.Interfaces;
using Moonlight.Features.Servers.UI.Components.Cards;
namespace Moonlight.Features.Servers.Implementations.AdminColumns;
public class ServerCount : IAdminDashboardColumn
{
public Task<RenderFragment> Get()
{
var res = ComponentHelper.FromType<AdminServersCard>();
return Task.FromResult(res);
}
}

View file

@ -7,6 +7,7 @@ using Moonlight.Core.Services;
using Moonlight.Features.Servers.Actions;
using Moonlight.Features.Servers.Configuration;
using Moonlight.Features.Servers.Http.Middleware;
using Moonlight.Features.Servers.Implementations.AdminColumns;
using Moonlight.Features.Servers.Implementations.Diagnose;
using Moonlight.Features.Servers.Models.Enums;
using Moonlight.Features.Servers.Services;
@ -96,6 +97,8 @@ public class ServersFeature : MoonlightFeature
var pluginService = app.Services.GetRequiredService<PluginService>();
await pluginService.RegisterImplementation<IDiagnoseAction>(new NodesDiagnoseAction());
await pluginService.RegisterImplementation<IAdminDashboardColumn>(new ServerCount());
}
public override Task OnUiInitialized(UiInitContext context)
@ -105,8 +108,6 @@ public class ServersFeature : MoonlightFeature
context.AddSidebarItem("Servers", "bx-server", "/servers", isAdmin: false, needsExactMatch: false);
context.AddSidebarItem("Servers", "bx-server", "/admin/servers", isAdmin: true, needsExactMatch: false);
context.AddAdminCard<AdminServersCard>();
return Task.CompletedTask;
}
}

View file

@ -3,24 +3,8 @@
@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 href="/admin/servers">
<StatCard Value="@ServerCount.ToString()" Description="Servers" Icon="bxs-server"></StatCard>
</a>
@code {

View file

@ -53,6 +53,7 @@
<Folder Include="Core\Database\Migrations\" />
<Folder Include="Core\Http\Requests\" />
<Folder Include="Core\Http\Resources\" />
<Folder Include="Core\Implementations\AdminComponents\" />
<Folder Include="Core\UI\Components\Forms\" />
<Folder Include="Features\Dummy\Configuration\" />
<Folder Include="Features\Dummy\Entities\" />