Skip to content

Show/hide hidden resources on dashboard #9180

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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: 7 additions & 0 deletions playground/Stress/Stress.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
}

builder.AddParameter("testParameterResource", () => "value", secret: true);
builder.AddContainer("hiddenContainer", "alpine")
.WithInitialState(new CustomResourceSnapshot
{
ResourceType = "CustomHiddenContainerType",
Properties = [],
IsHidden = true
});

// TODO: OTEL env var can be removed when OTEL libraries are updated to 1.9.0
// See https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/RELEASENOTES.md#1100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public partial class ResourceDetails : IComponentWithTelemetry, IDisposable
[Parameter]
public bool ShowSpecOnlyToggle { get; set; }

[Parameter]
public bool ShowHiddenResources { get; set; }

[Inject]
public required NavigationManager NavigationManager { get; init; }

Expand Down Expand Up @@ -176,7 +179,7 @@ private IEnumerable<ResourceDetailRelationshipViewModel> GetRelationships()
{
var matches = ResourceByName.Values
.Where(r => string.Equals(r.DisplayName, resourceRelationships.Key, StringComparisons.ResourceName))
.Where(r => r.KnownState != KnownResourceState.Hidden)
.Where(r => !r.IsResourceHidden(ShowHiddenResources))
.ToList();

foreach (var match in matches)
Expand All @@ -199,7 +202,7 @@ private IEnumerable<ResourceDetailRelationshipViewModel> GetBackRelationships()

var otherResources = ResourceByName.Values
.Where(r => r != Resource)
.Where(r => r.KnownState != KnownResourceState.Hidden);
.Where(r => !r.IsResourceHidden(ShowHiddenResources));

foreach (var otherResource in otherResources)
{
Expand Down
35 changes: 32 additions & 3 deletions src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ private sealed class ConsoleLogsSubscription
private readonly List<MenuButtonItem> _resourceMenuItems = new();

// State
private bool _showHiddenResources;
private bool _showTimestamp;
private bool _isTimestampUtc;
public ConsoleLogsViewModel PageViewModel { get; set; } = null!;
Expand Down Expand Up @@ -149,6 +150,12 @@ protected override async Task OnInitializedAsync()
_isTimestampUtc = consoleSettings.IsTimestampUtc;
}

var showHiddenResources = await SessionStorage.GetAsync<bool>(BrowserStorageKeys.ResourcesShowHiddenResources);
if (showHiddenResources.Success)
{
_showHiddenResources = showHiddenResources.Value;
}

await ConsoleLogsManager.EnsureInitializedAsync();
_consoleLogFilters = ConsoleLogsManager.Filters;

Expand Down Expand Up @@ -323,6 +330,27 @@ private void UpdateMenuButtons()
Icon = new Icons.Regular.Size16.ArrowDownload()
});

CommonMenuItems.AddToggleHiddenResourcesMenuItem(
_logsMenuItems,
ControlsStringsLoc,
_showHiddenResources,
_resourceByName.Values,
UpdateMenuButtons,
SessionStorage,
value =>
{
_showHiddenResources = value;

if (!_showHiddenResources && PageViewModel.SelectedResource?.IsResourceHidden(showHiddenResources: false) is true)
{
PageViewModel.SelectedResource = null;
PageViewModel.SelectedOption = _noSelection;
return this.AfterViewModelChangedAsync(_contentLayout, false);
}

return Task.CompletedTask;
});

