Migrate dashboard to Fluent UI Blazor v5 - #19431
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19431Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19431" |
There was a problem hiding this comment.
Pull request overview
Migrates the Aspire Dashboard to Fluent UI Blazor v5 and .NET 9 while updating component behavior, styling, dialogs, navigation, and tests.
Changes:
- Updates Fluent UI packages and Dashboard targets.
- Migrates removed v4 component APIs and introduces shared layout/dialog services.
- Adds and updates bUnit and Playwright regression coverage.
Reviewed changes
Copilot reviewed 177 out of 177 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
tests/Shared/TestCertificateLoader.cs |
Uses modern certificate loading. |
tests/Shared/Telemetry/TelemetryTestHelpers.cs |
Updates PKCS#12 loading. |
tests/Aspire.Dashboard.Tests/Model/ResourceStateViewModelTests.cs |
Updates expected icon color. |
tests/Aspire.Dashboard.Tests/Integration/StartupTests.cs |
Adjusts CSP assertion. |
tests/Aspire.Dashboard.Tests/Integration/ResponseCompressionTests.cs |
Tests new stylesheet. |
tests/Aspire.Dashboard.Tests/Integration/Playwright/TracesLayoutTests.cs |
Tests duration indicators. |
tests/Aspire.Dashboard.Tests/Integration/Playwright/ResourcesTests.cs |
Adds graph layout coverage. |
tests/Aspire.Dashboard.Tests/Integration/Playwright/ResourceSelectInteractionTests.cs |
Tests selector interaction. |
tests/Aspire.Dashboard.Tests/Integration/Playwright/DesktopNavMenuTests.cs |
Tests navigation persistence. |
tests/Aspire.Dashboard.Tests/Integration/Playwright/DashboardInteractionsTests.cs |
Updates resize-handle detection. |
tests/Aspire.Dashboard.Tests/Integration/Playwright/AspireMenuButtonFocusTests.cs |
Updates menu focus test. |
tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj |
Targets .NET 9. |
tests/Aspire.Dashboard.Components.Tests/Shared/TestMessageService.cs |
Removes obsolete test service. |
tests/Aspire.Dashboard.Components.Tests/Pages/TraceDetailsTests.cs |
Updates toolbar/grid assertions. |
tests/Aspire.Dashboard.Components.Tests/Pages/ResourcesTests.cs |
Migrates component interactions. |
tests/Aspire.Dashboard.Components.Tests/Pages/MetricsTests.cs |
Adds tree-selection coverage. |
tests/Aspire.Dashboard.Components.Tests/Pages/LoginTests.cs |
Updates login rendering setup. |
tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTerminalTests.cs |
Migrates selectors and search. |
tests/Aspire.Dashboard.Components.Tests/Layout/MobileNavMenuTests.cs |
Updates navigation assertion comment. |
tests/Aspire.Dashboard.Components.Tests/Dialogs/ManageDataDialogTests.cs |
Stabilizes dialog tests. |
tests/Aspire.Dashboard.Components.Tests/Dialogs/InteractionsInputDialogTests.cs |
Migrates dialog test infrastructure. |
tests/Aspire.Dashboard.Components.Tests/Dialogs/FilterDialogTests.cs |
Updates v5 input assertions. |
tests/Aspire.Dashboard.Components.Tests/Controls/UrlsColumnDisplayTests.cs |
Updates overflow assertions. |
tests/Aspire.Dashboard.Components.Tests/Controls/ResourceSelectTests.cs |
Adds selector display test. |
tests/Aspire.Dashboard.Components.Tests/Controls/ResourceDetailsTests.cs |
Updates menu ownership tests. |
tests/Aspire.Dashboard.Components.Tests/Controls/AspireMenuTests.cs |
Migrates menu behavior tests. |
tests/Aspire.Dashboard.Components.Tests/Controls/AspireMenuButtonTests.cs |
Updates menu-button tests. |
tests/Aspire.Dashboard.Components.Tests/Aspire.Dashboard.Components.Tests.csproj |
Targets .NET 9. |
src/Aspire.Dashboard/wwwroot/js/app.js |
Migrates grid resize handling. |
src/Aspire.Dashboard/wwwroot/css/markdown.css |
Replaces removed font token. |
src/Aspire.Dashboard/wwwroot/css/layout.css |
Adds shared v5 layout styles. |
src/Aspire.Dashboard/Utils/DashboardUIHelpers.cs |
Migrates message bars. |
src/Aspire.Dashboard/ServiceClient/DashboardClient.cs |
Modernizes certificate loading. |
src/Aspire.Dashboard/Otlp/Storage/TelemetryRepository.cs |
Stores new message references. |
src/Aspire.Dashboard/Model/TraceLinkHelpers.cs |
Migrates message-box dialogs. |
src/Aspire.Dashboard/Model/ThemeManager.cs |
Updates theme documentation. |
src/Aspire.Dashboard/Model/ResourceStateViewModel.cs |
Updates default icon color. |
src/Aspire.Dashboard/Model/MenuButtonItem.cs |
Migrates roles and IDs. |
src/Aspire.Dashboard/Model/Interaction/InteractionMessageBoxContent.cs |
Adds message-box content model. |
src/Aspire.Dashboard/Model/Interaction/InputViewModel.cs |
Updates input terminology. |
src/Aspire.Dashboard/Model/INotificationService.cs |
Migrates notification intent. |
src/Aspire.Dashboard/Model/DashboardMessageBarService.cs |
Adds message-bar abstraction. |
src/Aspire.Dashboard/Model/DashboardDialogParameters.cs |
Adds dialog abstractions. |
src/Aspire.Dashboard/Extensions/ComponentExtensions.cs |
Forces grid refreshes. |
src/Aspire.Dashboard/DashboardWebApplication.cs |
Registers migrated services. |
src/Aspire.Dashboard/Configuration/DashboardOptions.cs |
Modernizes certificate loading. |
src/Aspire.Dashboard/Components/ResourcesGridColumns/UrlsColumnDisplay.razor |
Migrates overflow/popover APIs. |
src/Aspire.Dashboard/Components/ResourcesGridColumns/UnreadLogErrorsBadge.razor |
Migrates badge and link. |
src/Aspire.Dashboard/Components/ResourcesGridColumns/ResourceNameDisplay.razor |
Updates icon color. |
src/Aspire.Dashboard/Components/ResourcesGridColumns/LogMessageColumnDisplay.razor |
Migrates button appearance. |
src/Aspire.Dashboard/Components/Pages/Traces.razor.css |
Styles determinate progress bars. |
src/Aspire.Dashboard/Components/Pages/Traces.razor.cs |
Migrates grid and dialogs. |
src/Aspire.Dashboard/Components/Pages/TraceDetail.razor.css |
Updates trace-detail layout. |
src/Aspire.Dashboard/Components/Pages/TraceDetail.razor.cs |
Migrates dialog results. |
src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor.css |
Stabilizes grid layout. |
src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor.cs |
Migrates message and grid APIs. |
src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor |
Rebuilds filter toolbar. |
src/Aspire.Dashboard/Components/Pages/Resources.razor.css |
Updates responsive toolbar layout. |
src/Aspire.Dashboard/Components/Pages/Resources.razor.cs |
Migrates tab lifecycle handling. |
src/Aspire.Dashboard/Components/Pages/Metrics.razor |
Migrates selectors and splitter. |
src/Aspire.Dashboard/Components/Pages/Login.razor.cs |
Migrates text-input focus. |
src/Aspire.Dashboard/Components/Pages/Login.razor |
Migrates login controls. |
src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs |
Migrates menu roles. |
src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor |
Rebuilds console toolbar. |
src/Aspire.Dashboard/Components/Layout/ToolbarPanel.razor |
Migrates mobile toolbar. |
src/Aspire.Dashboard/Components/Layout/ReconnectModal.razor |
Updates button appearances. |
src/Aspire.Dashboard/Components/Layout/NotificationsHeaderButton.razor |
Migrates notification controls. |
src/Aspire.Dashboard/Components/Layout/MobileNavMenu.razor |
Migrates mobile menu rendering. |
src/Aspire.Dashboard/Components/Layout/MainLayout.razor.cs |
Migrates themes and dialogs. |
src/Aspire.Dashboard/Components/Layout/DesktopToolbarDivider.razor |
Removes obsolete slot. |
src/Aspire.Dashboard/Components/Layout/AspirePageContentLayout.razor.css |
Stabilizes page layout. |
src/Aspire.Dashboard/Components/Layout/AspirePageContentLayout.razor.cs |
Migrates toolbar dialog reference. |
src/Aspire.Dashboard/Components/Layout/AspirePageContentLayout.razor |
Replaces Fluent toolbars. |
src/Aspire.Dashboard/Components/Dialogs/TextVisualizerDialog.razor.cs |
Migrates dialog reference. |
src/Aspire.Dashboard/Components/Dialogs/TextVisualizerDialog.razor |
Migrates dialog content. |
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs |
Migrates dialog instance. |
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor |
Migrates language selector. |
src/Aspire.Dashboard/Components/Dialogs/NotificationsDialog.razor.cs |
Migrates notification dialog. |
src/Aspire.Dashboard/Components/Dialogs/NotificationsDialog.razor |
Updates v5 appearances. |
src/Aspire.Dashboard/Components/Dialogs/NotificationEntryComponent.razor.cs |
Migrates intents and actions. |
src/Aspire.Dashboard/Components/Dialogs/NotificationEntryComponent.razor |
Updates notification controls. |
src/Aspire.Dashboard/Components/Dialogs/ManageDataDialog.razor.cs |
Removes obsolete interface. |
src/Aspire.Dashboard/Components/Dialogs/ManageDataDialog.razor |
Migrates grid and buttons. |
src/Aspire.Dashboard/Components/Dialogs/InteractionsProgressDialog.razor.cs |
Migrates dialog instance. |
src/Aspire.Dashboard/Components/Dialogs/InteractionsProgressDialog.razor |
Migrates progress dialog UI. |
src/Aspire.Dashboard/Components/Dialogs/InteractionsInputDialog.razor.cs |
Migrates input references. |
src/Aspire.Dashboard/Components/Dialogs/InteractionMessageBoxDialog.razor |
Adds message-box component. |
src/Aspire.Dashboard/Components/Dialogs/HelpDialog.razor |
Replaces Fluent anchor. |
src/Aspire.Dashboard/Components/Dialogs/GenAIVisualizerDialog.razor.cs |
Migrates nullable tab events. |
src/Aspire.Dashboard/Components/Dialogs/FilterDialog.razor.cs |
Migrates dialog instance. |
src/Aspire.Dashboard/Components/Dialogs/FilterDialog.razor |
Migrates filter controls. |
src/Aspire.Dashboard/Components/Dialogs/ExemplarsDialog.razor |
Updates button appearance. |
src/Aspire.Dashboard/Components/Dialogs/AIAgentsDialog.razor.cs |
Removes obsolete interface. |
src/Aspire.Dashboard/Components/Dialogs/AIAgentsDialog.razor |
Migrates dialog header. |
src/Aspire.Dashboard/Components/Controls/UserProfile.razor |
Replaces removed profile menu. |
src/Aspire.Dashboard/Components/Controls/TreeMetricSelector.razor.cs |
Adds tree state management. |
src/Aspire.Dashboard/Components/Controls/TreeMetricSelector.razor |
Migrates metric tree selection. |
src/Aspire.Dashboard/Components/Controls/TreeGenAISelector.razor.cs |
Adds stable tree IDs. |
src/Aspire.Dashboard/Components/Controls/TreeGenAISelector.razor |
Migrates GenAI tree selection. |
src/Aspire.Dashboard/Components/Controls/TraceActions.razor |
Updates menu appearance. |
src/Aspire.Dashboard/Components/Controls/SummaryDetailsView.razor.cs |
Migrates splitter state. |
src/Aspire.Dashboard/Components/Controls/SummaryDetailsView.razor |
Migrates multi-splitter markup. |
src/Aspire.Dashboard/Components/Controls/StructuredLogDetails.razor |
Rebuilds details toolbar. |
src/Aspire.Dashboard/Components/Controls/StructuredLogActions.razor |
Updates menu appearance. |
src/Aspire.Dashboard/Components/Controls/SpanTypeSelect.razor |
Migrates span selector. |
src/Aspire.Dashboard/Components/Controls/SpanDetails.razor.cs |
Removes obsolete grid labels. |
src/Aspire.Dashboard/Components/Controls/SpanActions.razor |
Updates menu appearance. |
src/Aspire.Dashboard/Components/Controls/ResourceSelectOptionTemplate.razor |
Fixes pointer interaction. |
src/Aspire.Dashboard/Components/Controls/ResourceSelect.razor.cs |
Removes obsolete binding workaround. |
src/Aspire.Dashboard/Components/Controls/ResourceSelect.razor |
Migrates resource selector. |
src/Aspire.Dashboard/Components/Controls/ResourceDetails.razor.cs |
Removes obsolete grid labels. |
src/Aspire.Dashboard/Components/Controls/ResourceActions.razor.css |
Replaces removed spacing tokens. |
src/Aspire.Dashboard/Components/Controls/ResourceActions.razor |
Updates action appearances. |
src/Aspire.Dashboard/Components/Controls/PropertyValues/TraceIdButtonValue.razor |
Updates link-button appearance. |
src/Aspire.Dashboard/Components/Controls/PropertyValues/SpanKindValue.razor |
Updates icon color. |
src/Aspire.Dashboard/Components/Controls/PropertyValues/SpanIdButtonValue.razor |
Updates link-button appearance. |
src/Aspire.Dashboard/Components/Controls/PropertyValues/ResourceNameButtonValue.razor |
Updates link-button appearance. |
src/Aspire.Dashboard/Components/Controls/PropertyValues/IconValue.razor |
Updates icon color. |
src/Aspire.Dashboard/Components/Controls/PropertyGrid.razor.cs |
Migrates generated-header API. |
src/Aspire.Dashboard/Components/Controls/PropertyGrid.razor |
Removes obsolete grid labels. |
src/Aspire.Dashboard/Components/Controls/PauseIncomingDataSwitch.razor |
Updates button appearance. |
src/Aspire.Dashboard/Components/Controls/LogLevelSelect.razor |
Migrates log-level selector. |
src/Aspire.Dashboard/Components/Controls/InteractionInputField.razor.cs |
Removes Fluent base class. |
src/Aspire.Dashboard/Components/Controls/InteractionInputField.razor |
Migrates labels and spinner. |
src/Aspire.Dashboard/Components/Controls/IconCheckbox.razor.cs |
Updates unchecked icon color. |
src/Aspire.Dashboard/Components/Controls/GridValue.razor |
Updates action appearances. |
src/Aspire.Dashboard/Components/Controls/Grid/AspireTemplateColumn.cs |
Removes redundant column ID. |
src/Aspire.Dashboard/Components/Controls/Grid/AspirePropertyColumn.cs |
Removes redundant column ID. |
src/Aspire.Dashboard/Components/Controls/FluentIconSwitch.razor |
Migrates appearance type. |
src/Aspire.Dashboard/Components/Controls/ExceptionDetails.razor |
Updates button and icon. |
src/Aspire.Dashboard/Components/Controls/DetailView.razor |
Updates header actions. |
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor |
Adds message-bar renderer. |
src/Aspire.Dashboard/Components/Controls/ClearSignalsButton.razor |
Migrates clear menu styling. |
src/Aspire.Dashboard/Components/Controls/Chart/MetricTable.razor |
Updates exemplar button. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartFilterTags.razor.cs |
Removes obsolete overflow metadata. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartFilterTags.razor |
Migrates overflow templates. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartFilters.razor |
Migrates generated-header API. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartFilterPopover.razor |
Migrates popover controls. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartContainer.razor.cs |
Migrates tab lifecycle. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartContainer.razor |
Migrates chart tabs. |
src/Aspire.Dashboard/Components/Controls/AspireMenuButton.razor.cs |
Migrates component lifecycle. |
src/Aspire.Dashboard/Components/Controls/AspireMenuButton.razor |
Restores expanded-state ARIA. |
src/Aspire.Dashboard/Components/Controls/AspireMenu.razor.cs |
Migrates menu state handling. |
src/Aspire.Dashboard/Components/Controls/AspireMenu.razor |
Migrates menu APIs. |
src/Aspire.Dashboard/Components/BlazorScript.razor |
Updates target documentation. |
src/Aspire.Dashboard/Components/App.razor |
Replaces legacy global styles. |
src/Aspire.Dashboard/BlazorAssets.targets |
Updates assets and synchronization. |
src/Aspire.Dashboard/Aspire.Dashboard.csproj |
Targets .NET 9. |
eng/dashboardpack/Common.projitems |
Packages Dashboard for .NET 9. |
Directory.Packages.props |
Updates Fluent UI packages. |
Directory.Build.props |
Updates Dashboard artifact path. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 179 out of 179 changed files in this pull request and generated no new comments.
Suppressed comments (5)
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor:26
TOptionis specified twice on the same component. Razor reports duplicate component parameters, so the Dashboard project cannot compile until the second attribute is removed.
src/Aspire.Dashboard/Components/Pages/Login.razor:26FluentTextInputv5 usesTextInputType;TextFieldTypeis no longer a component parameter and is emitted only as an unmatched HTML attribute. The underlying input therefore remains a plain text input and exposes the dashboard token instead of masking it.
tests/Aspire.Dashboard.Tests/Integration/Playwright/ResourcesTests.cs:116- This test navigates directly to the Graph URL, so it never exercises the tab switch or
ActiveTabChanged. It would still pass if clicking Graph caused a full reload or failed to update the layout. Start on the table view, record the navigation count, clickgraphTab, and then assert the graph and unchanged count.
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor:34 - This introduces an unlocalized visible label and accessible name. Dashboard notification actions already localize the equivalent text via
Dialogs.NotificationEntryDismiss(seeComponents/Dialogs/NotificationEntryComponent.razor:18); inject the dialog localizer here and use a resource string for both values.
@if (Content.AllowDismiss)
{
<FluentButton OnClick="@(() => CloseAsync(null))" aria-label="Dismiss">Dismiss</FluentButton>
}
src/Aspire.Dashboard/Components/Controls/AspireMenu.razor.cs:132
- The edge calculation reserves only 200px, but this menu is allowed to grow to 368px below. Near the right viewport edge, a menu wider than 200px is positioned at
clientX - 200and can overflow by up to 168px. Use the same maximum width for placement (or measure the rendered menu).
const int estimatedMenuWidth = 200;
_targetOffsetLeft = clientX + estimatedMenuWidth > screenWidth
? Math.Max(0, clientX - estimatedMenuWidth)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 179 out of 179 changed files in this pull request and generated no new comments.
Suppressed comments (5)
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor:25
TOptionis specified again on the next line. Razor rejects duplicate component parameters, so the Dashboard project will not compile until the duplicate is removed.
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor:33- This newly rendered button text and accessible name are hardcoded in English, so message-bar dismissal is not localized. Use the existing localized dismissal resource (for example, the pattern in
Components/Dialogs/NotificationEntryComponent.razor:18) for both the label and visible text.
<FluentButton OnClick="@(() => CloseAsync(null))" aria-label="Dismiss">Dismiss</FluentButton>
src/Aspire.Dashboard/wwwroot/css/layout.css:64
- The removed legacy stylesheets were the only source of the
--layout-left-paddingand--layout-right-paddingcustom properties; no definitions remain insrc/Aspire.Dashboard. Consequently this entirepaddingdeclaration is invalid at computed-value time, and the migrated toolbars lose their page gutters. Define the layout variables in this shared stylesheet (including--layout-top-padding, which is still used elsewhere) or replace all remaining uses with concrete values.
Directory.Build.props:58 - The target-framework migration leaves the CLI's generated in-repo AppHost project pointing at
artifacts/bin/Aspire.Dashboard/Debug/net8.0/insrc/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs:156. Since this project now emits undernet9.0, CLI local-development launches will receive a nonexistent dashboard directory. Update that hardcoded path as part of this migration.
<AspireDashboardDir>$(MSBuildThisFileDirectory)/artifacts/bin/Aspire.Dashboard/$(Configuration)/net9.0/</AspireDashboardDir>
src/Aspire.Dashboard/Components/Pages/Login.razor:47
Appearanceis a Fluent component parameter, but this element is now a native<a>. The browser only receives an inertAppearance="ButtonAppearance.Subtle"attribute, so the intended link appearance is not applied. Use a CSS class supported by the native anchor (or a supported Fluent link component) instead.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 180 out of 180 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor:26
TOptionis specified twice on this component, which causes Razor's duplicate-parameter diagnostic and prevents the Dashboard project from compiling. Keep the v5TOption/TValuepair and remove the secondTOption.
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor:34- The new dismiss control hard-codes an English user-facing label, so localized Dashboard sessions now show untranslated text. Use the existing localized
Dialogs.NotificationEntryDismissresource, asNotificationEntryComponent.razor:17-20already does for the equivalent action.
@if (Content.AllowDismiss)
{
<FluentButton OnClick="@(() => CloseAsync(null))" aria-label="Dismiss">Dismiss</FluentButton>
}
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor:8
- This renders
Titleas plain text, butInteractionsProviderstill passesWebUtility.HtmlEncode(item.Title). Blazor therefore encodes the value a second time, so titles containing&,<, or similar characters display HTML entities to users. DefineTitleas plain text and stop pre-encoding that caller (while retaining encoding/sanitization for markup message bodies).
@if (!string.IsNullOrEmpty(Content.Title))
{
<strong>@Content.Title</strong>
}
b92343e to
09dbfbc
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 180 out of 180 changed files in this pull request and generated no new comments.
Suppressed comments (6)
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor:26
TOptionis specified twice on the same component, which causes Razor's duplicate-attribute diagnostic and prevents the dashboard project from building. Keep only the declaration that also addsTValue.
src/Aspire.Dashboard/Components/Pages/Login.razor:26FluentTextInputv5 exposesTextInputType, notTextFieldType. Because unmatched attributes are forwarded, this silently leaves the login token control as a normal text input, exposing the authentication token on screen instead of masking it.
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor:33- The newly rendered button text and accessible name are hard-coded, so localized dashboard sessions now show English here. Dashboard controls consistently source user-facing labels from resources (for example,
NotificationEntryComponent.razor:18-20), andDialogs.NotificationEntryDismissalready provides the appropriate localized label.
<FluentButton OnClick="@(() => CloseAsync(null))" aria-label="Dismiss">Dismiss</FluentButton>
src/Aspire.Dashboard/wwwroot/css/layout.css:64
- This padding declaration now depends on
--layout-left-paddingand--layout-right-padding, but neither custom property is defined anywhere in the loaded dashboard styles aftertokens.css/app.csswere removed. Browsers therefore discard the whole declaration, and the shared desktop toolbars lose their intended page gutters. Define these layout tokens inlayout.css(also covering the remaining component CSS references) or replace the references with concrete values.
src/Aspire.Dashboard/Components/Controls/UserProfile.razor:8 - The replacement
<details>content has no positioning styles: the remainingUserProfile.razor.cssrules target the removed Fluent profile/persona elements and there are no rules fordetailsorsummary. Opening the profile therefore inserts the account panel into normal header flow instead of displaying a popup, expanding and shifting the dashboard header. Add popup/trigger styling for the new markup or replace it with a v5 popover/menu component.
src/Aspire.Dashboard/Components/Controls/DashboardMessageBar.razor:7 - This renders
Titleas ordinary Razor text, but interaction notifications passWebUtility.HtmlEncode(item.Title). Razor encodes that value again, so titles containing&,<, or similar characters are displayed as HTML entities. Keep this safe text rendering and stop pre-encoding the title at the interaction caller.
<strong>@Content.Title</strong>
09dbfbc to
af1cf19
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 185 out of 185 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
src/Aspire.Dashboard/Components/ResourcesGridColumns/UrlsColumnDisplay.razor:24
MaxRenderedItemsonly limits how many overflow records Fluent returns to Blazor; it does not limit these DOM children. Iterating every URL here therefore restores the hundreds-of-elements layout/reflow path that the removedTake(20)explicitly avoided, including the SignalR disconnect regression. Keep the child list capped and add the unrendered remainder back into the badge/popover calculation.
src/Aspire.Dashboard/Components/Controls/Chart/ChartFilterTags.razor:17MaxRenderedItemslimits only the overflow metadata returned to Blazor, not the number of child elements rendered. This loop now puts every dimension value into the DOM, reintroducing the expensive layout behavior that the removedTake(MaxRenderedTags)guarded against for high-cardinality metrics. Cap the rendered values and account for the remaining values in the badge/selection logic.
@foreach (var item in orderedValues)
{
var isIncludedInFilters = Filter.SelectedValues.Contains(item);
var isIncludedInFiltersClass = isIncludedInFilters ? "included-in-filters" : "";
// Always display the first item by setting a fixed value.
<div behavior="@(i == 0 ? "fixed" : null)">
src/Aspire.Dashboard/Components/Controls/AspireMenu.razor:56
FluentMenuItemalready wraps itsMenuItemsfragment in aFluentMenuListfor the submenu slot. Returning anotherFluentMenuListhere produces nested menu-list elements, so resource URL/command submenus no longer have the direct menu-item structure expected by Fluent and can break submenu interaction and keyboard navigation. Return only the nested items from this fragment.
return @<FluentMenuList>
@foreach (var nestedItem in item.NestedMenuItems)
{
@RenderMenuItem(nestedItem)
}
src/Aspire.Dashboard/Components/Controls/UserProfile.razor:9
- The replacement is rendered inside a 52px header whose CSS sets
overflow: hidden, while the existing profile CSS only targets the removed Fluent profile-menu elements. Native<details>keeps this<div>in the header's normal flow, so expanding it clips the account details and sign-out action instead of displaying a popup. Add a properly positioned/light-dismiss profile surface outside the clipped header (and update the obsolete profile CSS).
af1cf19 to
ba890c1
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 187 out of 187 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/Aspire.Dashboard/Components/Layout/AspirePageContentLayout.razor.cs:101
- This closing callback now runs for every completed dialog result, including
DashboardDialogReference.CloseAsync().CloseMobileToolbarAsync()still invokes the same listeners manually after callingCloseAsync, so programmatic closure (for example when switching to desktop) notifies every listener twice. Await the reference result and let this callback be the single cleanup path.
src/Aspire.Dashboard/Components/Controls/AspireMenu.razor.cs:133 - The context-menu offset reserves 200px, but the same menu is allowed to be 368px wide. Near the right viewport edge, a menu wider than 200px is positioned at
clientX - 200and can still overflow by up to 168px. Reserve the configured maximum width (and add an edge-position regression case) so the menu remains inside the viewport.
const int estimatedMenuWidth = 200;
_targetOffsetLeft = clientX + estimatedMenuWidth > screenWidth
? Math.Max(0, clientX - estimatedMenuWidth)
: clientX;
src/Aspire.Dashboard/Components/Dialogs/NotificationEntryComponent.razor.cs:65
- Primary actions used to hide the notification center while the action ran and then restore it. Closing the dialog here permanently changes that flow: after “View response” opens and is dismissed, the notification center is gone, and even a quick cancel action closes it. The empty
finallyalso confirms the restoration step was lost during the migration. Preserve the temporary hide/restore behavior, or explicitly reopen the notification center after the action completes.
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
ba890c1 to
bed4825
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
Fractional duration filtering is regressed, and notification and trace-grid tests omit required behavioral assertions.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
src/Aspire.Dashboard/Components/Layout/DashboardDialogProvider.cs:17
- This XML summary records migration history (restoring behavior from Fluent UI v4) instead of documenting the provider's current contract. That implementation history will become stale in generated API documentation; describe only the provider's present behavior.
src/Aspire.Dashboard/Model/Otlp/FilterDialogFormModel.cs:22 - Keep duration filters floating-point. OTLP spans expose
Duration.TotalMillisecondswith round-trip formatting, and the repository compares duration values as finitedoubles, so changing this model toint?makes valid values such as50.5impossible to enter (the updated test now explicitly rejects them). Restoredouble?here and use the corresponding floating-point number input/parser so sub-millisecond and fractional-millisecond filters continue to work.
- Files reviewed: 256/304 changed files
- Comments generated: 1
- Review effort level: Balanced
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🔵 Needs a closer look
The broad UI migration requires human review, and fractional-duration filters currently regress.
Review details
Suppressed comments (1)
src/Aspire.Dashboard/Model/Otlp/FilterDialogFormModel.cs:23
- Changing numeric filters to
intbreaks existing fractional-duration filters. Duration filters are serialized with values such as12.5and the trace/span query paths deliberately parse finitedoublemilliseconds, but opening that filter now normalizes it tonulland the dialog cannot preserve or reapply it. It also imposes an unrelated ~24.8-day upper bound. Keep the backing value andFluentNumberInputasdouble?and retain the finite-value validation.
- Files reviewed: 256/304 changed files
- Comments generated: 0 new
- Review effort level: Balanced
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🔵 Needs a closer look
The filter migration rejects valid fractional trace durations and must preserve double? parsing and input behavior.
Review details
Suppressed comments (1)
src/Aspire.Dashboard/Model/Otlp/FilterDialogFormModel.cs:23
- This makes the filter dialog reject valid fractional trace durations. Durations are serialized with
TotalMilliseconds.ToString("R"), and the repository parses filter values withdouble.TryParse, so values such as12.5are part of the existing filter contract; reopening one now producesNumericValue = null, and users can no longer create sub-millisecond/fractional filters. Keep this value asdouble?and restore the correspondingFluentNumberInput<double?>and parsing logic.
- Files reviewed: 257/305 changed files
- Comments generated: 0 new
- Review effort level: Balanced
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🔵 Needs a closer look
Two moderate duration-filter compatibility regressions remain unresolved.
Review details
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
src/Aspire.Dashboard/Model/Otlp/FilterDialogFormModel.cs:23
- Using
intlimits duration filters to 2,147,483,647 ms (about 24.8 days). Longer traces are valid, and the repository query path still parses duration values as finitedoublevalues, so an existing longer-duration filter is now loaded asnulland cannot be applied. Keep whole-millisecond input while usinglong?(andlong.TryParse/FluentNumberInput<long?>) so the UI does not narrow the supported range.
src/Aspire.Dashboard/Model/Otlp/FilterDialogFormModel.cs:23
- This narrows duration filters from finite
doublevalues to whole milliseconds, even though trace durations are produced withTotalMilliseconds.ToString("R", ...)and the repository still parses them as doubles. Existing filters such as0.5or50.5now reopen as an empty required value and cannot be recreated. Keepdouble?with the finite-value validation, and keep the dialog’s number input/parsing ondoubleas well.
- Files reviewed: 257/305 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Tests selectorSelects the full PR test matrix + all PR-gated jobs (ALL) — a rule matching 'Directory.Packages.props' selects ALL Advisory workflow impact (4)
Selection computed for commit |
|
Pull request created: #1631
|
|
📝 Documentation has been drafted in microsoft/aspire.dev#1631 targeting Triggered signals (3): Added a "Dashboard navigation" section to Note This draft PR needs human review before merging. |
|
The CI build failed due to test failure(s) that appear unrelated to the PR changes. These may be flaky tests. Suspected flaky test(s):
Suggested actions:
You can re-run the failed jobs from the workflow run page. |
Description
Migrates the Aspire Dashboard from Fluent UI Blazor v4 to v5 so the Dashboard can adopt the current component model and continue receiving Fluent UI fixes. The Dashboard references the Fluent UI Blazor v5 component package and its matching v5 icon package. Both packages contain .NET 8 assets. The Dashboard and Dashboard tests use
$(DefaultTargetFramework)(currentlynet8.0), and Dashboard packaging remains onnet8.0.The v5 packages are restored from the existing
dotnet9feed; the Fluent UI mappings should move back todotnet-publicwhen v5 is public. .NET 8 compatibility includes DI-backed Blazor component activation and guarded certificate-loading APIs. The temporary .NET 9 hosting runtime-selection workaround and cross-framework test-reference metadata have been removed.The migration replaces removed v4 component APIs and services across dialogs, notifications, menus, grids, tabs, trees, selectors, inputs, splitters, and test infrastructure. It also removes the legacy
app.cssandtokens.cssfiles and establishes a smaller shared layout stylesheet for the v5 controls.User-facing behavior restored or updated as part of the migration includes:
User-facing usage
Dashboard users can continue navigating and filtering Resources, Console Logs, Structured Logs, Traces, and Metrics with the same workflows. The desktop navigation can now be expanded to show page labels or collapsed to icons, and the selected mode persists across reloads.
Screenshots / Recordings
Validation
lib/net8.0compile/runtime assets.DashboardEventHandlersTestspassed.net8.0; restored project-reference framework negotiation passed. A full packaging run was not performed for this cleanup..NET 8.0.21, resource rendering, Settings, and Text Visualizer format selection.Fixes # (issue)
Checklist
<remarks />and<code />elements on your triple slash comments?