Skip to content

Commit acdf501

Browse files
authored
Fix console logs menu buttons not updated with resource (#7639)
1 parent 39b8606 commit acdf501

File tree

4 files changed

+77
-4
lines changed

4 files changed

+77
-4
lines changed

src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
<FluentButton Appearance="Appearance.Lightweight"
3535
Title="@(!string.IsNullOrEmpty(command.DisplayDescription) ? command.DisplayDescription : command.DisplayName)"
3636
Disabled="@(command.State == CommandViewModelState.Disabled)"
37-
OnClick="@(() => ExecuteResourceCommandAsync(command))">
37+
OnClick="@(() => ExecuteResourceCommandAsync(command))"
38+
Class="highlighted-command">
3839
@if (!string.IsNullOrEmpty(command.IconName) && CommandViewModel.ResolveIconName(command.IconName, command.IconVariant) is { } icon)
3940
{
4041
<FluentIcon Value="@icon" Width="16px" />

src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,14 @@ async Task TrackResourceSnapshotsAsync()
202202
}
203203
}
204204

205-
await InvokeAsync(StateHasChanged);
205+
await InvokeAsync(() =>
206+
{
207+
// The selected resource may have changed, so update resource action buttons.
208+
// Update inside in the render's sync context so the buttons don't change while the UI is rendering.
209+
UpdateMenuButtons();
210+
211+
StateHasChanged();
212+
});
206213
}
207214
});
208215
}

tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,70 @@ public async Task ConsoleLogsManager_ClearLogs_LogsFilteredOutAsync()
246246
cut.WaitForState(() => instance._logEntries.EntriesCount > 0);
247247
}
248248

249+
[Fact]
250+
public void MenuButtons_SelectedResourceChanged_ButtonsUpdated()
251+
{
252+
// Arrange
253+
var testResource = ModelTestHelpers.CreateResource(
254+
appName: "test-resource",
255+
state: KnownResourceState.Running,
256+
commands: [new CommandViewModel("test-name", CommandViewModelState.Enabled, "test-displayname", "test-displaydescription", confirmationMessage: "", parameter: null, isHighlighted: true, iconName: string.Empty, iconVariant: IconVariant.Regular)]);
257+
var subscribedResourceNameTcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
258+
var consoleLogsChannel = Channel.CreateUnbounded<IReadOnlyList<ResourceLogLine>>();
259+
var resourceChannel = Channel.CreateUnbounded<IReadOnlyList<ResourceViewModelChange>>();
260+
var dashboardClient = new TestDashboardClient(
261+
isEnabled: true,
262+
consoleLogsChannelProvider: name =>
263+
{
264+
subscribedResourceNameTcs.TrySetResult(name);
265+
return consoleLogsChannel;
266+
},
267+
resourceChannelProvider: () => resourceChannel,
268+
initialResources: [testResource]);
269+
270+
SetupConsoleLogsServices(dashboardClient);
271+
272+
var dimensionManager = Services.GetRequiredService<DimensionManager>();
273+
var viewport = new ViewportInformation(IsDesktop: true, IsUltraLowHeight: false, IsUltraLowWidth: false);
274+
dimensionManager.InvokeOnViewportInformationChanged(viewport);
275+
276+
// Act 1
277+
var cut = RenderComponent<Components.Pages.ConsoleLogs>(builder =>
278+
{
279+
builder.Add(p => p.ResourceName, "test-resource");
280+
builder.Add(p => p.ViewportInformation, viewport);
281+
});
282+
283+
var instance = cut.Instance;
284+
var logger = Services.GetRequiredService<ILogger<ConsoleLogsTests>>();
285+
var loc = Services.GetRequiredService<IStringLocalizer<Resources.ConsoleLogs>>();
286+
287+
// Assert 1
288+
cut.WaitForState(() => instance.PageViewModel.SelectedResource == testResource);
289+
290+
cut.WaitForAssertion(() =>
291+
{
292+
var highlightedCommands = cut.FindAll(".highlighted-command");
293+
Assert.Single(highlightedCommands);
294+
});
295+
296+
// Act 2
297+
testResource = ModelTestHelpers.CreateResource(
298+
appName: "test-resource",
299+
state: KnownResourceState.Running,
300+
commands: []);
301+
resourceChannel.Writer.TryWrite([
302+
new ResourceViewModelChange(ResourceViewModelChangeType.Upsert, testResource)
303+
]);
304+
305+
// Assert 2
306+
cut.WaitForAssertion(() =>
307+
{
308+
var highlightedCommands = cut.FindAll(".highlighted-command");
309+
Assert.Empty(highlightedCommands);
310+
});
311+
}
312+
249313
private void SetupConsoleLogsServices(TestDashboardClient? dashboardClient = null, TestTimeProvider? timeProvider = null)
250314
{
251315
var version = typeof(FluentMain).Assembly.GetName().Version!;

tests/Shared/DashboardModel/ModelTestHelpers.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public static ResourceViewModel CreateResource(
1919
string? resourceType = null,
2020
string? stateStyle = null,
2121
HealthStatus? reportHealthStatus = null,
22-
bool createNullHealthReport = false)
22+
bool createNullHealthReport = false,
23+
ImmutableArray<CommandViewModel>? commands = null)
2324
{
2425
return new ResourceViewModel
2526
{
@@ -38,7 +39,7 @@ public static ResourceViewModel CreateResource(
3839
KnownState = state,
3940
StateStyle = stateStyle,
4041
HealthReports = reportHealthStatus is null && !createNullHealthReport ? [] : [new HealthReportViewModel("healthcheck", reportHealthStatus, null, null)],
41-
Commands = [],
42+
Commands = commands ?? [],
4243
Relationships = [],
4344
};
4445
}

0 commit comments

Comments
 (0)