_logsMenuItems.Add(new()
{
IsDivider = true
Expand Down Expand Up @@ -392,12 +420,13 @@ private async Task ExecuteResourceCommandAsync(CommandViewModel command)
internal static ImmutableList<SelectViewModel<ResourceTypeDetails>> GetConsoleLogResourceSelectViewModels(
ConcurrentDictionary<string, ResourceViewModel> resourcesByName,
SelectViewModel<ResourceTypeDetails> noSelectionViewModel,
string resourceUnknownStateText)
string resourceUnknownStateText,
bool showHiddenResources)
{
var builder = ImmutableList.CreateBuilder<SelectViewModel<ResourceTypeDetails>>();

foreach (var grouping in resourcesByName
.Where(r => !r.Value.IsResourceHidden())
.Where(r => !r.Value.IsResourceHidden(showHiddenResources))
.OrderBy(c => c.Value, ResourceViewModelNameComparer.Instance)
.GroupBy(r => r.Value.DisplayName, StringComparers.ResourceName))
{
Expand Down Expand Up @@ -458,7 +487,7 @@ string GetDisplayText()
}
}

private void UpdateResourcesList() => _resources = GetConsoleLogResourceSelectViewModels(_resourceByName, _noSelection, Loc[nameof(Dashboard.Resources.ConsoleLogs.ConsoleLogsUnknownState)]);
private void UpdateResourcesList() => _resources = GetConsoleLogResourceSelectViewModels(_resourceByName, _noSelection, Loc[nameof(Dashboard.Resources.ConsoleLogs.ConsoleLogsUnknownState)], _showHiddenResources);

private void LoadLogs(ConsoleLogsSubscription newConsoleLogsSubscription)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Components/Pages/Resources.razor
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
<AspireMenu @bind-Open="_contextMenuOpen" @ref="_contextMenu" Anchor="resources-summary-layout-id" Anchored="false" Items="_contextMenuItems" VerticalThreshold="300" />
</Summary>
<Details>
<ResourceDetails Resource="context" ResourceByName="_resourceByName" ShowSpecOnlyToggle="true" />
<ResourceDetails Resource="context" ResourceByName="_resourceByName" ShowSpecOnlyToggle="true" ShowHiddenResources="@_showHiddenResources" />
</Details>
</SummaryDetailsView>
</MainSection>
Expand Down
36 changes: 30 additions & 6 deletions src/Aspire.Dashboard/Components/Pages/Resources.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public partial class Resources : ComponentBase, IComponentWithTelemetry, IAsyncD
[SupplyParameterFromQuery(Name = "view")]
public string? ViewKindName { get; set; }

[Parameter]
[SupplyParameterFromQuery(Name = "showHiddenResources")]
public bool ShowHiddenResources { get; set; }

[CascadingParameter]
public required ViewportInformation ViewportInformation { get; set; }

Expand Down Expand Up @@ -111,14 +115,15 @@ public partial class Resources : ComponentBase, IComponentWithTelemetry, IAsyncD
private ColumnResizeLabels _resizeLabels = ColumnResizeLabels.Default;
private ColumnSortLabels _sortLabels = ColumnSortLabels.Default;
private bool _showResourceTypeColumn;
private bool _showHiddenResources;

private bool Filter(ResourceViewModel resource)
{
return IsKeyValueTrue(resource.ResourceType, PageViewModel.ResourceTypesToVisibility)
&& IsKeyValueTrue(resource.State ?? string.Empty, PageViewModel.ResourceStatesToVisibility)
&& IsKeyValueTrue(resource.HealthStatus?.Humanize() ?? string.Empty, PageViewModel.ResourceHealthStatusesToVisibility)
&& (_filter.Length == 0 || resource.MatchesFilter(_filter))
&& !resource.IsResourceHidden();
&& !resource.IsResourceHidden(_showHiddenResources);

static bool IsKeyValueTrue(string key, IDictionary<string, bool> dictionary) => dictionary.TryGetValue(key, out var value) && value;
}
Expand Down Expand Up @@ -188,6 +193,12 @@ protected override async Task OnInitializedAsync()
_showResourceTypeColumn = showResourceTypeColumn.Value;
}

var showHiddenResources = await SessionStorage.GetAsync<bool>(BrowserStorageKeys.ResourcesShowHiddenResources);
if (showHiddenResources.Success)
{
_showHiddenResources = showHiddenResources.Value;
}

if (DashboardClient.IsEnabled)
{
var collapsedResult = await SessionStorage.GetAsync<List<string>>(BrowserStorageKeys.ResourcesCollapsedResourceNames);
Expand Down Expand Up @@ -339,7 +350,7 @@ private async Task UpdateResourceGraphResourcesAsync()
}

var activeResources = _resourceByName.Values.Where(Filter).OrderBy(e => e.ResourceType).ThenBy(e => e.Name).ToList();
var resources = activeResources.Select(r => ResourceGraphMapper.MapResource(r, _resourceByName, ColumnsLoc)).ToList();
var resources = activeResources.Select(r => ResourceGraphMapper.MapResource(r, _resourceByName, ColumnsLoc, _showHiddenResources)).ToList();
await _jsModule.InvokeVoidAsync("updateResourcesGraph", resources);
}

Expand Down Expand Up @@ -447,11 +458,24 @@ private void UpdateMenuButtons()
Icon = new Icons.Regular.Size16.Eye()
});
}

CommonMenuItems.AddToggleHiddenResourcesMenuItem(
_resourcesMenuItems,
ControlsStringsLoc,
_showHiddenResources,
_resourceByName.Values,
UpdateMenuButtons,
SessionStorage,
value =>
{
_showHiddenResources = value;
return _dataGrid.SafeRefreshDataAsync();
});
}

private bool HasCollapsedResources()
{
return _resourceByName.Any(r => !r.Value.IsResourceHidden() && _collapsedResourceNames.Contains(r.Key));
return _resourceByName.Any(r => !r.Value.IsResourceHidden(_showHiddenResources) && _collapsedResourceNames.Contains(r.Key));
}

