Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<!-- Set this to false when switching Microsoft.FluentUI.AspNetCore.Components to a release package. -->
<MicrosoftFluentUIAspNetCoreComponentsVersion>5.0.0-preview.26260.3</MicrosoftFluentUIAspNetCoreComponentsVersion>
<MicrosoftFluentUIAspNetCoreComponentsIsPreview>true</MicrosoftFluentUIAspNetCoreComponentsIsPreview>
<MicrosoftFluentUIAspNetCoreComponentsVersion>5.0.0</MicrosoftFluentUIAspNetCoreComponentsVersion>
<MicrosoftFluentUIAspNetCoreComponentsIsPreview>false</MicrosoftFluentUIAspNetCoreComponentsIsPreview>
<!-- The Npgsql versions used when using Npgsql EF Core on net8/net9. The major versions need to match between Npgsql and EF Core. -->
<Npgsql8Version>8.0.9</Npgsql8Version>
<Npgsql9Version>9.0.5</Npgsql9Version>
Expand Down Expand Up @@ -138,7 +137,7 @@
<PackageVersion Include="Microsoft.Data.SqlClient.Extensions.Azure" Version="7.0.2" />
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="10.0.12" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components" Version="$(MicrosoftFluentUIAspNetCoreComponentsVersion)" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="5.0.0-rc.6.26241.1" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="5.0.0" />
<PackageVersion Include="Milvus.Client" Version="2.3.0-preview.1" /> <!-- No stable release available -->
<PackageVersion Include="ModelContextProtocol" Version="1.4.1" />
<PackageVersion Include="MongoDB.Driver" Version="3.9.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@ public static GridItemsProvider<TItem> Create<TItem>(Func<IEnumerable<TItem>?> g
public static IEnumerable<TItem> ApplySorting<TItem>(IEnumerable<TItem> items, GridItemsProviderRequest<TItem> request)
{
request.CancellationToken.ThrowIfCancellationRequested();
return request.SortByColumn?.SortBy switch
if (request.SortColumns is not [var sortColumn, ..])
{
null => items,
EnumerableGridSort<TItem> sort => sort.Apply(items, request.SortByAscending),
return items;
}

return sortColumn.Column.SortBy switch
{
EnumerableGridSort<TItem> sort => sort.Apply(items, sortColumn.Ascending),
_ => throw new InvalidOperationException("In-memory grid columns must use EnumerableGridSort.")
};
}
Expand Down
26 changes: 26 additions & 0 deletions src/Aspire.Dashboard/Components/Layout/MainLayout.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,32 @@
fill: var(--colorBrandForeground1) !important;
}

::deep.layout > .desktop-nav-rail button.fluent-appbar-more-item {
--appbar-item-height-adjustment: calc(var(--appbar-item-size) - 48px);
display: flex;
width: 100%;
min-width: 0;
height: 48px;
min-height: 48px;
flex: 0 0 48px;
align-items: center;
justify-content: flex-start;
}

::deep.layout > .desktop-nav-rail button.fluent-appbar-more-item > .fluent-stack-vertical {
width: var(--desktop-nav-collapsed-width) !important;
height: 100% !important;
flex: 0 0 var(--desktop-nav-collapsed-width);
}

::deep.layout > .desktop-nav-rail button.fluent-appbar-more-item:hover {
background-color: var(--colorNeutralBackground3);
}

::deep.layout > .desktop-nav-rail button.fluent-appbar-more-item:hover svg {
fill: var(--colorBrandForeground1) !important;
}

