Final admin Page
Added Admin System To be as Modular as masu wants it to be
This commit is contained in:
parent
7225db0bf1
commit
56184a8254
|
@ -7,6 +7,7 @@ using MoonCoreUI.Services;
|
||||||
using Moonlight.Core.Configuration;
|
using Moonlight.Core.Configuration;
|
||||||
using Moonlight.Core.Database;
|
using Moonlight.Core.Database;
|
||||||
using Moonlight.Core.Database.Entities;
|
using Moonlight.Core.Database.Entities;
|
||||||
|
using Moonlight.Core.Implementations.AdminColumns;
|
||||||
using Moonlight.Core.Implementations.Diagnose;
|
using Moonlight.Core.Implementations.Diagnose;
|
||||||
using Moonlight.Core.Interfaces;
|
using Moonlight.Core.Interfaces;
|
||||||
using Moonlight.Core.Models;
|
using Moonlight.Core.Models;
|
||||||
|
@ -156,6 +157,9 @@ public class CoreFeature : MoonlightFeature
|
||||||
await pluginService.RegisterImplementation<IDiagnoseAction>(new FeatureDiagnoseAction());
|
await pluginService.RegisterImplementation<IDiagnoseAction>(new FeatureDiagnoseAction());
|
||||||
await pluginService.RegisterImplementation<IDiagnoseAction>(new LogDiagnoseAction());
|
await pluginService.RegisterImplementation<IDiagnoseAction>(new LogDiagnoseAction());
|
||||||
|
|
||||||
|
//Admin Page
|
||||||
|
await pluginService.RegisterImplementation<IAdminDashboardColumn>(new UserCount());
|
||||||
|
|
||||||
// Startup job services
|
// Startup job services
|
||||||
var startupJobService = app.Services.GetRequiredService<StartupJobService>();
|
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("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);
|
||||||
|
|
||||||
// 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;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
Moonlight/Core/Implementations/AdminColumns/UserCount.cs
Normal file
16
Moonlight/Core/Implementations/AdminColumns/UserCount.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
8
Moonlight/Core/Interfaces/IAdminDashboardColumn.cs
Normal file
8
Moonlight/Core/Interfaces/IAdminDashboardColumn.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Interfaces;
|
||||||
|
|
||||||
|
public interface IAdminDashboardColumn
|
||||||
|
{
|
||||||
|
public Task<RenderFragment> Get();
|
||||||
|
}
|
8
Moonlight/Core/Interfaces/IAdminDashboardComponent.cs
Normal file
8
Moonlight/Core/Interfaces/IAdminDashboardComponent.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Interfaces;
|
||||||
|
|
||||||
|
public interface IAdminDashboardComponent
|
||||||
|
{
|
||||||
|
public Task<RenderFragment> Get();
|
||||||
|
}
|
|
@ -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; }
|
|
||||||
}
|
|
|
@ -22,40 +22,6 @@ public class UiInitContext
|
||||||
RouteAssemblies.Add(assembly);
|
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)
|
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()
|
||||||
|
|
|
@ -3,24 +3,8 @@
|
||||||
|
|
||||||
@inject Repository<User> UserRepository
|
@inject Repository<User> UserRepository
|
||||||
|
|
||||||
<a class="mt-4 card" href="/admin/servers">
|
<a href="/admin/servers">
|
||||||
<div class="card-body">
|
<StatCard Value="@UserCount.ToString()" Description="Users" Icon="bxs-group"></StatCard>
|
||||||
<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>
|
</a>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
|
@ -1,47 +1,54 @@
|
||||||
@page "/admin"
|
@page "/admin"
|
||||||
@using MoonCore.Abstractions
|
@using MoonCore.Abstractions
|
||||||
@using Moonlight.Core.Database.Entities
|
@using Moonlight.Core.Database.Entities
|
||||||
|
@using Moonlight.Core.Interfaces
|
||||||
@using Moonlight.Core.Services
|
@using Moonlight.Core.Services
|
||||||
@using Moonlight.Features.Servers.Entities
|
@using Moonlight.Features.Servers.Entities
|
||||||
|
|
||||||
@inject Repository<Server> ServerRepository
|
@inject PluginService PluginService
|
||||||
|
|
||||||
@inject FeatureService FeatureService
|
|
||||||
@inject IdentityService IdentityService
|
|
||||||
|
|
||||||
@attribute [RequirePermission(999)]
|
@attribute [RequirePermission(999)]
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader Load="Load">
|
||||||
<div class="row mb-4">
|
<div class="row mb-8">
|
||||||
@foreach (var adminCard in FeatureService.UiContext.AdminPageCards.OrderBy(x => x.Index).ToArray())
|
@foreach(var column in Columns)
|
||||||
{
|
{
|
||||||
// basically renders the component if the permissions of the viewed item is lower or equal
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
// to the users permission, -> better developer experience for feature devs
|
@column
|
||||||
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>
|
</div>
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
|
@foreach (var component in Components)
|
||||||
|
{
|
||||||
|
<div class="mb-4">
|
||||||
|
@component
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</LazyLoader>
|
</LazyLoader>
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
|
private List<RenderFragment> Columns = new();
|
||||||
|
private List<RenderFragment> Components = new();
|
||||||
|
|
||||||
private async Task Load(LazyLoader arg)
|
private async Task Load(LazyLoader arg)
|
||||||
{
|
{
|
||||||
await arg.SetText("Loading Information...");
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ using Moonlight.Core.Services;
|
||||||
using Moonlight.Features.Servers.Actions;
|
using Moonlight.Features.Servers.Actions;
|
||||||
using Moonlight.Features.Servers.Configuration;
|
using Moonlight.Features.Servers.Configuration;
|
||||||
using Moonlight.Features.Servers.Http.Middleware;
|
using Moonlight.Features.Servers.Http.Middleware;
|
||||||
|
using Moonlight.Features.Servers.Implementations.AdminColumns;
|
||||||
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;
|
||||||
|
@ -96,6 +97,8 @@ public class ServersFeature : MoonlightFeature
|
||||||
var pluginService = app.Services.GetRequiredService<PluginService>();
|
var pluginService = app.Services.GetRequiredService<PluginService>();
|
||||||
|
|
||||||
await pluginService.RegisterImplementation<IDiagnoseAction>(new NodesDiagnoseAction());
|
await pluginService.RegisterImplementation<IDiagnoseAction>(new NodesDiagnoseAction());
|
||||||
|
|
||||||
|
await pluginService.RegisterImplementation<IAdminDashboardColumn>(new ServerCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task OnUiInitialized(UiInitContext context)
|
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", "/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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,24 +3,8 @@
|
||||||
|
|
||||||
@inject Repository<Server> ServerRepository
|
@inject Repository<Server> ServerRepository
|
||||||
|
|
||||||
<a class="mt-4 card" href="/admin/users">
|
<a href="/admin/servers">
|
||||||
<div class="card-body">
|
<StatCard Value="@ServerCount.ToString()" Description="Servers" Icon="bxs-server"></StatCard>
|
||||||
<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>
|
</a>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
<Folder Include="Core\Database\Migrations\" />
|
<Folder Include="Core\Database\Migrations\" />
|
||||||
<Folder Include="Core\Http\Requests\" />
|
<Folder Include="Core\Http\Requests\" />
|
||||||
<Folder Include="Core\Http\Resources\" />
|
<Folder Include="Core\Http\Resources\" />
|
||||||
|
<Folder Include="Core\Implementations\AdminComponents\" />
|
||||||
<Folder Include="Core\UI\Components\Forms\" />
|
<Folder Include="Core\UI\Components\Forms\" />
|
||||||
<Folder Include="Features\Dummy\Configuration\" />
|
<Folder Include="Features\Dummy\Configuration\" />
|
||||||
<Folder Include="Features\Dummy\Entities\" />
|
<Folder Include="Features\Dummy\Entities\" />
|
||||||
|
|
Loading…
Reference in a new issue