@@ -17,6 +19,11 @@
@foreach (var setting in settings)
{
+ @if (!string.IsNullOrEmpty(setting.SettingDescription))
+ {
+ @setting.SettingDescription
+ }
+
@if (setting.Property.PropertyType == typeof(bool))
{
var boolVal = (bool)(setting.Value ?? false);
@@ -49,6 +56,15 @@
}
}
+ else if (IsListType(setting.Property.PropertyType))
+ {
+ var s = setting;
+ @setting.Description
+
+ Edit
+ }
else
{
var strVal = setting.Value?.ToString() ?? "";
@@ -76,6 +92,8 @@
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
[Parameter] public InspectronSettings? Settings { get; set; }
+ [Microsoft.AspNetCore.Components.Inject] private IDialogService DialogService { get; set; } = null!;
+
private Dictionary> _categories = new();
private string? _selectedCategory;
private List _treeRoot = new();
@@ -95,7 +113,6 @@
if (root != null)
Traverse(root, "");
- // Build the UI tree from category paths
foreach (var categoryPath in _categories.Keys)
{
var parts = categoryPath.Split('/');
@@ -137,11 +154,18 @@
{
var owner = bpd.Owner;
var description = string.IsNullOrEmpty(pd.Description) ? bpd.DisplayName : pd.Description;
+
+ string? settingDesc = null;
+ var descAttr = bpd.PropertyInfo.GetCustomAttribute();
+ if (descAttr != null)
+ settingDesc = descAttr.Description;
+
var entry = new SettingEntry
{
Owner = owner,
Property = bpd.PropertyInfo,
Description = description,
+ SettingDescription = settingDesc,
Value = bpd.PropertyInfo.GetValue(owner)
};
@@ -163,11 +187,9 @@
private List GetSettingsForCategory(string category)
{
- // Exact match first
if (_categories.TryGetValue(category, out var exact))
return exact;
- // Otherwise aggregate all sub-categories
var prefix = category + "/";
return _categories
.Where(kvp => kvp.Key.StartsWith(prefix))
@@ -175,6 +197,39 @@
.ToList();
}
+ private static bool IsListType(Type type)
+ {
+ return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>);
+ }
+
+ private static string GetListDisplayText(IList? list)
+ {
+ if (list == null || list.Count == 0)
+ return "(empty list)";
+ var items = new List();
+ foreach (var item in list)
+ items.Add(item?.ToString() ?? "(null)");
+ return string.Join(Environment.NewLine, items);
+ }
+
+ private async Task EditList(SettingEntry setting)
+ {
+ var elementType = setting.Property.PropertyType.GetGenericArguments()[0];
+ var parameters = new DialogParameters
+ {
+ { x => x.ElementType, elementType },
+ { x => x.InitialList, setting.Value as IList }
+ };
+ var options = new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true };
+ var dialog = await DialogService.ShowAsync($"Edit {setting.Description}", parameters, options);
+ var result = await dialog.Result;
+ if (result != null && !result.Canceled && result.Data is IList newList)
+ {
+ setting.Value = newList;
+ StateHasChanged();
+ }
+ }
+
private void Save()
{
foreach (var list in _categories.Values)
@@ -186,7 +241,22 @@
{
try
{
- if (setting.Value != null && setting.Value.GetType() != setting.Property.PropertyType)
+ if (IsListType(setting.Property.PropertyType) && setting.Value is IList listVal)
+ {
+ // For list types, clear and repopulate the original list
+ var originalList = setting.Property.GetValue(setting.Owner) as IList;
+ if (originalList != null)
+ {
+ originalList.Clear();
+ foreach (var item in listVal)
+ originalList.Add(item);
+ }
+ else
+ {
+ setting.Property.SetValue(setting.Owner, setting.Value);
+ }
+ }
+ else if (setting.Value != null && setting.Value.GetType() != setting.Property.PropertyType)
{
var converted = Convert.ChangeType(setting.Value, setting.Property.PropertyType);
setting.Property.SetValue(setting.Owner, converted);
@@ -198,7 +268,6 @@
}
catch
{
- // Skip properties that fail to convert
}
}
}
@@ -214,6 +283,7 @@
public object Owner { get; set; } = null!;
public PropertyInfo Property { get; set; } = null!;
public string Description { get; set; } = "";
+ public string? SettingDescription { get; set; }
public object? Value { get; set; }
}
diff --git a/VisionBuilder.UI.Blazor/wwwroot/css/visionbuilder.css b/VisionBuilder.UI.Blazor/wwwroot/css/visionbuilder.css
index dc8b516..7bfae6c 100644
--- a/VisionBuilder.UI.Blazor/wwwroot/css/visionbuilder.css
+++ b/VisionBuilder.UI.Blazor/wwwroot/css/visionbuilder.css
@@ -289,5 +289,26 @@
}
.settings-field {
- margin-bottom: 12px;
+ margin-bottom: 16px;
+}
+
+/* List Editor Dialog */
+.list-editor-layout {
+ display: flex;
+ gap: 12px;
+ min-height: 300px;
+}
+
+.list-editor-list {
+ flex: 1;
+ border: 1px solid #e0e0e0;
+ overflow-y: auto;
+ max-height: 350px;
+}
+
+.list-editor-buttons {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ min-width: 80px;
}