Added a new visual config editor

This commit is contained in:
Marcel Baumgartner
2023-07-06 16:46:01 +02:00
parent ab529991fd
commit d024a834f9
9 changed files with 442 additions and 42 deletions

View File

@@ -0,0 +1,65 @@
@using System.Reflection
@using System.Collections
@using Moonlight.App.Helpers
<div class="accordion my-3" id="configSetting@(Model.GetHashCode())">
<div class="accordion-item">
<h2 class="accordion-header" id="configSetting-header@(Model.GetHashCode())">
<button class="accordion-button fs-4 fw-semibold collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#configSetting-body@(Model.GetHashCode())" aria-expanded="false" aria-controls="configSetting-body@(Model.GetHashCode())">
@{
var name = Formatter.ReplaceEnd(Model.GetType().Name, "Data", "");
name = Formatter.ConvertCamelCaseToSpaces(name);
}
@(name)
</button>
</h2>
<div id="configSetting-body@(Model.GetHashCode())" class="accordion-collapse collapse" aria-labelledby="configSetting-header@(Model.GetHashCode())" data-bs-parent="#configSetting">
<div class="accordion-body">
@foreach (var property in Model.GetType().GetProperties())
{
@BindAndRenderProperty(property)
}
</div>
</div>
</div>
</div>
@code
{
[Parameter]
public object Model { get; set; }
private RenderFragment BindAndRenderProperty(PropertyInfo property)
{
if (property.PropertyType.IsClass && !property.PropertyType.IsPrimitive && !typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
return @<SmartFormClass Model="@property.GetValue(Model)"/>;
// If the property is a subclass, serialize and generate form for it
/*
foreach (var subProperty in property.PropertyType.GetProperties())
{
return BindAndRenderProperty(subProperty);
}*/
}
else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(string) || property.PropertyType == typeof(bool) || property.PropertyType == typeof(decimal) || property.PropertyType == typeof(long))
{
return @<SmartFormProperty Model="Model" PropertyInfo="property"/>;
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
// If the property is a collection, generate form for each element
var collection = property.GetValue(Model) as IEnumerable;
if (collection != null)
{
foreach (var element in collection)
{
}
}
}
// Additional property types could be handled here (e.g., DateTime, int, etc.)
return @<div></div>;
}
}

View File

@@ -0,0 +1,79 @@
@using System.Reflection
@using Moonlight.App.Helpers
@using System.ComponentModel
<label class="form-label" for="@PropertyInfo.Name">
@(Formatter.ConvertCamelCaseToSpaces(PropertyInfo.Name))
</label>
@{
//TODO: Tidy up this code
var attrs = PropertyInfo.GetCustomAttributes(true);
var descAttr = attrs
.FirstOrDefault(x => x.GetType() == typeof(DescriptionAttribute));
var blurBool = attrs.Any(x => x.GetType() == typeof(BlurAttribute));
var blur = blurBool ? "blur-unless-hover" : "";
}
@if (descAttr != null)
{
var a = descAttr as DescriptionAttribute;
<div class="form-text fs-5 mb-2 mt-0">
@(a.Description)
</div>
}
<div class="input-group mb-5">
@if (PropertyInfo.PropertyType == typeof(string))
{
var binder = new PropBinder(PropertyInfo, Model!);
<div class="@(blur) w-100">
<InputText id="@PropertyInfo.Name" @bind-Value="binder.StringValue" class="form-control"/>
</div>
}
else if (PropertyInfo.PropertyType == typeof(int))
{
var binder = new PropBinder(PropertyInfo, Model!);
<InputNumber id="@PropertyInfo.Name" @bind-Value="binder.IntValue" class="form-control"/>
}
else if (PropertyInfo.PropertyType == typeof(long))
{
var binder = new PropBinder(PropertyInfo, Model!);
<InputNumber id="@PropertyInfo.Name" @bind-Value="binder.LongValue" class="form-control"/>
}
else if (PropertyInfo.PropertyType == typeof(bool))
{
var binder = new PropBinder(PropertyInfo, Model!);
<div class="form-check">
<InputCheckbox id="@PropertyInfo.Name" @bind-Value="binder.BoolValue" class="form-check-input"/>
</div>
}
else if (PropertyInfo.PropertyType == typeof(DateTime))
{
var binder = new PropBinder(PropertyInfo, Model!);
<InputDate id="@PropertyInfo.Name" @bind-Value="binder.DateTimeValue" class="form-control"/>
}
else if (PropertyInfo.PropertyType == typeof(decimal))
{
var binder = new PropBinder(PropertyInfo, Model!);
<InputNumber id="@PropertyInfo.Name" step="0.01" @bind-Value="binder.DoubleValue" class="form-control"/>
}
</div>
@code
{
[Parameter]
public PropertyInfo PropertyInfo { get; set; }
[Parameter]
public object Model { get; set; }
}

View File

@@ -39,6 +39,11 @@
<TL>News</TL>
</a>
</li>
<li class="nav-item mt-2">
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 8 ? "active" : "")" href="/admin/system/configuration">
<TL>Configuration</TL>
</a>
</li>
</ul>
</div>
</div>