Fix dashboard static assets and add client e2e scripts

This commit is contained in:
Joseph Doherty
2026-04-27 12:10:40 -04:00
parent 3d11ac3316
commit d431ff9660
17 changed files with 794 additions and 11 deletions
@@ -8,7 +8,7 @@ public sealed class DashboardOptions
public bool RequireAdminScope { get; init; } = true;
public bool AllowAnonymousLocalhost { get; init; }
public bool AllowAnonymousLocalhost { get; init; } = true;
public int SnapshotIntervalMilliseconds { get; init; } = 1_000;
@@ -13,7 +13,7 @@
<body class="dashboard-body">
<Routes @rendermode="InteractiveServer" />
<script src="/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="_framework/blazor.web.js"></script>
<script src="/_framework/blazor.web.js"></script>
</body>
</html>
@@ -1,4 +1,5 @@
@page "/"
@page "/dashboard/"
@inherits DashboardPageBase
<PageTitle>MXAccess Gateway Dashboard</PageTitle>
@@ -1,4 +1,5 @@
@page "/events"
@page "/dashboard/events"
@inherits DashboardPageBase
<PageTitle>Dashboard Events</PageTitle>
@@ -1,4 +1,5 @@
@page "/sessions/{SessionId}"
@page "/dashboard/sessions/{SessionId}"
@inherits DashboardPageBase
<PageTitle>Dashboard Session</PageTitle>
@@ -1,4 +1,5 @@
@page "/sessions"
@page "/dashboard/sessions"
@inherits DashboardPageBase
<PageTitle>Dashboard Sessions</PageTitle>
@@ -1,4 +1,5 @@
@page "/settings"
@page "/dashboard/settings"
@inherits DashboardPageBase
<PageTitle>Dashboard Settings</PageTitle>
@@ -1,4 +1,5 @@
@page "/workers"
@page "/dashboard/workers"
@inherits DashboardPageBase
<PageTitle>Dashboard Workers</PageTitle>
+73 -1
View File
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
using MxGateway.Contracts;
using MxGateway.Server.Configuration;
using MxGateway.Server.Dashboard;
@@ -13,6 +14,8 @@ namespace MxGateway.Server;
public static class GatewayApplication
{
private const string StaticAssetsManifestFileName = "MxGateway.Server.staticwebassets.endpoints.json";
public static WebApplication Build(string[] args)
{
WebApplicationBuilder builder = CreateBuilder(args);
@@ -30,7 +33,12 @@ public static class GatewayApplication
public static WebApplicationBuilder CreateBuilder(string[] args)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
WebApplicationBuilder builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
ContentRootPath = ResolveContentRootPath(),
});
StaticWebAssetsLoader.UseStaticWebAssets(builder.Environment, builder.Configuration);
builder.Services.AddGatewayConfiguration();
builder.Services.AddSqliteAuthStore();
@@ -47,8 +55,65 @@ public static class GatewayApplication
return builder;
}
private static string ResolveContentRootPath()
{
string? configuredContentRootPath = Environment.GetEnvironmentVariable("ASPNETCORE_CONTENTROOT");
if (!string.IsNullOrWhiteSpace(configuredContentRootPath)
&& IsServerContentRoot(configuredContentRootPath))
{
return configuredContentRootPath;
}
string currentDirectory = Environment.CurrentDirectory;
if (IsServerContentRoot(currentDirectory))
{
return currentDirectory;
}
string baseDirectory = AppContext.BaseDirectory;
if (IsServerContentRoot(baseDirectory))
{
return baseDirectory;
}
string? discoveredContentRootPath = DiscoverServerContentRoot(currentDirectory)
?? DiscoverServerContentRoot(baseDirectory);
return discoveredContentRootPath ?? baseDirectory;
}
private static string? DiscoverServerContentRoot(string startPath)
{
DirectoryInfo? directory = new(startPath);
while (directory is not null)
{
if (IsServerContentRoot(directory.FullName))
{
return directory.FullName;
}
string serverProjectPath = Path.Combine(directory.FullName, "src", "MxGateway.Server");
if (IsServerContentRoot(serverProjectPath))
{
return serverProjectPath;
}
directory = directory.Parent;
}
return null;
}
private static bool IsServerContentRoot(string path)
{
return File.Exists(Path.Combine(path, "appsettings.json"))
&& Directory.Exists(Path.Combine(path, "wwwroot"));
}
public static IEndpointRouteBuilder MapGatewayEndpoints(this IEndpointRouteBuilder endpoints)
{
endpoints.MapStaticAssets(ResolveStaticAssetsManifestPath());
endpoints.MapGet("/", () => Results.Redirect("/health/live"));
endpoints.MapGet(
@@ -64,4 +129,11 @@ public static class GatewayApplication
return endpoints;
}
private static string ResolveStaticAssetsManifestPath()
{
string manifestPath = Path.Combine(AppContext.BaseDirectory, StaticAssetsManifestFileName);
return File.Exists(manifestPath) ? manifestPath : StaticAssetsManifestFileName;
}
}
+1 -1
View File
@@ -35,7 +35,7 @@
"Enabled": true,
"PathBase": "/dashboard",
"RequireAdminScope": true,
"AllowAnonymousLocalhost": false,
"AllowAnonymousLocalhost": true,
"SnapshotIntervalMilliseconds": 1000,
"RecentFaultLimit": 100,
"RecentSessionLimit": 200,
@@ -35,7 +35,7 @@ public sealed class GatewayOptionsTests
Assert.True(options.Dashboard.Enabled);
Assert.Equal("/dashboard", options.Dashboard.PathBase);
Assert.True(options.Dashboard.RequireAdminScope);
Assert.False(options.Dashboard.AllowAnonymousLocalhost);
Assert.True(options.Dashboard.AllowAnonymousLocalhost);
Assert.Equal(1_000, options.Dashboard.SnapshotIntervalMilliseconds);
Assert.Equal(100, options.Dashboard.RecentFaultLimit);
Assert.Equal(200, options.Dashboard.RecentSessionLimit);