Made sidebar item collection extendable via interface. Refactored settings to system

This commit is contained in:
2025-12-27 23:54:48 +01:00
parent 05c05f1b72
commit ba942b2f8f
7 changed files with 91 additions and 56 deletions

View File

@@ -0,0 +1,49 @@
using LucideBlazor;
using Moonlight.Frontend.Interfaces;
using Moonlight.Frontend.Models;
namespace Moonlight.Frontend.Implementations;
public sealed class SidebarProvider : ISidebarProvider
{
public Task<SidebarItem[]> GetItemsAsync()
{
return Task.FromResult<SidebarItem[]>([
new()
{
Name = "Overview",
IconType = typeof(LayoutDashboardIcon),
Path = "/",
IsExactPath = true,
Order = 0
},
new()
{
Name = "Overview",
IconType = typeof(LayoutDashboardIcon),
Path = "/admin",
IsExactPath = true,
Group = "Admin",
Order = 0
},
new()
{
Name = "Users",
IconType = typeof(UsersRoundIcon),
Path = "/users",
IsExactPath = false,
Group = "Admin",
Order = 10
},
new()
{
Name = "System",
IconType = typeof(SettingsIcon),
Path = "/admin/system",
IsExactPath = false,
Group = "Admin",
Order = 20
}
]);
}
}

View File

@@ -0,0 +1,8 @@
using Moonlight.Frontend.Models;
namespace Moonlight.Frontend.Interfaces;
public interface ISidebarProvider
{
public Task<SidebarItem[]> GetItemsAsync();
}

View File

@@ -0,0 +1,17 @@
using System.Diagnostics.CodeAnalysis;
namespace Moonlight.Frontend.Models;
public record SidebarItem
{
public string Name { get; init; }
public string Path { get; init; }
public bool IsExactPath { get; init; }
public string? Group { get; init; }
public int Order { get; init; }
// Used to prevent the IL-Trimming from removing this type as its dynamically assigned a type and we
// need it to work properly
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public Type IconType { get; init; }
}

View File

@@ -1,6 +1,8 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Moonlight.Frontend.Implementations;
using Moonlight.Frontend.Interfaces;
using Moonlight.Frontend.UI;
using ShadcnBlazor;
using ShadcnBlazor.Extras;
@@ -18,5 +20,7 @@ public partial class Startup
builder.Services.AddShadcnBlazor();
builder.Services.AddShadcnBlazorExtras();
builder.Services.AddSingleton<ISidebarProvider, SidebarProvider>();
}
}

View File

@@ -1,4 +1,4 @@
@page "/admin/settings"
@page "/admin/system"
@using LucideBlazor
@using ShadcnBlazor.Buttons
@using ShadcnBlazor.Cards
@@ -12,10 +12,6 @@
<PaintRollerIcon />
Customization
</TabsTrigger>
<TabsTrigger Value="authentication">
<ScanFaceIcon />
Authentication
</TabsTrigger>
<TabsTrigger Value="api">
<KeyIcon />
API & API Keys

View File

@@ -1,8 +1,9 @@
@using System.Diagnostics.CodeAnalysis
@using LucideBlazor
@using Moonlight.Frontend.Interfaces
@using Moonlight.Frontend.Models
@using ShadcnBlazor.Sidebars
@inject NavigationManager Navigation
@inject IEnumerable<ISidebarProvider> Providers
@implements IDisposable
@@ -37,7 +38,7 @@
<SidebarGroupContent>
<SidebarMenu>
@foreach (var item in group)
@foreach (var item in group.OrderBy(x => x.Order))
{
var isActive = item.IsExactPath
? item.Path == url.LocalPath
@@ -69,41 +70,14 @@
{
private readonly List<SidebarItem> Items = new();
protected override void OnInitialized()
protected override async Task OnInitializedAsync()
{
Items.AddRange([
new()
{
Name = "Overview",
IconType = typeof(LayoutDashboardIcon),
Path = "/",
IsExactPath = true
},
new()
{
Name = "Overview",
IconType = typeof(LayoutDashboardIcon),
Path = "/admin",
IsExactPath = true,
Group = "Admin"
},
new()
{
Name = "Users",
IconType = typeof(UsersRoundIcon),
Path = "/users",
IsExactPath = false,
Group = "Admin"
},
new()
{
Name = "Settings",
IconType = typeof(SettingsIcon),
Path = "/admin/settings",
IsExactPath = false,
Group = "Admin"
}
]);
foreach (var provider in Providers)
{
Items.AddRange(
await provider.GetItemsAsync()
);
}
Navigation.LocationChanged += OnLocationChanged;
}
@@ -120,19 +94,6 @@
}
}
private record SidebarItem
{
public string Name { get; set; }
public string Path { get; set; }
public bool IsExactPath { get; set; }
public string? Group { get; set; }
// Used to prevent the IL-Trimming from removing this type as its dynamically assigned a type and we
// need it to work properly
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public Type IconType { get; set; }
}
public void Dispose()
{
Navigation.LocationChanged -= OnLocationChanged;