diff --git a/CaddyManager/CaddyManager.csproj b/CaddyManager/CaddyManager.csproj index aad5d47..fab0efe 100644 --- a/CaddyManager/CaddyManager.csproj +++ b/CaddyManager/CaddyManager.csproj @@ -5,6 +5,7 @@ enable enable Linux + 13 @@ -14,6 +15,7 @@ + diff --git a/CaddyManager/Components/App.razor b/CaddyManager/Components/App.razor index 43e2f5e..8f70b9c 100644 --- a/CaddyManager/Components/App.razor +++ b/CaddyManager/Components/App.razor @@ -16,6 +16,9 @@ + + + diff --git a/CaddyManager/Components/Layout/MainLayout.razor b/CaddyManager/Components/Layout/MainLayout.razor index a168a7d..a9feeb8 100644 --- a/CaddyManager/Components/Layout/MainLayout.razor +++ b/CaddyManager/Components/Layout/MainLayout.razor @@ -12,20 +12,11 @@ - + - - - Caddy Manager - - - Reverse Proxies - Global Caddyfile - Settings - - + @Body @@ -33,11 +24,7 @@ -@code{ - private bool _open = false; - - private void ToggleDrawer() - { - _open = !_open; - } -} \ No newline at end of file +@code +{ + private NavigationDrawer _drawer = null!; +} diff --git a/CaddyManager/Components/Layout/NavigationDrawer.razor b/CaddyManager/Components/Layout/NavigationDrawer.razor new file mode 100644 index 0000000..fa01f8e --- /dev/null +++ b/CaddyManager/Components/Layout/NavigationDrawer.razor @@ -0,0 +1,10 @@ + + + Caddy Manager + + + Reverse Proxies + Global Caddyfile + Settings + + \ No newline at end of file diff --git a/CaddyManager/Components/Layout/NavigationDrawer.razor.cs b/CaddyManager/Components/Layout/NavigationDrawer.razor.cs new file mode 100644 index 0000000..5979750 --- /dev/null +++ b/CaddyManager/Components/Layout/NavigationDrawer.razor.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Components; + +namespace CaddyManager.Components.Layout; + +public partial class NavigationDrawer : ComponentBase +{ + private bool _drawerOpen = false; + + internal void ToggleDrawer() + { + _drawerOpen = !_drawerOpen; + } +} \ No newline at end of file diff --git a/CaddyManager/Components/Pages/Caddyfile.razor b/CaddyManager/Components/Pages/Caddyfile.razor index 4f7cc1a..ed8e896 100644 --- a/CaddyManager/Components/Pages/Caddyfile.razor +++ b/CaddyManager/Components/Pages/Caddyfile.razor @@ -1,66 +1,24 @@ @page "/caddyfile" +@attribute [StreamRendering] +@using CaddyManager.Contracts.Caddy +@inject ICaddyService CaddyService -Weather +Global Caddyfile -

Weather

- -

This component demonstrates showing data.

- -@if (forecasts == null) -{ -

- Loading... -

-} -else -{ - - - - - - - - - - - @foreach (var forecast in forecasts) - { - - - - - - - } - -
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
-} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - // Simulate asynchronous loading to demonstrate a loading indicator - await Task.Delay(500); - - var startDate = DateOnly.FromDateTime(DateTime.Now); - var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; - forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = startDate.AddDays(index), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = summaries[Random.Shared.Next(summaries.Length)] - }).ToArray(); - } - - private class WeatherForecast - { - public DateOnly Date { get; set; } - public int TemperatureC { get; set; } - public string? Summary { get; set; } - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - } - -} \ No newline at end of file + + + + Global Caddyfile + + + + + + + + + Save + Cancel + + + diff --git a/CaddyManager/Components/Pages/Caddyfile.razor.cs b/CaddyManager/Components/Pages/Caddyfile.razor.cs new file mode 100644 index 0000000..64c6d1c --- /dev/null +++ b/CaddyManager/Components/Pages/Caddyfile.razor.cs @@ -0,0 +1,36 @@ +using BlazorMonaco.Editor; +using Microsoft.AspNetCore.Components; + +namespace CaddyManager.Components.Pages; + +public partial class Caddyfile: ComponentBase +{ + private string _caddyConfigurationContent = string.Empty; + + protected override Task OnInitializedAsync() + { + // Load the content of the Caddy configuration file + _caddyConfigurationContent = CaddyService.GetCaddyGlobalConfigurationContent(); + return base.OnInitializedAsync(); + } + + private StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor) + { + return new StandaloneEditorConstructionOptions + { + AutomaticLayout = true, + Language = "plaintext", + Value = _caddyConfigurationContent, + }; + } + + private void Submit() + { + // CaddyService.SaveCaddyGlobalConfigurationContent(_caddyConfigurationContent); + } + + private void Cancel() + { + // CaddyService.GetCaddyGlobalConfigurationContent(); + } +} \ No newline at end of file diff --git a/CaddyManager/Components/Pages/CaddyfileEditor/CaddyfileEditor.razor b/CaddyManager/Components/Pages/CaddyfileEditor/CaddyfileEditor.razor new file mode 100644 index 0000000..f6aeee4 --- /dev/null +++ b/CaddyManager/Components/Pages/CaddyfileEditor/CaddyfileEditor.razor @@ -0,0 +1,14 @@ +@attribute [StreamRendering] +@using CaddyManager.Contracts.Caddy +@inject ICaddyService CaddyService + + + + + + + + Cancel + Save + + \ No newline at end of file diff --git a/CaddyManager/Components/Pages/CaddyfileEditor/CaddyfileEditor.razor.cs b/CaddyManager/Components/Pages/CaddyfileEditor/CaddyfileEditor.razor.cs new file mode 100644 index 0000000..282f7fd --- /dev/null +++ b/CaddyManager/Components/Pages/CaddyfileEditor/CaddyfileEditor.razor.cs @@ -0,0 +1,37 @@ +using BlazorMonaco.Editor; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace CaddyManager.Components.Pages.CaddyfileEditor; + +public partial class CaddyfileEditor : ComponentBase +{ + private string _caddyConfigurationContent = string.Empty; + + [CascadingParameter] + private IMudDialogInstance MudDialog { get; set; } = null!; + + [Parameter] + public string FileName { get; set; } = string.Empty; + + protected override Task OnInitializedAsync() + { + // Load the content of the Caddy configuration file + _caddyConfigurationContent = CaddyService.GetCaddyConfigurationContent(FileName); + return base.OnInitializedAsync(); + } + + private StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor) + { + return new StandaloneEditorConstructionOptions + { + AutomaticLayout = true, + Language = "plaintext", + Value = _caddyConfigurationContent, + }; + } + + private void Submit() => MudDialog.Close(DialogResult.Ok(true)); + + private void Cancel() => MudDialog.Cancel(); +} \ No newline at end of file diff --git a/CaddyManager/Components/Pages/ReverseProxies.razor b/CaddyManager/Components/Pages/ReverseProxies.razor deleted file mode 100644 index 3f196b6..0000000 --- a/CaddyManager/Components/Pages/ReverseProxies.razor +++ /dev/null @@ -1,24 +0,0 @@ -@page "/" -@using CaddyManager.Contracts.Caddy -@inject ICaddyService CaddyService - -Home - - - @foreach(var caddyConfig in _availableCaddyConfigurations) - { - - - } - - -@code -{ - List _availableCaddyConfigurations = []; - - protected override Task OnInitializedAsync() - { - _availableCaddyConfigurations = CaddyService.GetExistingCaddyConfigurations(); - return base.OnInitializedAsync(); - } -} diff --git a/CaddyManager/Components/Pages/ReverseProxies/ReverseProxiesPage.razor b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxiesPage.razor new file mode 100644 index 0000000..422cfd7 --- /dev/null +++ b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxiesPage.razor @@ -0,0 +1,14 @@ +@page "/" +@attribute [StreamRendering] +@using CaddyManager.Contracts.Caddy +@inject ICaddyService CaddyService + +Reverse proxy confiurations + + + @foreach(var caddyConfig in _availableCaddyConfigurations) + { + + + } + \ No newline at end of file diff --git a/CaddyManager/Components/Pages/ReverseProxies/ReverseProxiesPage.razor.cs b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxiesPage.razor.cs new file mode 100644 index 0000000..b54c25c --- /dev/null +++ b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxiesPage.razor.cs @@ -0,0 +1,12 @@ +namespace CaddyManager.Components.Pages.ReverseProxies; + +public partial class ReverseProxiesPage +{ + private List _availableCaddyConfigurations = []; + + protected override Task OnInitializedAsync() + { + _availableCaddyConfigurations = CaddyService.GetExistingCaddyConfigurations(); + return base.OnInitializedAsync(); + } +} \ No newline at end of file diff --git a/CaddyManager/Components/Pages/ReverseProxies/ReverseProxyItem.razor b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxyItem.razor new file mode 100644 index 0000000..68ee571 --- /dev/null +++ b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxyItem.razor @@ -0,0 +1,6 @@ +@using CaddyManager.Contracts.Caddy +@attribute [StreamRendering] +@inject ICaddyService CaddyService +@inject IDialogService DialogService + + \ No newline at end of file diff --git a/CaddyManager/Components/Pages/ReverseProxies/ReverseProxyItem.razor.cs b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxyItem.razor.cs new file mode 100644 index 0000000..9a1c4e8 --- /dev/null +++ b/CaddyManager/Components/Pages/ReverseProxies/ReverseProxyItem.razor.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace CaddyManager.Components.Pages.ReverseProxies; + +public partial class ReverseProxyItem : ComponentBase +{ + /// + /// File path of the Caddy configuration file + /// + [Parameter] + public string FileName { get; set; } = string.Empty; + + private Task Edit() + { + return DialogService.ShowAsync(FileName, options: new DialogOptions + { + FullWidth = true, + MaxWidth = MaxWidth.Medium, + }, parameters: new DialogParameters + { + { "FileName", FileName } + }); + } +} \ No newline at end of file diff --git a/CaddyManager/Components/_Imports.razor b/CaddyManager/Components/_Imports.razor index 4be395c..d055408 100644 --- a/CaddyManager/Components/_Imports.razor +++ b/CaddyManager/Components/_Imports.razor @@ -8,4 +8,7 @@ @using Microsoft.JSInterop @using CaddyManager @using CaddyManager.Components -@using MudBlazor \ No newline at end of file +@using MudBlazor +@using BlazorMonaco +@using BlazorMonaco.Editor +@using BlazorMonaco.Languages \ No newline at end of file diff --git a/CaddyManager/Contracts/Caddy/ICaddyService.cs b/CaddyManager/Contracts/Caddy/ICaddyService.cs index 6b147f4..fdfbd12 100644 --- a/CaddyManager/Contracts/Caddy/ICaddyService.cs +++ b/CaddyManager/Contracts/Caddy/ICaddyService.cs @@ -10,4 +10,18 @@ public interface ICaddyService /// /// List GetExistingCaddyConfigurations(); + + /// + /// Method to get the content of a Caddy configuration file by its name + /// The expected path to be [ConfigDir]/[configurationName].caddy + /// + /// + /// + string GetCaddyConfigurationContent(string configurationName); + + /// + /// Method to get the content of the global Caddy configuration file + /// + /// + string GetCaddyGlobalConfigurationContent(); } \ No newline at end of file diff --git a/CaddyManager/Properties/launchSettings.json b/CaddyManager/Properties/launchSettings.json index 12cfcea..9720fdc 100644 --- a/CaddyManager/Properties/launchSettings.json +++ b/CaddyManager/Properties/launchSettings.json @@ -18,6 +18,12 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Blazor": { + "commandName": "Executable", + "workingDirectory": "$(ProjectDir)", + "executablePath": "/Users/ebolo/.dotnet/dotnet", + "commandLineArgs": "watch run debug --launch-profile http" } } } diff --git a/CaddyManager/Services/CaddyService.cs b/CaddyManager/Services/CaddyService.cs index 3a10322..afb5207 100644 --- a/CaddyManager/Services/CaddyService.cs +++ b/CaddyManager/Services/CaddyService.cs @@ -7,11 +7,37 @@ namespace CaddyManager.Services; /// public class CaddyService(IConfigurationsService configurationsService) : ICaddyService { - private CaddyServiceConfigurations _configurations => configurationsService.CaddyServiceConfigurations; + /// + /// File name of the global configuration Caddyfile + /// + public const string CaddyGlobalConfigName = "Caddyfile"; + + private CaddyServiceConfigurations Configurations => configurationsService.CaddyServiceConfigurations; /// public List GetExistingCaddyConfigurations() { - return Directory.GetFiles(_configurations.ConfigDir).ToList(); + return Directory.GetFiles(Configurations.ConfigDir) + .Where(filePath => Path.GetFileName(filePath) != CaddyGlobalConfigName) + .Select(Path.GetFileNameWithoutExtension) + .ToList()!; } + + /// + public string GetCaddyConfigurationContent(string configurationName) + { + var path = configurationName == CaddyGlobalConfigName + ? Path.Combine(Configurations.ConfigDir, CaddyGlobalConfigName) + : Path.Combine(Configurations.ConfigDir, $"{configurationName}.caddy"); + + if (File.Exists(path)) + { + return File.ReadAllText(path); + } + + return string.Empty; + } + + /// + public string GetCaddyGlobalConfigurationContent() => GetCaddyConfigurationContent(CaddyGlobalConfigName); } \ No newline at end of file diff --git a/CaddyManager/wwwroot/app.css b/CaddyManager/wwwroot/app.css index e69de29..d1d0997 100644 --- a/CaddyManager/wwwroot/app.css +++ b/CaddyManager/wwwroot/app.css @@ -0,0 +1,7 @@ +.caddy-file-editor { + height: 400px; +} + +.caddy-file-editor.global-caddy { + height: 600px; +} \ No newline at end of file