private void UpdateMaxHighlightedCount()
Expand Down Expand Up @@ -613,14 +637,14 @@ private async Task ClearSelectedResourceAsync(bool causedByUserAction = false)
_elementIdBeforeDetailsViewOpened = null;
}

private string GetResourceName(ResourceViewModel resource) => ResourceViewModel.GetResourceName(resource, _resourceByName);
private string GetResourceName(ResourceViewModel resource) => ResourceViewModel.GetResourceName(resource, _resourceByName, _showHiddenResources);

private bool HasMultipleReplicas(ResourceViewModel resource)
{
var count = 0;
foreach (var (_, item) in _resourceByName)
{
if (item.IsResourceHidden())
if (item.IsResourceHidden(_showHiddenResources))
{
continue;
}
Expand Down Expand Up @@ -694,7 +718,7 @@ private async Task OnToggleCollapse(ResourceGridViewModel viewModel)
private async Task OnToggleCollapseAll()
{
var resourcesWithChildren = _resourceByName.Values
.Where(r => !r.IsResourceHidden())
.Where(r => !r.IsResourceHidden(_showHiddenResources))
.Where(r => _resourceByName.Values.Any(nested => nested.GetResourcePropertyValue(KnownProperties.Resource.ParentName) == r.Name))
.ToList();

Expand Down
50 changes: 50 additions & 0 deletions src/Aspire.Dashboard/Model/CommonMenuItems.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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.Resources;
using Aspire.Dashboard.Utils;
using Microsoft.Extensions.Localization;
using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons;

namespace Aspire.Dashboard.Model;

public static class CommonMenuItems
{
public static void AddToggleHiddenResourcesMenuItem(
List<MenuButtonItem> menuItems,
IStringLocalizer<ControlsStrings> loc,
bool showHiddenResources,
IEnumerable<ResourceViewModel> resources,
Action updateMenuButtons,
ISessionStorage sessionStorage,
Func<bool, Task> refreshFunction)
{
var areResourcesHidden = resources.Any(r => r.IsResourceHidden(false));
if (!showHiddenResources)
{
menuItems.Add(new MenuButtonItem
{
IsDisabled = !areResourcesHidden,
OnClick = OnToggleShowHiddenResources,
Text = loc[nameof(ControlsStrings.ShowHiddenResources)],
Icon = new Icons.Regular.Size16.Eye()
});
}
else
{
menuItems.Add(new MenuButtonItem
{
OnClick = OnToggleShowHiddenResources,
Text = loc[nameof(ControlsStrings.HideHiddenResources)],
Icon = new Icons.Regular.Size16.EyeOff()
});
}
async Task OnToggleShowHiddenResources()
{
showHiddenResources = !showHiddenResources;
await sessionStorage.SetAsync(BrowserStorageKeys.ResourcesShowHiddenResources, showHiddenResources).ConfigureAwait(true);
await refreshFunction(showHiddenResources).ConfigureAwait(true);
updateMenuButtons();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Aspire.Dashboard.Model.ResourceGraph;

public static class ResourceGraphMapper
{
public static ResourceDto MapResource(ResourceViewModel r, IDictionary<string, ResourceViewModel> resourcesByName, IStringLocalizer<Columns> columnsLoc)
public static ResourceDto MapResource(ResourceViewModel r, IDictionary<string, ResourceViewModel> resourcesByName, IStringLocalizer<Columns> columnsLoc, bool showHiddenResources)
{
var resolvedNames = new List<string>();

Expand All @@ -24,7 +24,7 @@ public static ResourceDto MapResource(ResourceViewModel r, IDictionary<string, R
{
var matches = resourcesByName.Values
.Where(r => string.Equals(r.DisplayName, resourceRelationships.Key, StringComparisons.ResourceName))
.Where(r => !r.IsResourceHidden())
.Where(r => !r.IsResourceHidden(showHiddenResources))
.ToList();

foreach (var match in matches)
Expand Down
10 changes: 7 additions & 3 deletions src/Aspire.Dashboard/Model/ResourceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ internal bool MatchesFilter(string filter)
return null;
}

public bool IsResourceHidden()
public bool IsResourceHidden(bool showHiddenResources)
{
if (showHiddenResources)
{
return false;
}
return IsHidden || KnownState is KnownResourceState.Hidden;
}

Expand All @@ -102,12 +106,12 @@ public bool IsResourceHidden()
?? Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus.Unhealthy;
}

public static string GetResourceName(ResourceViewModel resource, IDictionary<string, ResourceViewModel> allResources)
public static string GetResourceName(ResourceViewModel resource, IDictionary<string, ResourceViewModel> allResources, bool showHiddenResources = false)
{
var count = 0;
foreach (var (_, item) in allResources)
{
if (item.IsResourceHidden())
if (item.IsResourceHidden(showHiddenResources))
{
continue;
}
Expand Down
Loading
Loading