Merge pull request #417 from Moonlight-Panel/v2_ImproveModularUI
Made user dashboard modular and extendable via plugins
This commit is contained in:
commit
257af8106d
17 changed files with 190 additions and 107 deletions
|
@ -8,9 +8,12 @@ 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.Implementations.UI.Admin.AdminColumns;
|
||||||
|
using Moonlight.Core.Implementations.UI.Index;
|
||||||
using Moonlight.Core.Interfaces;
|
using Moonlight.Core.Interfaces;
|
||||||
|
using Moonlight.Core.Interfaces.Ui.Admin;
|
||||||
|
using Moonlight.Core.Interfaces.UI.User;
|
||||||
using Moonlight.Core.Models;
|
using Moonlight.Core.Models;
|
||||||
using Moonlight.Core.Models.Abstractions;
|
using Moonlight.Core.Models.Abstractions;
|
||||||
using Moonlight.Core.Models.Abstractions.Feature;
|
using Moonlight.Core.Models.Abstractions.Feature;
|
||||||
|
@ -160,8 +163,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
|
// UI
|
||||||
await pluginService.RegisterImplementation<IAdminDashboardColumn>(new UserCount());
|
await pluginService.RegisterImplementation<IAdminDashboardColumn>(new UserCount());
|
||||||
|
await pluginService.RegisterImplementation<IUserDashboardComponent>(new GreetingMessages());
|
||||||
|
|
||||||
// Startup job services
|
// Startup job services
|
||||||
var startupJobService = app.Services.GetRequiredService<StartupJobService>();
|
var startupJobService = app.Services.GetRequiredService<StartupJobService>();
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
using MoonCoreUI.Helpers;
|
||||||
|
using Moonlight.Core.Interfaces.Ui.Admin;
|
||||||
|
using Moonlight.Core.Models.Abstractions;
|
||||||
|
using Moonlight.Core.UI.Components.Cards;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Implementations.UI.Admin.AdminColumns;
|
||||||
|
|
||||||
|
public class UserCount : IAdminDashboardColumn
|
||||||
|
{
|
||||||
|
public Task<UiComponent> Get()
|
||||||
|
{
|
||||||
|
var res = new UiComponent()
|
||||||
|
{
|
||||||
|
Component = ComponentHelper.FromType<AdminUserCard>(),
|
||||||
|
Index = int.MinValue
|
||||||
|
};
|
||||||
|
|
||||||
|
return Task.FromResult(res);
|
||||||
|
}
|
||||||
|
}
|
20
Moonlight/Core/Implementations/UI/Index/GreetingMessages.cs
Normal file
20
Moonlight/Core/Implementations/UI/Index/GreetingMessages.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using MoonCoreUI.Helpers;
|
||||||
|
using Moonlight.Core.Interfaces.UI.User;
|
||||||
|
using Moonlight.Core.Models.Abstractions;
|
||||||
|
using Moonlight.Core.UI.Components.Cards;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Implementations.UI.Index;
|
||||||
|
|
||||||
|
public class GreetingMessages : IUserDashboardComponent
|
||||||
|
{
|
||||||
|
public Task<UiComponent> Get()
|
||||||
|
{
|
||||||
|
var res = new UiComponent()
|
||||||
|
{
|
||||||
|
Component = ComponentHelper.FromType<TimeBasedGreetingMessages>(),
|
||||||
|
Index = int.MinValue
|
||||||
|
};
|
||||||
|
|
||||||
|
return Task.FromResult(res);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace Moonlight.Core.Interfaces;
|
|
||||||
|
|
||||||
public interface IAdminDashboardColumn
|
|
||||||
{
|
|
||||||
public Task<RenderFragment> Get();
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace Moonlight.Core.Interfaces;
|
|
||||||
|
|
||||||
public interface IAdminDashboardComponent
|
|
||||||
{
|
|
||||||
public Task<RenderFragment> Get();
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
using Moonlight.Core.Models.Abstractions;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Interfaces.Ui.Admin;
|
||||||
|
|
||||||
|
public interface IAdminDashboardColumn
|
||||||
|
{
|
||||||
|
public Task<UiComponent> Get();
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using Moonlight.Core.Models.Abstractions;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Interfaces.Ui.Admin;
|
||||||
|
|
||||||
|
public interface IAdminDashboardComponent
|
||||||
|
{
|
||||||
|
public Task<UiComponent> Get();
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using Moonlight.Core.Models.Abstractions;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Interfaces.UI.User;
|
||||||
|
|
||||||
|
public interface IUserDashboardComponent
|
||||||
|
{
|
||||||
|
public Task<UiComponent> Get();
|
||||||
|
}
|
10
Moonlight/Core/Models/Abstractions/UiComponent.cs
Normal file
10
Moonlight/Core/Models/Abstractions/UiComponent.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Moonlight.Core.Models.Abstractions;
|
||||||
|
|
||||||
|
public class UiComponent
|
||||||
|
{
|
||||||
|
public required RenderFragment Component { get; set; }
|
||||||
|
|
||||||
|
public int Index { get; set; } = 0;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
@using MoonCore.Services
|
||||||
|
@using Moonlight.Core.Configuration
|
||||||
|
@using Moonlight.Core.Services
|
||||||
|
|
||||||
|
@inject IdentityService IdentityService
|
||||||
|
@inject ConfigService<CoreConfiguration> ConfigService
|
||||||
|
|
||||||
|
<div class="card card-body p-8">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fs-2 fw-semibold">
|
||||||
|
@{
|
||||||
|
var greeting = GetGreetingMessage();
|
||||||
|
}
|
||||||
|
@greeting.Item1
|
||||||
|
<span class="text-info">@IdentityService.CurrentUser.Username</span>
|
||||||
|
@greeting.Item2
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
// For explanation:
|
||||||
|
// The first value is the actual message
|
||||||
|
// end second value is for question marks and so on
|
||||||
|
//
|
||||||
|
// and yes, this "feature" is kinda useless but still i wanted to implement
|
||||||
|
// it. - Masu
|
||||||
|
private (string, string) GetGreetingMessage()
|
||||||
|
{
|
||||||
|
var config = ConfigService.Get().Customisation;
|
||||||
|
|
||||||
|
if (config.DisableTimeBasedGreetingMessages)
|
||||||
|
return ("Welcome back, ", "");
|
||||||
|
|
||||||
|
var time = DateTime.UtcNow.AddHours(config.GreetingTimezoneDifference);
|
||||||
|
|
||||||
|
if (time.Hour >= 23 || time.Hour < 5)
|
||||||
|
return ("\ud83d\ude34 Still awake, ", "?");
|
||||||
|
|
||||||
|
if (time.Hour >= 5 && time.Hour < 10)
|
||||||
|
return ("\ud83d\ude04 Good morning, ", "");
|
||||||
|
|
||||||
|
if (time.Hour >= 10 && time.Hour < 14)
|
||||||
|
return ("\u2600\ufe0f Have a nice day, ", "");
|
||||||
|
|
||||||
|
if (time.Hour >= 14 && time.Hour < 16)
|
||||||
|
return ("\ud83d\ude03 Good afternoon, ", "");
|
||||||
|
|
||||||
|
if (time.Hour >= 16 && time.Hour < 22)
|
||||||
|
return ("\ud83c\udf25\ufe0f Have a nice evening, ", "");
|
||||||
|
|
||||||
|
if (time.Hour >= 22 && time.Hour < 23)
|
||||||
|
return ("\ud83c\udf19 Sleep well, ", "");
|
||||||
|
|
||||||
|
return ("Welcome back ", "");
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
@using MoonCore.Abstractions
|
@using MoonCore.Abstractions
|
||||||
@using Moonlight.Core.Database.Entities
|
@using Moonlight.Core.Database.Entities
|
||||||
@using Moonlight.Core.Interfaces
|
@using Moonlight.Core.Interfaces
|
||||||
|
@using Moonlight.Core.Interfaces.Ui.Admin
|
||||||
|
@using Moonlight.Core.Models.Abstractions
|
||||||
@using Moonlight.Core.Services
|
@using Moonlight.Core.Services
|
||||||
@using Moonlight.Features.Servers.Entities
|
@using Moonlight.Features.Servers.Entities
|
||||||
|
|
||||||
|
@ -11,17 +13,17 @@
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader Load="Load">
|
||||||
<div class="row mb-8">
|
<div class="row mb-8">
|
||||||
@foreach(var column in Columns)
|
@foreach(var column in Columns.OrderBy(x => x.Index))
|
||||||
{
|
{
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
@column
|
@column.Component
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@foreach (var component in Components)
|
@foreach (var component in Components.OrderBy(x => x.Index))
|
||||||
{
|
{
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
@component
|
@component.Component
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</LazyLoader>
|
</LazyLoader>
|
||||||
|
@ -29,8 +31,8 @@
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
private List<RenderFragment> Columns = new();
|
private List<UiComponent> Columns = new();
|
||||||
private List<RenderFragment> Components = new();
|
private List<UiComponent> Components = new();
|
||||||
|
|
||||||
private async Task Load(LazyLoader arg)
|
private async Task Load(LazyLoader arg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,60 +1,33 @@
|
||||||
@page "/"
|
@page "/"
|
||||||
|
@using Moonlight.Core.Interfaces.UI.User
|
||||||
|
@using Moonlight.Core.Models.Abstractions
|
||||||
@using Moonlight.Core.Services
|
@using Moonlight.Core.Services
|
||||||
@using MoonCore.Services
|
|
||||||
@using Moonlight.Core.Configuration
|
|
||||||
|
|
||||||
@inject IdentityService IdentityService
|
@inject PluginService PluginService
|
||||||
@inject ConfigService<CoreConfiguration> ConfigService
|
|
||||||
|
|
||||||
<div class="card card-body p-8">
|
<LazyLoader Load="Load">
|
||||||
<div class="d-flex align-items-center">
|
@foreach (var component in Components.OrderBy(x => x.Index))
|
||||||
<span class="fs-2 fw-semibold">
|
{
|
||||||
@{
|
<div class="mb-4">
|
||||||
var greeting = GetGreetingMessage();
|
@component.Component
|
||||||
}
|
</div>
|
||||||
@greeting.Item1
|
}
|
||||||
<span class="text-info">@IdentityService.CurrentUser.Username</span>
|
</LazyLoader>
|
||||||
@greeting.Item2
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
// For explanation:
|
private List<UiComponent> Components = new();
|
||||||
// The first value is the actual message
|
|
||||||
// end second value is for question marks and so on
|
|
||||||
//
|
private async Task Load(LazyLoader arg)
|
||||||
// and yes, this "feature" is kinda useless but still i wanted to implement
|
|
||||||
// it. - Masu
|
|
||||||
private (string, string) GetGreetingMessage()
|
|
||||||
{
|
{
|
||||||
var config = ConfigService.Get().Customisation;
|
await arg.SetText("Loading...");
|
||||||
|
|
||||||
if (config.DisableTimeBasedGreetingMessages)
|
var implementations = await PluginService.GetImplementations<IUserDashboardComponent>();
|
||||||
return ("Welcome back, ", "");
|
|
||||||
|
|
||||||
var time = DateTime.UtcNow.AddHours(config.GreetingTimezoneDifference);
|
foreach (var implementation in implementations)
|
||||||
|
{
|
||||||
if (time.Hour >= 23 || time.Hour < 5)
|
Components.Add(await implementation.Get());
|
||||||
return ("\ud83d\ude34 Still awake, ", "?");
|
}
|
||||||
|
|
||||||
if (time.Hour >= 5 && time.Hour < 10)
|
|
||||||
return ("\ud83d\ude04 Good morning, ", "");
|
|
||||||
|
|
||||||
if (time.Hour >= 10 && time.Hour < 14)
|
|
||||||
return ("\u2600\ufe0f Have a nice day, ", "");
|
|
||||||
|
|
||||||
if (time.Hour >= 14 && time.Hour < 16)
|
|
||||||
return ("\ud83d\ude03 Good afternoon, ", "");
|
|
||||||
|
|
||||||
if (time.Hour >= 16 && time.Hour < 22)
|
|
||||||
return ("\ud83c\udf25\ufe0f Have a nice evening, ", "");
|
|
||||||
|
|
||||||
if (time.Hour >= 22 && time.Hour < 23)
|
|
||||||
return ("\ud83c\udf19 Sleep well, ", "");
|
|
||||||
|
|
||||||
return ("Welcome back ", "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using MoonCoreUI.Helpers;
|
||||||
|
using Moonlight.Core.Interfaces.Ui.Admin;
|
||||||
|
using Moonlight.Core.Models.Abstractions;
|
||||||
|
using Moonlight.Features.Servers.UI.Components.Cards;
|
||||||
|
|
||||||
|
namespace Moonlight.Features.Servers.Implementations.UI.Admin.AdminColumns;
|
||||||
|
|
||||||
|
public class ServerCount : IAdminDashboardColumn
|
||||||
|
{
|
||||||
|
public Task<UiComponent> Get()
|
||||||
|
{
|
||||||
|
var res = new UiComponent()
|
||||||
|
{
|
||||||
|
Component = ComponentHelper.FromType<AdminServersCard>()
|
||||||
|
};
|
||||||
|
|
||||||
|
return Task.FromResult(res);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,13 +2,14 @@ using MoonCore.Helpers;
|
||||||
using MoonCore.Services;
|
using MoonCore.Services;
|
||||||
using Moonlight.Core.Configuration;
|
using Moonlight.Core.Configuration;
|
||||||
using Moonlight.Core.Interfaces;
|
using Moonlight.Core.Interfaces;
|
||||||
|
using Moonlight.Core.Interfaces.Ui.Admin;
|
||||||
using Moonlight.Core.Models.Abstractions.Feature;
|
using Moonlight.Core.Models.Abstractions.Feature;
|
||||||
using Moonlight.Core.Services;
|
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.Implementations.UI.Admin.AdminColumns;
|
||||||
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;
|
using Moonlight.Features.Servers.UI.Components.Cards;
|
||||||
|
|
|
@ -53,7 +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\Implementations\UI\Admin\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\" />
|
||||||
|
@ -75,6 +75,7 @@
|
||||||
<Folder Include="Features\FileManager\Http\Requests\" />
|
<Folder Include="Features\FileManager\Http\Requests\" />
|
||||||
<Folder Include="Features\FileManager\Http\Resources\" />
|
<Folder Include="Features\FileManager\Http\Resources\" />
|
||||||
<Folder Include="Features\Servers\Http\Resources\" />
|
<Folder Include="Features\Servers\Http\Resources\" />
|
||||||
|
<Folder Include="Features\Servers\Implementations\UI\Admin\" />
|
||||||
<Folder Include="storage\" />
|
<Folder Include="storage\" />
|
||||||
<Folder Include="Styles\" />
|
<Folder Include="Styles\" />
|
||||||
<Folder Include="wwwroot\css\" />
|
<Folder Include="wwwroot\css\" />
|
||||||
|
|
Loading…
Reference in a new issue