Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard dropdown max visible items #2678

Merged
merged 8 commits into from
Mar 7, 2024
Merged
15 changes: 15 additions & 0 deletions src/Aspire.Dashboard/Components/Controls/ResourceSelect.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@using Aspire.Dashboard.Resources

<FluentSelect @ref="_resourceSelectComponent"
Items="Resources"
OptionValue="@(c => c!.Id?.InstanceId)"
OptionDisabled="@(c => c!.Id?.Type is Otlp.Model.OtlpApplicationType.ReplicaSet)"
SelectedOption="SelectedResource"
SelectedOptionChanged="SelectedResourceChanged"
AriaLabel="@AriaLabel"
Class="resource-list"
Height="@GetPopupHeight()">
<OptionTemplate>
<ResourceSelectOptionTemplate ViewModel="@context" />
</OptionTemplate>
</FluentSelect>
62 changes: 62 additions & 0 deletions src/Aspire.Dashboard/Components/Controls/ResourceSelect.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Aspire.Dashboard.Model;
using Aspire.Dashboard.Model.Otlp;
using Microsoft.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components;
using Microsoft.JSInterop;

namespace Aspire.Dashboard.Components.Controls;

public partial class ResourceSelect
{
private const int ResourceOptionPixelHeight = 32;
private const int MaxVisibleResourceOptions = 10;
JamesNK marked this conversation as resolved.
Show resolved Hide resolved

[Parameter]
public IEnumerable<SelectViewModel<ResourceTypeDetails>> Resources { get; set; } = default!;

[Parameter]
public SelectViewModel<ResourceTypeDetails> SelectedResource { get; set; } = default!;

[Parameter]
public EventCallback<SelectViewModel<ResourceTypeDetails>> SelectedResourceChanged { get; set; }

[Parameter]
public string? AriaLabel { get; set; }

[Inject]
public required IJSRuntime JSRuntime { get; init; }

private FluentSelect<SelectViewModel<ResourceTypeDetails>>? _resourceSelectComponent;

/// <summary>
/// Workaround for issue in fluent-select web component where the display value of the
/// selected item doesn't update automatically when the item changes.
/// </summary>
public ValueTask UpdateDisplayValueAsync()
{
if (JSRuntime is null || _resourceSelectComponent is null)
{
return ValueTask.CompletedTask;
}

return JSRuntime.InvokeVoidAsync("updateSelectDisplayValue", _resourceSelectComponent.Element);
}

private string? GetPopupHeight()
{
if (Resources?.TryGetNonEnumeratedCount(out var count) is false or null)
{
return null;
}

if (count <= MaxVisibleResourceOptions)
{
return null;
}

return $"{ResourceOptionPixelHeight * MaxVisibleResourceOptions}px";
JamesNK marked this conversation as resolved.
Show resolved Hide resolved
}
}
17 changes: 5 additions & 12 deletions src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,11 @@
<div class="resource-logs-layout">
<h1 class="page-header">@Loc[nameof(Dashboard.Resources.ConsoleLogs.ConsoleLogsHeader)]</h1>
<FluentToolbar Orientation="Orientation.Horizontal">
<FluentSelect @ref="_resourceSelectComponent"
Class="resource-list"
Items="@_resources"
OptionValue="@(c => c.Id?.InstanceId)"
OptionDisabled="@(c => c.Id?.Type is Otlp.Model.OtlpApplicationType.ReplicaSet)"
@bind-SelectedOption="PageViewModel.SelectedOption"
@bind-SelectedOption:after="HandleSelectedOptionChangedAsync"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAResource)]">
<OptionTemplate>
<ResourceSelectOptionTemplate ViewModel="@context" />
</OptionTemplate>
</FluentSelect>
<ResourceSelect @ref="_resourceSelectComponent"
Resources="_resources"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAResource)]"
@bind-SelectedResource="PageViewModel.SelectedOption"
@bind-SelectedResource:after="HandleSelectedOptionChangedAsync" />
<FluentLabel Typo="Typography.Body" aria-live="polite" aria-label="@Loc[nameof(Dashboard.Resources.ConsoleLogs.LogStatusLabel)]">@PageViewModel.Status</FluentLabel>
</FluentToolbar>
<LogViewer @ref="_logViewer" />
Expand Down
12 changes: 4 additions & 8 deletions src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Diagnostics;
using Aspire.Dashboard.Components.Controls;
using Aspire.Dashboard.Model;
using Aspire.Dashboard.Model.Otlp;
using Aspire.Dashboard.Otlp.Model;
using Aspire.Dashboard.Resources;
using Aspire.Dashboard.Utils;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.FluentUI.AspNetCore.Components;
using Microsoft.JSInterop;

namespace Aspire.Dashboard.Components.Pages;

Expand All @@ -21,9 +20,6 @@ public sealed partial class ConsoleLogs : ComponentBase, IAsyncDisposable, IPage
[Inject]
public required IDashboardClient DashboardClient { get; init; }

