190 lines
5.7 KiB
Plaintext
190 lines
5.7 KiB
Plaintext
@page "/admin/sys/settings"
|
|
@using Moonlight.App.Services
|
|
@using System.Reflection
|
|
@using Moonlight.App.Extensions.Attributes
|
|
@using Moonlight.App.Models.Enums
|
|
|
|
@attribute [RequirePermission(Permission.AdminRoot)]
|
|
|
|
@inject ConfigService ConfigService
|
|
@inject ToastService ToastService
|
|
|
|
<AdminSysNavigation Index="1" />
|
|
|
|
@if (ModelToShow == null)
|
|
{
|
|
<NotFoundAlert />
|
|
}
|
|
else
|
|
{
|
|
<div class="card mt-5">
|
|
<div class="card-header">
|
|
@{
|
|
string title;
|
|
|
|
if (Path.Length == 0)
|
|
title = "Configuration";
|
|
else
|
|
{
|
|
title = "Configuration - " + string.Join(" - ", Path);
|
|
}
|
|
}
|
|
|
|
<h3 class="card-title">@(title)</h3>
|
|
<div class="card-toolbar">
|
|
<WButton OnClick="Reload" CssClasses="btn btn-icon btn-warning me-3">
|
|
<i class="bx bx-sm bx-revision"></i>
|
|
</WButton>
|
|
<WButton OnClick="Save" CssClasses="btn btn-icon btn-success">
|
|
<i class="bx bx-sm bx-save"></i>
|
|
</WButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Tooltip>
|
|
Changes to these settings are live applied. The save button only make the changes persistently saved to disk
|
|
</Tooltip>
|
|
|
|
<div class="row mt-5">
|
|
<div class="col-md-3 col-12 mb-5">
|
|
<div class="card card-body">
|
|
@{
|
|
var props = ModelToShow
|
|
.GetType()
|
|
.GetProperties()
|
|
.Where(x => x.PropertyType.Assembly.FullName!.Contains("Moonlight") && x.PropertyType.IsClass)
|
|
.ToArray();
|
|
}
|
|
|
|
@foreach (var prop in props)
|
|
{
|
|
<div class="d-flex flex-stack">
|
|
<div class="d-flex align-items-center flex-row-fluid flex-wrap">
|
|
<a href="/admin/sys/settings?section=@(Section + "/" + prop.Name)" class="fs-4 text-primary">@(prop.Name)</a>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@if (Path.Length != 0)
|
|
{
|
|
<div class="d-flex flex-stack">
|
|
<div class="d-flex align-items-center flex-row-fluid flex-wrap">
|
|
<a href="/admin/sys/@(GetBackPath())" class="fs-4 text-primary">Back</a>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-9 col-12">
|
|
<div class="card card-body">
|
|
<div class="row">
|
|
<LazyLoader @ref="LazyLoader" Load="Load">
|
|
@foreach (var prop in Properties)
|
|
{
|
|
<div class="col-md-6 col-12">
|
|
<CascadingValue Name="Property" Value="prop">
|
|
<CascadingValue Name="Data" Value="ModelToShow">
|
|
@{
|
|
var typeToCreate = typeof(AutoProperty<>).MakeGenericType(prop.PropertyType);
|
|
}
|
|
|
|
@ComponentHelper.FromType(typeToCreate)
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</div>
|
|
}
|
|
</LazyLoader>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@code
|
|
{
|
|
[Parameter]
|
|
[SupplyParameterFromQuery]
|
|
public string? Section { get; set; } = "";
|
|
|
|
private object? ModelToShow;
|
|
private PropertyInfo[] Properties = Array.Empty<PropertyInfo>();
|
|
private string[] Path = Array.Empty<string>();
|
|
|
|
private LazyLoader? LazyLoader;
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
if (Section != null && Section.StartsWith("/"))
|
|
Section = Section.TrimStart('/');
|
|
|
|
Path = Section != null ? Section.Split("/") : Array.Empty<string>();
|
|
|
|
ModelToShow = Resolve(ConfigService.Get(), Path, 0);
|
|
|
|
if (ModelToShow != null)
|
|
{
|
|
Properties = ModelToShow
|
|
.GetType()
|
|
.GetProperties()
|
|
.Where(x => !x.PropertyType.Assembly.FullName!.Contains("Moonlight"))
|
|
.ToArray();
|
|
}
|
|
else
|
|
{
|
|
Properties = Array.Empty<PropertyInfo>();
|
|
}
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
if (LazyLoader != null)
|
|
await LazyLoader.Reload();
|
|
}
|
|
|
|
private string GetBackPath()
|
|
{
|
|
if (Path.Length == 1)
|
|
return "settings";
|
|
else
|
|
{
|
|
var path = string.Join('/', Path.Take(Path.Length - 1)).TrimEnd('/');
|
|
return $"settings?section={path}";
|
|
}
|
|
}
|
|
|
|
private object? Resolve(object model, string[] path, int index)
|
|
{
|
|
if (path.Length == 0)
|
|
return model;
|
|
|
|
if (path.Length == index)
|
|
return model;
|
|
|
|
var prop = model
|
|
.GetType()
|
|
.GetProperties()
|
|
.FirstOrDefault(x => x.PropertyType.Assembly.FullName!.Contains("Moonlight") && x.Name == path[index]);
|
|
|
|
if (prop == null)
|
|
return null;
|
|
|
|
return Resolve(prop.GetValue(model)!, path, index + 1);
|
|
}
|
|
|
|
private Task Load(LazyLoader arg)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private async Task Save()
|
|
{
|
|
ConfigService.Save();
|
|
await ToastService.Success("Successfully saved config to disk");
|
|
}
|
|
|
|
private async Task Reload()
|
|
{
|
|
ConfigService.Reload();
|
|
await ToastService.Info("Reloaded configuration from disk");
|
|
}
|
|
} |