Updated web ui to razor

This commit is contained in:
2025-04-22 23:40:00 +03:00
parent c548c6191d
commit 2d319f3d34
108 changed files with 983 additions and 168 deletions

View File

@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter] private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@@ -0,0 +1,7 @@
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.

View File

@@ -0,0 +1,142 @@
@page "/plugins/local"
@using DiscordBotCore.Logging
@using DiscordBotCore.PluginManagement
@using DiscordBotCore.PluginManagement.Models
<h3>Installed Plugins</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Version</th>
<th>Offline Added</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var plugin in _installedPlugins)
{
<tr>
<td>@plugin.Name</td>
<td>@plugin.Version</td>
<td>@(plugin.IsOfflineAdded ? "Yes" : "No")</td>
<td>
<button class="btn btn-danger btn-sm" @onclick="async () => await DeletePluginButtonClick(plugin.Name)">Delete</button>
<button class="btn btn-info btn-sm" @onclick="async () => await PluginDetailsButtonClick(plugin.Name)">Details</button>
</td>
</tr>
}
</tbody>
</table>
@if (_showPluginDetailsModal && _selectedPluginDetails != null)
{
<div class="modal show d-block" tabindex="-1" style="background-color: rgba(0,0,0,0.5);">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Plugin Details: @_selectedPluginDetails.Name</h5>
<button type="button" class="btn-close" @onclick="ClosePluginDetailsModal"></button>
</div>
<div class="modal-body">
<p><strong>Version:</strong> @_selectedPluginDetails.Version</p>
<p><strong>Author:</strong> @_selectedPluginDetails.Author</p>
<p><strong>Description:</strong> @_selectedPluginDetails.Description</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" @onclick="ClosePluginDetailsModal">Close</button>
</div>
</div>
</div>
</div>
}
@code {
[Inject]
public IPluginManager PluginManager { get; set; }
[Inject]
public ILogger Logger { get; set; }
private readonly List<InstalledPlugin> _installedPlugins = new List<InstalledPlugin>();
private bool _showPluginDetailsModal;
private OnlinePlugin? _selectedPluginDetails;
private async Task DeletePluginButtonClick(string pluginName)
{
Logger.Log($"Deleting plugin {pluginName}", this);
bool result = await PluginManager.MarkPluginToUninstall(pluginName);
if (!result)
{
Logger.Log($"Failed to delete plugin {pluginName}", this, LogType.Error);
return;
}
_installedPlugins.RemoveAll(p => p.Name == pluginName);
Logger.Log($"Plugin {pluginName} deleted", this);
StateHasChanged();
}
private async Task PluginDetailsButtonClick(string pluginName)
{
Logger.Log($"Getting plugin details for {pluginName}", this);
var pluginDetails = await PluginManager.GetPluginDataByName(pluginName);
if (pluginDetails == null)
{
Logger.Log($"Failed to get details for plugin {pluginName}", this, LogType.Error);
return;
}
_selectedPluginDetails = pluginDetails;
_showPluginDetailsModal = true;
Logger.Log($"Plugin details for {pluginName} retrieved", this);
StateHasChanged();
}
private void ClosePluginDetailsModal()
{
Logger.Log("Closing plugin details modal", this);
_showPluginDetailsModal = false;
_selectedPluginDetails = null;
StateHasChanged();
}
protected override async Task OnInitializedAsync()
{
Logger.Log("Local plugins page initialized", this);
var plugins = await PluginManager.GetInstalledPlugins();
if (!plugins.Any())
{
Logger.Log("No plugins found", this, LogType.Warning);
return;
}
Logger.Log($"Found {plugins.Count} plugins", this);
_installedPlugins.Clear();
foreach (var plugin in plugins)
{
var installedPlugin = new InstalledPlugin
{
Name = plugin.PluginName,
Version = plugin.PluginVersion,
IsOfflineAdded = plugin.IsOfflineAdded
};
_installedPlugins.Add(installedPlugin);
}
StateHasChanged();
}
private class InstalledPlugin
{
public string Name { get; set; }
public string Version { get; set; }
public bool IsOfflineAdded { get; set; }
}
}

View File

@@ -0,0 +1,148 @@
@page "/plugins/online"
@using DiscordBotCore.Logging
@using DiscordBotCore.PluginManagement
<h3>Available Plugins</h3>
@if (_onlinePlugins.Any())
{
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Author</th>
<th>Version</th>
<th>Download</th>
</tr>
</thead>
<tbody>
@foreach (var plugin in _onlinePlugins)
{
<tr>
<td>@plugin.Name</td>
<td>@plugin.Description</td>
<td>@plugin.Author</td>
<td>@plugin.Version</td>
<td>
<button type="button" class="btn btn-primary" @onmousedown="async () => await InstallPlugin(plugin.Id)">Download</button>
</td>
</tr>
}
</tbody>
</table>
}
else
{
<p>Loading...</p>
}
@if (_showInstallPercentage)
{
<div class="modal show d-block" tabindex="-1" style="background-color: rgba(0, 0, 0, 0.5);">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Installing Plugin...</h5>
<button type="button" class="btn-close" @onclick="CloseInstallPercentageModal"></button>
</div>
<div class="modal-body">
<p>Progress: @($"{_installPercentage:F0}")%</p>
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar"
style="width: @_installPercentage%"
aria-valuenow="@_installPercentage"
aria-valuemin="0"
aria-valuemax="100">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" @onclick="CloseInstallPercentageModal">Cancel</button>
</div>
</div>
</div>
</div>
}
@code {
[Inject]
public IPluginManager PluginManager { get; set; }
[Inject]
public ILogger Logger { get; set; }
private bool _showInstallPercentage;
private float _installPercentage = 0f;
private readonly List<OnlinePluginModel> _onlinePlugins = new();
protected override async Task OnInitializedAsync()
{
Logger.Log("Getting online plugins...", this);
var plugins = await PluginManager.GetPluginsList();
if (!plugins.Any())
{
Logger.Log("No online plugins found.", this);
return;
}
_onlinePlugins.Clear();
foreach (var plugin in plugins)
{
var onlinePlugin = new OnlinePluginModel
{
Id = plugin.Id,
Name = plugin.Name,
Description = plugin.Description,
Author = plugin.Author,
Version = plugin.Version,
};
_onlinePlugins.Add(onlinePlugin);
}
}
private async Task InstallPlugin(int pluginId)
{
var pluginData = await PluginManager.GetPluginDataById(pluginId);
if (pluginData == null)
{
Logger.Log($"Plugin data not found for ID: {pluginId}", this);
return;
}
Logger.Log($"Installing plugin {pluginData.Name}...", this);
_showInstallPercentage = true;
IProgress<float> progress = new Progress<float>(percent =>
{
_installPercentage = percent;
StateHasChanged();
});
await PluginManager.InstallPlugin(pluginData, progress);
Logger.Log($"Plugin {pluginData.Name} installed successfully.", this);
CloseInstallPercentageModal();
}
private void CloseInstallPercentageModal()
{
Logger.Log("Closing install percentage modal", this);
_showInstallPercentage = false;
_installPercentage = 0f;
}
private class OnlinePluginModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public string Version { get; set; }
}
}