[Inject]
public required IJSRuntime JS { get; init; }

[Inject]
public required ProtectedSessionStorage SessionStorage { get; init; }

Expand All @@ -44,7 +40,7 @@ public sealed partial class ConsoleLogs : ComponentBase, IAsyncDisposable, IPage
private Task? _resourceSubscriptionTask;

// UI
private FluentSelect<SelectViewModel<ResourceTypeDetails>>? _resourceSelectComponent;
private ResourceSelect? _resourceSelectComponent;
private SelectViewModel<ResourceTypeDetails> _noSelection = null!;
private LogViewer _logViewer = null!;

Expand Down Expand Up @@ -306,9 +302,9 @@ private async Task OnResourceChanged(ResourceViewModelChangeType changeType, Res

// Workaround for issue in fluent-select web component where the display value of the
// selected item doesn't update automatically when the item changes
if (_resourceSelectComponent is not null && JS is not null)
if (_resourceSelectComponent is not null)
{
await JS.InvokeVoidAsync("updateFluentSelectDisplayValue", _resourceSelectComponent.Element);
await _resourceSelectComponent.UpdateDisplayValueAsync();
}
}

Expand Down
15 changes: 4 additions & 11 deletions src/Aspire.Dashboard/Components/Pages/Metrics.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,10 @@
<div class="metrics-layout">
<h1 class="page-header">@Loc[nameof(Dashboard.Resources.Metrics.MetricsHeader)]</h1>
<FluentToolbar Orientation="Orientation.Horizontal">
<FluentSelect Items="@_applications"
Class="resource-list"
OptionDisabled="@(c => c.Id?.Type is OtlpApplicationType.ReplicaSet)"
OptionValue="@(c => c.Id?.InstanceId)"
@bind-SelectedOption="PageViewModel.SelectedApplication"
@bind-SelectedOption:after="HandleSelectedApplicationChangedAsync"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]">
<OptionTemplate>
<ResourceSelectOptionTemplate ViewModel="@context" />
</OptionTemplate>
</FluentSelect>
<ResourceSelect Resources="_applications"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]"
@bind-SelectedResource="PageViewModel.SelectedApplication"
@bind-SelectedResource:after="HandleSelectedApplicationChangedAsync" />
<FluentIcon slot="end" Icon="Icons.Regular.Size20.Clock" Style="margin-right:5px;" />
<FluentSelect slot="end" TOption="SelectViewModel<TimeSpan>"
Items="@_durations"
Expand Down
15 changes: 4 additions & 11 deletions src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,10 @@
<div class="logs-layout">
<h1 class="page-header">@Loc[nameof(Dashboard.Resources.StructuredLogs.StructuredLogsHeader)]</h1>
<FluentToolbar Orientation="Orientation.Horizontal">
<FluentSelect Items="@_applicationViewModels"
Class="resource-list"
OptionValue="@(c => c.Id?.InstanceId)"
OptionDisabled="@(c => c.Id?.Type is OtlpApplicationType.ReplicaSet)"
@bind-SelectedOption="PageViewModel.SelectedApplication"
@bind-SelectedOption:after="HandleSelectedApplicationChangedAsync"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]">
<OptionTemplate>
<ResourceSelectOptionTemplate ViewModel="@context" />
</OptionTemplate>
</FluentSelect>
<ResourceSelect Resources="_applicationViewModels"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]"
@bind-SelectedResource="PageViewModel.SelectedApplication"
@bind-SelectedResource:after="HandleSelectedApplicationChangedAsync" />
<FluentSearch @bind-Value="PageViewModel.Filter"
@oninput="HandleFilter"
@bind-Value:after="HandleClear"
Expand Down
15 changes: 4 additions & 11 deletions src/Aspire.Dashboard/Components/Pages/Traces.razor
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@
<div class="traces-layout">
<h1 class="page-header">@Loc[nameof(Dashboard.Resources.Traces.TracesHeader)]</h1>
<FluentToolbar Orientation="Orientation.Horizontal">
<FluentSelect Items="@_applicationViewModels"
Class="resource-list"
OptionValue="@(c => c.Id?.InstanceId)"
OptionDisabled="@(c => c.Id?.Type is OtlpApplicationType.ReplicaSet)"
@bind-SelectedOption="_selectedApplication"
@bind-SelectedOption:after="HandleSelectedApplicationChangedAsync"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]">
<OptionTemplate>
<ResourceSelectOptionTemplate ViewModel="@context" />
</OptionTemplate>
</FluentSelect>
<ResourceSelect Resources="_applicationViewModels"
AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]"
@bind-SelectedResource="_selectedApplication"
@bind-SelectedResource:after="HandleSelectedApplicationChangedAsync" />
<FluentSearch @bind-Value="_filter"
@oninput="HandleFilter"
@bind-Value:after="HandleClear"
Expand Down