Refactored project to module structure
This commit is contained in:
53
Moonlight.Frontend/Admin/Sys/Settings/Settings.razor
Normal file
53
Moonlight.Frontend/Admin/Sys/Settings/Settings.razor
Normal file
@@ -0,0 +1,53 @@
|
||||
@using Microsoft.Extensions.Options
|
||||
@using ShadcnBlazor.Cards
|
||||
@using ShadcnBlazor.Sidebars
|
||||
@inject IOptions<SystemSettingsOptions> Options
|
||||
|
||||
<div class="mt-5 flex flex-col md:flex-row gap-5">
|
||||
<Card ClassName="flex py-2 grow-0 min-w-56 max-h-[65vh] md:min-h-[65vh]">
|
||||
<CardContent ClassName="px-2 flex flex-col gap-y-1 h-full max-h-[65vh] overflow-y-auto scrollbar-thin">
|
||||
@foreach (var menuPage in Pages)
|
||||
{
|
||||
<SidebarMenuButton @onclick="() => Navigate(menuPage)" IsActive="@(CurrentPage == menuPage)"
|
||||
ClassName="overflow-visible">
|
||||
<DynamicComponent Type="@menuPage.IconComponentType"/>
|
||||
<span>@menuPage.Name</span>
|
||||
</SidebarMenuButton>
|
||||
}
|
||||
</CardContent>
|
||||
</Card>
|
||||
@if (CurrentPage != null)
|
||||
{
|
||||
<Card ClassName="flex grow">
|
||||
<CardHeader>
|
||||
<CardTitle>@CurrentPage.Name</CardTitle>
|
||||
<CardDescription>@CurrentPage.Description</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<DynamicComponent Type="@CurrentPage.ComponentType"/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
}
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private SystemSettingsPage[] Pages;
|
||||
private SystemSettingsPage? CurrentPage;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Pages = Options
|
||||
.Value
|
||||
.Components
|
||||
.OrderBy(x => x.Order)
|
||||
.ToArray();
|
||||
|
||||
CurrentPage = Pages.FirstOrDefault();
|
||||
}
|
||||
|
||||
private void Navigate(SystemSettingsPage page)
|
||||
{
|
||||
CurrentPage = page;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Moonlight.Frontend.Admin.Sys.Settings;
|
||||
|
||||
public class SystemSettingsOptions
|
||||
{
|
||||
private readonly List<SystemSettingsPage> InnerComponents = new();
|
||||
public IReadOnlyList<SystemSettingsPage> Components => InnerComponents;
|
||||
|
||||
public void Add<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TIcon,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
TComponent>(string name, string description,
|
||||
int order)
|
||||
where TIcon : ComponentBase where TComponent : ComponentBase
|
||||
{
|
||||
Add(name, description, order, typeof(TIcon), typeof(TComponent));
|
||||
}
|
||||
|
||||
public void Add(string name, string description, int order,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type iconComponent,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component)
|
||||
{
|
||||
InnerComponents.Add(new SystemSettingsPage(name, description, order, iconComponent, component));
|
||||
}
|
||||
|
||||
public void Remove<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TComponent>()
|
||||
where TComponent : ComponentBase
|
||||
{
|
||||
Remove(typeof(TComponent));
|
||||
}
|
||||
|
||||
public void Remove([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type componentType)
|
||||
{
|
||||
InnerComponents.RemoveAll(x => x.ComponentType == componentType);
|
||||
}
|
||||
}
|
||||
|
||||
public record SystemSettingsPage(
|
||||
string Name,
|
||||
string Description,
|
||||
int Order,
|
||||
Type IconComponentType,
|
||||
Type ComponentType
|
||||
);
|
||||
@@ -0,0 +1,74 @@
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Frontend.Shared.Frontend
|
||||
@using Moonlight.Shared.Admin.Sys.Settings
|
||||
@using ShadcnBlazor.Extras.Common
|
||||
@using ShadcnBlazor.Extras.Forms
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject ToastService ToastService
|
||||
@inject FrontendService FrontendService
|
||||
|
||||
<LazyLoader Load="LoadAsync">
|
||||
<EnhancedEditForm Model="Request" OnValidSubmit="OnValidSubmit">
|
||||
<DataAnnotationsValidator/>
|
||||
|
||||
<FieldSet>
|
||||
<FormValidationSummary/>
|
||||
|
||||
<FieldGroup>
|
||||
<Field>
|
||||
<FieldLabel>Name</FieldLabel>
|
||||
<TextInputField @bind-Value="Request.Name"/>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
</FieldSet>
|
||||
|
||||
<SubmitButton ClassName="mt-3">
|
||||
<SaveIcon/>
|
||||
Save
|
||||
</SubmitButton>
|
||||
</EnhancedEditForm>
|
||||
</LazyLoader>
|
||||
|
||||
@code
|
||||
{
|
||||
private SetWhiteLabelingDto Request;
|
||||
|
||||
private async Task LoadAsync(LazyLoader _)
|
||||
{
|
||||
var dto = await HttpClient.GetFromJsonAsync<WhiteLabelingDto>(
|
||||
"api/admin/system/settings/whiteLabeling",
|
||||
SerializationContext.Default.Options
|
||||
);
|
||||
|
||||
Request = new SetWhiteLabelingDto
|
||||
{
|
||||
Name = dto!.Name
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<bool> OnValidSubmit(EditContext editContext, ValidationMessageStore validationMessageStore)
|
||||
{
|
||||
var response = await HttpClient.PostAsJsonAsync(
|
||||
"api/admin/system/settings/whiteLabeling",
|
||||
Request,
|
||||
SerializationContext.Default.Options
|
||||
);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
await FrontendService.ReloadAsync();
|
||||
await ToastService.SuccessAsync("Setting", "Successfully updated white labeling settings");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user