::deep.layout > .desktop-nav-rail .fluent-appbar-item > a.active {
background-color: color-mix(in srgb, var(--colorBrandBackground) 14%, transparent);
box-shadow: inset 3px 0 0 var(--colorBrandBackground);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Aspire.Dashboard.Components.Layout;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace Aspire.Dashboard.Components.Pages;

Expand Down Expand Up @@ -79,8 +80,19 @@ async Task SetStateAndNavigateAsync()
var serializableViewModel = page.ConvertViewModelToSerializable();
var pathWithParameters = page.GetUrlFromSerializableViewModel(serializableViewModel);

try
{
// Persist before navigating so the JS interop call also verifies that the circuit is still
// connected. A queued UI callback can otherwise ask RemoteNavigationManager to navigate
// after the browser has disconnected, which it reports as an unhandled navigation failure.
await page.SessionStorage.SetAsync(page.SessionStorageKey, serializableViewModel);
}
catch (JSDisconnectedException)
{
return;
}

page.NavigationManager.NavigateTo(pathWithParameters);
await page.SessionStorage.SetAsync(page.SessionStorageKey, serializableViewModel).ConfigureAwait(false);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Components/Pages/Resources.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ internal ValueTask<GridItemsProviderResult<ResourceGridViewModel>> GetData(GridI
// Get filtered and ordered resources.
var filteredResources = GetFilteredResources()
.Select(r => new ResourceGridViewModel { Resource = r });
filteredResources = request.SortByColumn is null
filteredResources = request.SortColumns.Count == 0
? filteredResources
.OrderBy(p => p.Resource.ResourceType)
.ThenBy(p => p.Resource, ResourceViewModelNameComparer.Instance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public async Task EnumerableProvider_SortsBeforePagingAndReadsCurrentItems()
var provider = EnumerableGridItemsProvider.Create(() => items);
var column = new AspireTemplateColumn<int>();
ParameterView.FromDictionary(new Dictionary<string, object?> { [nameof(column.SortBy)] = EnumerableGridSort<int>.ByAscending(item => item) }).SetParameterProperties(column);
var request = new GridItemsProviderRequest<int> { SortByColumn = column, SortByAscending = true, StartIndex = 1, Count = 2 };
var request = new GridItemsProviderRequest<int> { SortColumns = [new(column, Ascending: true)], StartIndex = 1, Count = 2 };

var result = await provider(request);
Assert.Equal([2, 3], result.Items);
Expand Down Expand Up @@ -97,7 +97,7 @@ public async Task EnumerableProvider_RejectsQueryableSort()
var column = new AspireTemplateColumn<int>();
ParameterView.FromDictionary(new Dictionary<string, object?> { [nameof(column.SortBy)] = GridSort<int>.ByAscending(item => item) }).SetParameterProperties(column);

await Assert.ThrowsAsync<InvalidOperationException>(async () => await provider(new GridItemsProviderRequest<int> { SortByColumn = column }));
await Assert.ThrowsAsync<InvalidOperationException>(async () => await provider(new GridItemsProviderRequest<int> { SortColumns = [new(column, Ascending: true)] }));
}

[Fact]
Expand Down
27 changes: 24 additions & 3 deletions tests/Aspire.Dashboard.Components.Tests/Pages/ResourcesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Localization;
using Microsoft.FluentUI.AspNetCore.Components;
using Microsoft.JSInterop;
using OpenTelemetry.Proto.Logs.V1;
using Xunit;
using TelemetryTestHelpers = Aspire.Tests.Shared.Telemetry.TelemetryTestHelpers;
Expand Down Expand Up @@ -135,13 +136,12 @@ public async Task Resources_NameColumnSortsDescending()

await cut.InvokeAsync(() => grid.Instance.SortByColumnAsync(nameColumn.Instance, DataGridSortDirection.Descending));

Assert.False(grid.Instance.SortByAscending);
Assert.False(Assert.Single(grid.Instance.SortColumns).Ascending);
Assert.Equal("descending", cut.Find("th[col-index='1']").GetAttribute("aria-sort"));

var request = new GridItemsProviderRequest<ResourceGridViewModel>
{
SortByColumn = nameColumn.Instance,
SortByAscending = false,
SortColumns = [new(nameColumn.Instance, Ascending: false)],
};
var result = await cut.InvokeAsync(() => cut.Instance.GetData(request).AsTask());

Expand Down Expand Up @@ -577,6 +577,27 @@ public async Task MobileParametersTab_UpdatesUrlWithoutOpeningFilterPanel()
Assert.Empty(layout.DialogCloseListeners);
}

[Fact]
public async Task MobileParametersTab_DoesNotNavigateAfterCircuitDisconnects()
{
var viewport = new ViewportInformation(IsDesktop: false, IsUltraLowHeight: false, IsUltraLowWidth: false);
var sessionStorage = new TestSessionStorage
{
OnSetAsync = (_, _) => throw new JSDisconnectedException("The circuit disconnected.")
};
ResourceSetupHelpers.SetupResourcesPage(this, viewport, sessionStorage: sessionStorage);

var cut = Render<Components.Pages.Resources>(builder => builder.AddCascadingValue(viewport));
var tabs = cut.FindComponent<FluentTabs>().Instance;
var parametersTab = cut.FindComponents<FluentTab>().Single(tab => tab.Instance.Id == "tab-Parameters");
var navigation = Services.GetRequiredService<NavigationManager>();
var initialUri = navigation.Uri;

await cut.InvokeAsync(() => tabs.ActiveTabChanged.InvokeAsync(parametersTab.Instance));

Assert.Equal(initialUri, navigation.Uri);
}

[Theory]
[InlineData(false, false)]
[InlineData(true, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ public static void SetupResourceDetails(BunitContext context)
FluentUISetupHelpers.SetupFluentUIComponents(context);
}

public static void SetupResourcesPage(BunitContext context, ViewportInformation viewport, IDashboardClient? dashboardClient = null, ILocalStorage? localStorage = null)
public static void SetupResourcesPage(
BunitContext context,
ViewportInformation viewport,
IDashboardClient? dashboardClient = null,
ILocalStorage? localStorage = null,
ISessionStorage? sessionStorage = null)
{
FluentUISetupHelpers.SetupFluentDivider(context);
FluentUISetupHelpers.SetupFluentInputLabel(context);
Expand All @@ -57,7 +62,7 @@ public static void SetupResourcesPage(BunitContext context, ViewportInformation
FluentUISetupHelpers.SetupFluentOverflow(context);
FluentUISetupHelpers.SetupFluentMenu(context);

FluentUISetupHelpers.AddCommonDashboardServices(context, localStorage: localStorage);
FluentUISetupHelpers.AddCommonDashboardServices(context, localStorage: localStorage, sessionStorage: sessionStorage);
context.JSInterop.SetupVoid("focusElement", _ => true);
context.Services.AddSingleton<IconResolver>();
context.Services.AddSingleton<ILogger<StructuredLogs>>(NullLogger<StructuredLogs>.Instance);
Expand Down
Loading