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
-{
-
-
-
- | Date |
- Temp. (C) |
- Temp. (F) |
- Summary |
-
-
-
- @foreach (var forecast in forecasts)
- {
-
- | @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