feat: allow searching by server name
All checks were successful
Caddy Manager CI build / docker (push) Successful in 1m1s

This commit is contained in:
2025-07-12 10:55:04 +07:00
parent d90b77d537
commit d0bb0f709a
7 changed files with 42 additions and 58 deletions

View File

@@ -1,5 +1,6 @@
@page "/"
@attribute [StreamRendering]
@using CaddyManager.Models.Caddy
<PageTitle>Reverse proxy configurations</PageTitle>
@@ -24,11 +25,11 @@
AdornmentIcon="@(string.IsNullOrWhiteSpace(_debouncedText) ? Icons.Material.Filled.Search : Icons.Material.Filled.Close)"
OnAdornmentClick="HandleSearchBarAdornmentClick" />
</MudContainer>
<MudList T="string" Class="pt-10" SelectionMode="SelectionMode.MultiSelection"
<MudList T="CaddyConfigurationInfo" Class="pt-10" SelectionMode="SelectionMode.MultiSelection"
@bind-SelectedValues="_selectedCaddyConfigurations">
@foreach (var (index, caddyConfig) in _availableCaddyConfigurations.Index())
{
<CaddyReverseProxyItem FileName="@caddyConfig" OnCaddyRestartRequired="@RestartCaddy"/>
<CaddyReverseProxyItem ConfigurationInfo="@caddyConfig" OnCaddyRestartRequired="@RestartCaddy"/>
@if (index < _availableCaddyConfigurations.Count - 1)
{

View File

@@ -2,9 +2,11 @@ using System.Globalization;
using CaddyManager.Components.Pages.Generic;
using CaddyManager.Contracts.Caddy;
using CaddyManager.Contracts.Docker;
using CaddyManager.Models.Caddy;
using Humanizer;
using Microsoft.AspNetCore.Components;
using MudBlazor;
using CaddyfileEditorComponent = CaddyManager.Components.Pages.Caddy.CaddyfileEditor.CaddyfileEditor;
namespace CaddyManager.Components.Pages.Caddy.CaddyReverseProxies;
@@ -15,8 +17,8 @@ namespace CaddyManager.Components.Pages.Caddy.CaddyReverseProxies;
public partial class CaddyReverseProxiesPage : ComponentBase
{
private bool _isProcessing;
private List<string> _availableCaddyConfigurations = [];
private IReadOnlyCollection<string> _selectedCaddyConfigurations = [];
private List<CaddyConfigurationInfo> _availableCaddyConfigurations = [];
private IReadOnlyCollection<CaddyConfigurationInfo> _selectedCaddyConfigurations = [];
private string _debouncedText = string.Empty;
[Inject] private ICaddyService CaddyService { get; set; } = null!;
@@ -41,14 +43,14 @@ public partial class CaddyReverseProxiesPage : ComponentBase
/// <returns></returns>
private async Task NewReverseProxy()
{
var dialog = await DialogService.ShowAsync<CaddyfileEditor.CaddyfileEditor>("New configuration",
options: new MudBlazor.DialogOptions
var dialog = await DialogService.ShowAsync<CaddyfileEditorComponent>("New configuration",
options: new DialogOptions
{
FullWidth = true,
MaxWidth = MudBlazor.MaxWidth.Medium
}, parameters: new MudBlazor.DialogParameters
MaxWidth = MaxWidth.Medium
}, parameters: new DialogParameters<CaddyfileEditorComponent>
{
{ "FileName", string.Empty }
{ p => p.FileName, string.Empty }
});
var result = await dialog.Result;
@@ -66,9 +68,9 @@ public partial class CaddyReverseProxiesPage : ComponentBase
private void Refresh()
{
var notSearching = string.IsNullOrWhiteSpace(_debouncedText);
_availableCaddyConfigurations = CaddyService.GetExistingCaddyConfigurations()
.Where(confName => notSearching || confName.Contains(_debouncedText, StringComparison.OrdinalIgnoreCase))
.ToList();
_availableCaddyConfigurations = [..CaddyService.GetExistingCaddyConfigurations()
.Where(conf => notSearching || conf.FileName.Contains(_debouncedText, StringComparison.OrdinalIgnoreCase) || conf.ReverseProxyHostname.Contains(_debouncedText, StringComparison.OrdinalIgnoreCase))
.OrderBy(conf => conf.FileName)];
StateHasChanged();
}
@@ -93,10 +95,10 @@ public partial class CaddyReverseProxiesPage : ComponentBase
{
p => p.OnConfirm, EventCallback.Factory.Create(this, () =>
{
var response = CaddyService.DeleteCaddyConfigurations(_selectedCaddyConfigurations.ToList());
var response = CaddyService.DeleteCaddyConfigurations(_selectedCaddyConfigurations.Select(c => c.FileName).ToList());
_selectedCaddyConfigurations =
_selectedCaddyConfigurations.Except(response.DeletedConfigurations).ToList();
_selectedCaddyConfigurations.Where(c => !response.DeletedConfigurations.Contains(c.FileName)).ToList();
if (response.Success)
{

View File

@@ -1,10 +1,11 @@
@using Humanizer
@using CaddyManager.Models.Caddy
@attribute [StreamRendering]
<MudListItem T="string" Text="@FileName" OnClick="Edit" OnClickPreventDefault="true">
<MudListItem T="CaddyConfigurationInfo" Text="@ConfigurationInfo.FileName" OnClick="Edit" OnClickPreventDefault="true">
<MudStack Row AlignItems="AlignItems.Center" Class="pl-2">
<MudIcon Icon="@Icons.Custom.FileFormats.FileCode"></MudIcon>
<MudText>@FileName</MudText>
<MudText>@ConfigurationInfo.FileName</MudText>
<MudSpacer/>
<MudChip T="string" Variant="Variant.Outlined">@ConfigurationInfo.ReverseProxyHostname</MudChip>
<MudTooltip Delay="0" Placement="Placement.Left">

View File

@@ -11,49 +11,21 @@ namespace CaddyManager.Components.Pages.Caddy.CaddyReverseProxies;
/// </summary>
public partial class CaddyReverseProxyItem : ComponentBase
{
/// <summary>
/// File path of the Caddy configuration file
/// </summary>
[Parameter]
public string FileName { get; set; } = string.Empty;
/// <summary>
/// Callback to refresh the Caddy reverse proxies on the main page
/// </summary>
[Parameter]
public EventCallback OnCaddyRestartRequired { get; set; }
[Parameter]
public CaddyConfigurationInfo ConfigurationInfo { get; set; } = null!;
/// <summary>
/// Dialog service for showing the Caddy file editor dialog
/// </summary>
[Inject]
private IDialogService DialogService { get; set; } = null!;
/// <summary>
/// Caddy service for getting the Caddy configuration file information
/// </summary>
[Inject]
private ICaddyService CaddyService { get; set; } = null!;
private CaddyConfigurationInfo ConfigurationInfo { get; set; } = new();
/// <summary>
/// Refresh the current state of the component.
/// </summary>
private void Refresh()
{
ConfigurationInfo = CaddyService.GetCaddyConfigurationInfo(FileName);
StateHasChanged();
}
/// <inheritdoc />
protected override void OnAfterRender(bool firstRender)
{
if (!firstRender) return;
Refresh();
}
/// <summary>
/// Show the Caddy file editor dialog
/// </summary>
@@ -63,10 +35,10 @@ public partial class CaddyReverseProxyItem : ComponentBase
var dialog = await DialogService.ShowAsync<CaddyfileEditor.CaddyfileEditor>("Caddy file", options: new DialogOptions
{
FullWidth = true,
MaxWidth = MaxWidth.Medium,
}, parameters: new DialogParameters
MaxWidth = MudBlazor.MaxWidth.Medium,
}, parameters: new MudBlazor.DialogParameters
{
{ "FileName", FileName }
{ "FileName", ConfigurationInfo.FileName }
});
var result = await dialog.Result;
@@ -75,7 +47,5 @@ public partial class CaddyReverseProxyItem : ComponentBase
{
await OnCaddyRestartRequired.InvokeAsync();
}
Refresh();
}
}

View File

@@ -11,7 +11,7 @@ public interface ICaddyService
/// Returns the existing Caddy configurations within the configured directory
/// </summary>
/// <returns></returns>
List<string> GetExistingCaddyConfigurations();
List<CaddyConfigurationInfo> GetExistingCaddyConfigurations();
/// <summary>
/// Method to get the content of a Caddy configuration file by its name

View File

@@ -19,4 +19,9 @@ public class CaddyConfigurationInfo
/// Ports being used with the reverse proxy hostname
/// </summary>
public List<int> ReverseProxyPorts { get; set; } = [];
/// <summary>
/// The name of the configuration file.
/// </summary>
public string FileName { get; set; } = string.Empty;
}

View File

@@ -18,18 +18,23 @@ public class CaddyService(
private CaddyServiceConfigurations Configurations => configurationsService.Get<CaddyServiceConfigurations>();
/// <inheritdoc />
public List<string> GetExistingCaddyConfigurations()
public List<CaddyConfigurationInfo> GetExistingCaddyConfigurations()
{
if (!Directory.Exists(Configurations.ConfigDir))
{
Directory.CreateDirectory(Configurations.ConfigDir);
}
return Directory.GetFiles(Configurations.ConfigDir)
return [.. Directory.GetFiles(Configurations.ConfigDir)
.Where(filePath => Path.GetFileName(filePath) != CaddyGlobalConfigName)
.Select(Path.GetFileNameWithoutExtension)
.Order()
.ToList()!;
.Select(filePath =>
{
var fileName = Path.GetFileNameWithoutExtension(filePath);
var info = GetCaddyConfigurationInfo(fileName);
info.FileName = fileName;
return info;
})
.OrderBy(info => info.FileName)];
}
/// <inheritdoc />