Fix: enable global interactivity so dialogs/selects actually work
ci / build-test (push) Successful in 1m12s

Editing a meter (any admin dialog, select dropdown, snackbar, dark-mode toggle)
did nothing: pages declared @rendermode InteractiveServer individually, but
MainLayout — which hosts MudDialogProvider/MudPopoverProvider/MudSnackbarProvider
— was rendered by <Routes>, which was static. Inline MudDialogs and MudSelect
popovers render through those providers, so with the providers non-interactive no
dialog could ever open.

Set the render mode on <Routes> and <HeadOutlet> in App.razor (global
interactivity) and removed the now-redundant per-page @rendermode declarations
(they would otherwise throw "parent already has a render mode").

Why it slipped through: the integration render tests only issue a GET (static
prerender), which never exercises the SignalR circuit. Verified this fix with a
real headless-browser run (Playwright): the meter edit dialog opens and the
"Sub-meter of (upstream meters)" multi-select opens with options — proving the
layout providers are now interactive. 116 tests still green.

Claude-Session: https://claude.ai/code/session_01Lz2RqAsnQhetqWNoCDfexK
This commit is contained in:
2026-07-14 14:22:15 +02:00
parent 7e34aeccc8
commit 85d650a8f5
14 changed files with 2 additions and 15 deletions
+2 -2
View File
@@ -10,11 +10,11 @@
<link rel="stylesheet" href="_content/MudBlazor/MudBlazor.min.css" /> <link rel="stylesheet" href="_content/MudBlazor/MudBlazor.min.css" />
<link rel="stylesheet" href="@Assets["MeterVault.App.styles.css"]" /> <link rel="stylesheet" href="@Assets["MeterVault.App.styles.css"]" />
<ImportMap /> <ImportMap />
<HeadOutlet /> <HeadOutlet @rendermode="InteractiveServer" />
</head> </head>
<body> <body>
<Routes /> <Routes @rendermode="InteractiveServer" />
<ReconnectModal /> <ReconnectModal />
<script src="@Assets["_framework/blazor.web.js"]"></script> <script src="@Assets["_framework/blazor.web.js"]"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script> <script src="_content/MudBlazor/MudBlazor.min.js"></script>
@@ -1,5 +1,4 @@
@page "/admin/categories" @page "/admin/categories"
@rendermode InteractiveServer
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
@inject IDialogService DialogService @inject IDialogService DialogService
@@ -1,5 +1,4 @@
@page "/admin/connectors" @page "/admin/connectors"
@rendermode InteractiveServer
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
@inject MeterVault.Infrastructure.Ingestion.HaConnectionTester HaTester @inject MeterVault.Infrastructure.Ingestion.HaConnectionTester HaTester
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
@@ -1,5 +1,4 @@
@page "/admin/energy-types" @page "/admin/energy-types"
@rendermode InteractiveServer
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
@inject IDialogService DialogService @inject IDialogService DialogService
@@ -1,5 +1,4 @@
@page "/admin/settings" @page "/admin/settings"
@rendermode InteractiveServer
@inject Microsoft.Extensions.Options.IOptions<MeterVault.Infrastructure.Options.MeterVaultOptions> Options @inject Microsoft.Extensions.Options.IOptions<MeterVault.Infrastructure.Options.MeterVaultOptions> Options
@using MudBlazor @using MudBlazor
@@ -1,5 +1,4 @@
@page "/admin/tariffs" @page "/admin/tariffs"
@rendermode InteractiveServer
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
@inject IDialogService DialogService @inject IDialogService DialogService
@@ -1,5 +1,4 @@
@page "/consumables" @page "/consumables"
@rendermode InteractiveServer
@inject ConsumableService ConsumablesSvc @inject ConsumableService ConsumablesSvc
@using MudBlazor @using MudBlazor
-1
View File
@@ -1,5 +1,4 @@
@page "/" @page "/"
@rendermode InteractiveServer
@inject DashboardService Dash @inject DashboardService Dash
<PageTitle>MeterVault — Overview</PageTitle> <PageTitle>MeterVault — Overview</PageTitle>
@@ -1,5 +1,4 @@
@page "/energy/{Id:int}" @page "/energy/{Id:int}"
@rendermode InteractiveServer
@inject FlowService Flow @inject FlowService Flow
@inject MeterVault.Infrastructure.Costing.CostService Costs @inject MeterVault.Infrastructure.Costing.CostService Costs
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
-1
View File
@@ -1,5 +1,4 @@
@page "/import" @page "/import"
@rendermode InteractiveServer
@inject MeterVault.Infrastructure.Import.ReferenceDataImporter ReferenceImporter @inject MeterVault.Infrastructure.Import.ReferenceDataImporter ReferenceImporter
@inject MeterVault.Infrastructure.Import.CsvImporter CsvImporter @inject MeterVault.Infrastructure.Import.CsvImporter CsvImporter
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
@@ -1,5 +1,4 @@
@page "/meters/{Id:int}" @page "/meters/{Id:int}"
@rendermode InteractiveServer
@inject MeterDetailService Details @inject MeterDetailService Details
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
-1
View File
@@ -1,5 +1,4 @@
@page "/meters" @page "/meters"
@rendermode InteractiveServer
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory @inject Microsoft.EntityFrameworkCore.IDbContextFactory<MeterVault.Infrastructure.Persistence.MeterVaultDbContext> DbFactory
@inject MeterVault.Core.Normalization.INormalizationEngine Engine @inject MeterVault.Core.Normalization.INormalizationEngine Engine
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
-1
View File
@@ -1,5 +1,4 @@
@page "/solar" @page "/solar"
@rendermode InteractiveServer
@inject SolarService SolarSvc @inject SolarService SolarSvc
@using MudBlazor @using MudBlazor
-1
View File
@@ -1,5 +1,4 @@
@page "/trends" @page "/trends"
@rendermode InteractiveServer
@inject DashboardService Dash @inject DashboardService Dash
<PageTitle>MeterVault — Trends</PageTitle> <PageTitle>MeterVault — Trends</PageTitle>