Skip to content

Migrate dashboard to Fluent UI Blazor v5 - #19431

Draft
James Newton-King (JamesNK) wants to merge 7 commits into
mainfrom
jamesnk/fluentui-v5-dashboard
Draft

Migrate dashboard to Fluent UI Blazor v5#19431
James Newton-King (JamesNK) wants to merge 7 commits into
mainfrom
jamesnk/fluentui-v5-dashboard

Conversation

@JamesNK

Copy link
Copy Markdown
Member

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 matching Fluent UI component and icon packages are updated together, and the Dashboard, Dashboard tests, and Dashboard packaging move to .NET 9 to satisfy the v5 icon package requirements.

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.css and tokens.css files and establishes a smaller shared layout stylesheet for the v5 controls.

User-facing behavior restored or updated as part of the migration includes:

  • Responsive filter toolbars that align controls to the end, use bounded search widths, and wrap without horizontal scrollbars.
  • Working resource, level, type, and duration selectors with stable sizing and pointer interaction.
  • Search icons and correctly slotted v5 text inputs.
  • Metrics and GenAI tree selection/expansion state restored through the v5 tree APIs.
  • Determinate trace duration indicators.
  • A collapsible desktop navigation rail with persisted icon-only and icon-plus-label modes.
  • Stable Resources graph, tab, details, grid, and footer layouts.

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

This PR includes UI changes. Please add screenshots or screen recordings so reviewers can evaluate the visual changes without running locally.

  • For before/after comparisons, place them side-by-side or label them clearly.
  • For interactive changes (animations, transitions, new flows), prefer a short screen recording (GIF or video).
  • If you cannot capture visuals now, note what scenario to test and mark this section as TODO.

Validation

  • Dashboard component and integration suites were run throughout the migration, including full-suite runs and focused reruns for each changed component area.
  • Playwright regressions cover shared responsive toolbars, selector visibility and interaction, Resources graph layout, trace duration indicators, and desktop navigation expansion/persistence.
  • TestShop was used for manual validation across Resources, Console Logs, Structured Logs, Traces, Trace Detail, and Metrics on desktop and mobile-sized viewports.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Copilot AI balanced review requested due to automatic review settings August 17, 2026 09:20
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19431

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19431"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +24 to 26
<FluentTextInput @ref="_tokenTextField" Id="token-text-field" @bind-Value="_formModel.Token"
Placeholder="@Loc[nameof(Dashboard.Resources.Login.TextFieldPlaceholder)]"
TextFieldType="TextFieldType.Password" AutoComplete="one-time-code" Class="token-entry-text" Immediate="true" />
Comment on lines +25 to 26
<FluentSelect TOption="CultureInfo" TValue="CultureInfo"
TOption="CultureInfo"
Comment on lines +113 to +116
await page.GotoAsync("/?view=Graph");

var graphTab = page.Locator("#tab-Graph");
await Assertions.Expect(graphTab).ToHaveAttributeAsync("aria-selected", "true");
Comment on lines +69 to +75
var firstCompleted = await Task.WhenAny(opened.Task, resultTask).ConfigureAwait(false);
if (firstCompleted == resultTask)
{
await resultTask.ConfigureAwait(false);
}

var reference = new DashboardMessageBarReference(await opened.Task.ConfigureAwait(false), resultTask, notificationService);
Comment on lines +31 to +34
@if (Content.AllowDismiss)
{
<FluentButton OnClick="@(() => CloseAsync(null))" aria-label="Dismiss">Dismiss</FluentButton>
}
Copilot AI review requested due to automatic review settings August 17, 2026 23:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • TOption is 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:26
  • FluentTextInput v5 uses TextInputType; TextFieldType is 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, click graphTab, 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 (see Components/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 - 200 and 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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants