From e4dcde3a947d74ac5271633efedfa27a3cc38652 Mon Sep 17 00:00:00 2001 From: Drew Noakes Date: Mon, 26 Aug 2024 13:33:16 +1000 Subject: [PATCH] GridColumnManager improvements The previous code had two issues that are addressed here: - Inconsistent use of string comparers for column names. - O(N) scan through the column collection for lookups. This PR uses a dictionary for columns, which ensures consistent comparer use, and gives O(1) lookup. --- .../ResourcesGridColumns/GridColumnManager.cs | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/Aspire.Dashboard/Components/ResourcesGridColumns/GridColumnManager.cs b/src/Aspire.Dashboard/Components/ResourcesGridColumns/GridColumnManager.cs index c63760b3014..62862e4de0b 100644 --- a/src/Aspire.Dashboard/Components/ResourcesGridColumns/GridColumnManager.cs +++ b/src/Aspire.Dashboard/Components/ResourcesGridColumns/GridColumnManager.cs @@ -1,54 +1,57 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text; using Aspire.Dashboard.Components.Resize; using Aspire.Dashboard.Model; namespace Aspire.Dashboard.Components; -public class GridColumnManager +public class GridColumnManager(IEnumerable columns, DimensionManager dimensionManager) { - private readonly GridColumn[] _columns; - private readonly DimensionManager _dimensionManager; + private readonly Dictionary _columnById + = columns.ToDictionary(c => c.Name, StringComparers.GridColumn); - public GridColumnManager(GridColumn[] columns, DimensionManager dimensionManager) + /// + /// Gets whether the column is known, visible, and has a width for the current viewport. + /// + public bool IsColumnVisible(string columnName) { - if (columns.DistinctBy(c => c.Name, StringComparers.GridColumn).Count() != columns.Length) - { - throw new InvalidOperationException("There are duplicate columns"); - } - - _columns = columns; - _dimensionManager = dimensionManager; + return _columnById.TryGetValue(columnName, out var column) // Is a known column. + && GetColumnWidth(column) is not null // Has width for current viewport. + && column.IsVisible?.Invoke() is null or true; // Is visible. } - public bool IsColumnVisible(string columnId) - { - return GetColumnWidth(_columns.First(column => column.Name == columnId)) is not null; - } - - private string? GetColumnWidth(GridColumn column) + /// + /// Gets a string that can be used as the value for the grid-template-columns CSS property. + /// For example, 1fr 2fr 1fr. + /// + /// + public string GetGridTemplateColumns() { - if (column.IsVisible is not null && !column.IsVisible()) - { - return null; - } + StringBuilder sb = new(); - if (_dimensionManager.ViewportInformation.IsDesktop) + foreach (var (_, column) in _columnById) { - return column.DesktopWidth; + if (column.IsVisible?.Invoke() is null or true && + GetColumnWidth(column) is string width) + { + if (sb.Length > 0) + { + sb.Append(' '); + } + + sb.Append(width); + } } - return column.MobileWidth; + return sb.ToString(); } - public string GetGridTemplateColumns() + private string? GetColumnWidth(GridColumn column) { - var visibleColumns = _columns - .Select(GetColumnWidth) - .Where(s => s is not null) - .Select(s => s!); - - return string.Join(" ", visibleColumns); + return dimensionManager.ViewportInformation.IsDesktop + ? column.DesktopWidth + : column.MobileWidth; } }