feat: init the pages for reverse proxy configs and global configs
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<LangVersion>13</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -14,6 +15,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BlazorMonaco" Version="3.3.0" />
|
||||
<PackageReference Include="MudBlazor" Version="8.0.0" />
|
||||
<PackageReference Include="NetCore.AutoRegisterDi" Version="2.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
<body>
|
||||
<Routes @rendermode="InteractiveServer"/>
|
||||
<script src="_content/BlazorMonaco/jsInterop.js"></script>
|
||||
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -12,20 +12,11 @@
|
||||
|
||||
<MudLayout>
|
||||
<MudAppBar Elevation="1" Dense="true">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@ToggleDrawer" />
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@_drawer.ToggleDrawer" />
|
||||
<MudSpacer />
|
||||
<MudIconButton Icon="@Icons.Custom.Brands.GitHub" Color="Color.Inherit" Href="https://github.com/MudBlazor/MudBlazor" Target="_blank" />
|
||||
</MudAppBar>
|
||||
<MudDrawer @bind-Open="@_open" ClipMode="DrawerClipMode.Docked" Elevation="1" Variant="@DrawerVariant.Responsive">
|
||||
<MudDrawerHeader>
|
||||
<MudText Typo="Typo.h6">Caddy Manager</MudText>
|
||||
</MudDrawerHeader>
|
||||
<MudNavMenu>
|
||||
<MudNavLink Match="NavLinkMatch.All" Href="/">Reverse Proxies</MudNavLink>
|
||||
<MudNavLink Match="NavLinkMatch.All" Href="/caddyfile">Global Caddyfile</MudNavLink>
|
||||
<MudNavLink Match="NavLinkMatch.All" Href="/settings">Settings</MudNavLink>
|
||||
</MudNavMenu>
|
||||
</MudDrawer>
|
||||
<NavigationDrawer @ref="_drawer"/>
|
||||
<MudMainContent Class="pt-16 px-16">
|
||||
<MudContainer Class="mt-6">
|
||||
@Body
|
||||
@@ -33,11 +24,7 @@
|
||||
</MudMainContent>
|
||||
</MudLayout>
|
||||
|
||||
@code{
|
||||
private bool _open = false;
|
||||
|
||||
private void ToggleDrawer()
|
||||
{
|
||||
_open = !_open;
|
||||
}
|
||||
}
|
||||
@code
|
||||
{
|
||||
private NavigationDrawer _drawer = null!;
|
||||
}
|
||||
|
||||
10
CaddyManager/Components/Layout/NavigationDrawer.razor
Normal file
10
CaddyManager/Components/Layout/NavigationDrawer.razor
Normal file
@@ -0,0 +1,10 @@
|
||||
<MudDrawer @bind-Open="@_drawerOpen" ClipMode="DrawerClipMode.Docked" Elevation="1" Variant="@DrawerVariant.Responsive">
|
||||
<MudDrawerHeader>
|
||||
<MudText Typo="Typo.h6">Caddy Manager</MudText>
|
||||
</MudDrawerHeader>
|
||||
<MudNavMenu>
|
||||
<MudNavLink Match="NavLinkMatch.All" Href="/" Icon="@Icons.Custom.FileFormats.FileCode">Reverse Proxies</MudNavLink>
|
||||
<MudNavLink Match="NavLinkMatch.All" Href="/caddyfile" Icon="@Icons.Material.Filled.Language">Global Caddyfile</MudNavLink>
|
||||
<MudNavLink Match="NavLinkMatch.All" Href="/settings" Icon="@Icons.Material.Filled.Settings">Settings</MudNavLink>
|
||||
</MudNavMenu>
|
||||
</MudDrawer>
|
||||
13
CaddyManager/Components/Layout/NavigationDrawer.razor.cs
Normal file
13
CaddyManager/Components/Layout/NavigationDrawer.razor.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +1,24 @@
|
||||
@page "/caddyfile"
|
||||
@attribute [StreamRendering]
|
||||
@using CaddyManager.Contracts.Caddy
|
||||
@inject ICaddyService CaddyService
|
||||
|
||||
<PageTitle>Weather</PageTitle>
|
||||
<PageTitle>Global Caddyfile</PageTitle>
|
||||
|
||||
<h1>Weather</h1>
|
||||
|
||||
<p>This component demonstrates showing data.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th aria-label="Temperature in Celsius">Temp. (C)</th>
|
||||
<th aria-label="Temperature in Farenheit">Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
<MudCard>
|
||||
<MudCardHeader>
|
||||
<MudText Typo="Typo.h6">
|
||||
Global Caddyfile
|
||||
</MudText>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<StandaloneCodeEditor ConstructionOptions="@EditorConstructionOptions" CssClass="caddy-file-editor global-caddy"></StandaloneCodeEditor>
|
||||
<MudDivider/>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudContainer Class="d-flex flex-row-reverse flex-grow-1 gap-4">
|
||||
<MudButton Color="Color.Primary" OnClick="Submit">Save</MudButton>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
</MudContainer>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
|
||||
36
CaddyManager/Components/Pages/Caddyfile.razor.cs
Normal file
36
CaddyManager/Components/Pages/Caddyfile.razor.cs
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
@attribute [StreamRendering]
|
||||
@using CaddyManager.Contracts.Caddy
|
||||
@inject ICaddyService CaddyService
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<StandaloneCodeEditor ConstructionOptions="@EditorConstructionOptions" CssClass="caddy-file-editor"></StandaloneCodeEditor>
|
||||
<MudDivider/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
<MudButton Color="Color.Primary" OnClick="Submit">Save</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
@page "/"
|
||||
@using CaddyManager.Contracts.Caddy
|
||||
@inject ICaddyService CaddyService
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<MudList T="string">
|
||||
@foreach(var caddyConfig in _availableCaddyConfigurations)
|
||||
{
|
||||
<MudListItem Text="@caddyConfig" Icon="@Icons.Material.Filled.InsertDriveFile"/>
|
||||
<MudDivider/>
|
||||
}
|
||||
</MudList>
|
||||
|
||||
@code
|
||||
{
|
||||
List<string> _availableCaddyConfigurations = [];
|
||||
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
_availableCaddyConfigurations = CaddyService.GetExistingCaddyConfigurations();
|
||||
return base.OnInitializedAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
@page "/"
|
||||
@attribute [StreamRendering]
|
||||
@using CaddyManager.Contracts.Caddy
|
||||
@inject ICaddyService CaddyService
|
||||
|
||||
<PageTitle>Reverse proxy confiurations</PageTitle>
|
||||
|
||||
<MudList T="string">
|
||||
@foreach(var caddyConfig in _availableCaddyConfigurations)
|
||||
{
|
||||
<ReverseProxyItem FileName="@caddyConfig"/>
|
||||
<MudDivider/>
|
||||
}
|
||||
</MudList>
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace CaddyManager.Components.Pages.ReverseProxies;
|
||||
|
||||
public partial class ReverseProxiesPage
|
||||
{
|
||||
private List<string> _availableCaddyConfigurations = [];
|
||||
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
_availableCaddyConfigurations = CaddyService.GetExistingCaddyConfigurations();
|
||||
return base.OnInitializedAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@using CaddyManager.Contracts.Caddy
|
||||
@attribute [StreamRendering]
|
||||
@inject ICaddyService CaddyService
|
||||
@inject IDialogService DialogService
|
||||
|
||||
<MudListItem Text="@FileName" Icon="@Icons.Material.Filled.InsertDriveFile" T="string" OnClick="Edit"/>
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
|
||||
namespace CaddyManager.Components.Pages.ReverseProxies;
|
||||
|
||||
public partial class ReverseProxyItem : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// File path of the Caddy configuration file
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
|
||||
private Task Edit()
|
||||
{
|
||||
return DialogService.ShowAsync<CaddyfileEditor.CaddyfileEditor>(FileName, options: new DialogOptions
|
||||
{
|
||||
FullWidth = true,
|
||||
MaxWidth = MaxWidth.Medium,
|
||||
}, parameters: new DialogParameters
|
||||
{
|
||||
{ "FileName", FileName }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,7 @@
|
||||
@using Microsoft.JSInterop
|
||||
@using CaddyManager
|
||||
@using CaddyManager.Components
|
||||
@using MudBlazor
|
||||
@using MudBlazor
|
||||
@using BlazorMonaco
|
||||
@using BlazorMonaco.Editor
|
||||
@using BlazorMonaco.Languages
|
||||
@@ -10,4 +10,18 @@ public interface ICaddyService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<string> GetExistingCaddyConfigurations();
|
||||
|
||||
/// <summary>
|
||||
/// Method to get the content of a Caddy configuration file by its name
|
||||
/// The expected path to be [ConfigDir]/[configurationName].caddy
|
||||
/// </summary>
|
||||
/// <param name="configurationName"></param>
|
||||
/// <returns></returns>
|
||||
string GetCaddyConfigurationContent(string configurationName);
|
||||
|
||||
/// <summary>
|
||||
/// Method to get the content of the global Caddy configuration file
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetCaddyGlobalConfigurationContent();
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,37 @@ namespace CaddyManager.Services;
|
||||
/// <inheritdoc />
|
||||
public class CaddyService(IConfigurationsService configurationsService) : ICaddyService
|
||||
{
|
||||
private CaddyServiceConfigurations _configurations => configurationsService.CaddyServiceConfigurations;
|
||||
/// <summary>
|
||||
/// File name of the global configuration Caddyfile
|
||||
/// </summary>
|
||||
public const string CaddyGlobalConfigName = "Caddyfile";
|
||||
|
||||
private CaddyServiceConfigurations Configurations => configurationsService.CaddyServiceConfigurations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public List<string> GetExistingCaddyConfigurations()
|
||||
{
|
||||
return Directory.GetFiles(_configurations.ConfigDir).ToList();
|
||||
return Directory.GetFiles(Configurations.ConfigDir)
|
||||
.Where(filePath => Path.GetFileName(filePath) != CaddyGlobalConfigName)
|
||||
.Select(Path.GetFileNameWithoutExtension)
|
||||
.ToList()!;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCaddyGlobalConfigurationContent() => GetCaddyConfigurationContent(CaddyGlobalConfigName);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
.caddy-file-editor {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.caddy-file-editor.global-caddy {
|
||||
height: 600px;
|
||||
}
|
||||
Reference in New Issue
Block a user