From e071e8e4c906f540b7daea66da6edcf21e62e763 Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Wed, 18 Dec 2024 16:26:42 -0500 Subject: [PATCH 1/4] Add resource to console logs page title --- src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor index 3624efff22d..96ef60296aa 100644 --- a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor @@ -5,7 +5,14 @@ @using Aspire.Dashboard.Resources @namespace Aspire.Dashboard.Components.Pages - +@if (PageViewModel.SelectedResource is null) +{ + +} +else +{ + (@PageViewModel.SelectedResource.DisplayName) +}
Date: Thu, 19 Dec 2024 13:39:37 -0500 Subject: [PATCH 2/4] Add resource titles to pages where appropriate --- ...cationName.razor => AspirePageTitle.razor} | 2 +- ...Name.razor.cs => AspirePageTitle.razor.cs} | 20 +++++++++++++++---- .../Components/Layout/MainLayout.razor | 4 ++-- .../Components/Pages/ConsoleLogs.razor | 14 ++++++------- .../Components/Pages/Login.razor | 4 ++-- .../Components/Pages/Metrics.razor | 7 ++++++- .../Components/Pages/Resources.razor | 2 +- .../Components/Pages/StructuredLogs.razor | 7 ++++++- .../Components/Pages/TraceDetail.razor | 9 +++++++-- .../Components/Pages/Traces.razor | 7 ++++++- .../Controls/ApplicationNameTests.cs | 4 ++-- 11 files changed, 55 insertions(+), 25 deletions(-) rename src/Aspire.Dashboard/Components/Controls/{ApplicationName.razor => AspirePageTitle.razor} (70%) rename src/Aspire.Dashboard/Components/Controls/{ApplicationName.razor.cs => AspirePageTitle.razor.cs} (68%) diff --git a/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor b/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor similarity index 70% rename from src/Aspire.Dashboard/Components/Controls/ApplicationName.razor rename to src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor index ca4f15cec7d..a01ba84fea7 100644 --- a/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor +++ b/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor @@ -1,3 +1,3 @@ @namespace Aspire.Dashboard.Components -@_applicationName +@_pageTitle diff --git a/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs b/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor.cs similarity index 68% rename from src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs rename to src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor.cs index 26ef81728e7..c5a313d657a 100644 --- a/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs +++ b/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor.cs @@ -8,10 +8,13 @@ namespace Aspire.Dashboard.Components; -public sealed partial class ApplicationName : ComponentBase, IDisposable +public sealed partial class AspirePageTitle : ComponentBase, IDisposable { private CancellationTokenSource? _disposalCts; + [Parameter] + public string? AdditionalText { get; init; } + [Parameter] public string? ResourceName { get; init; } @@ -21,7 +24,7 @@ public sealed partial class ApplicationName : ComponentBase, IDisposable [Inject] public required IDashboardClient DashboardClient { get; init; } - private string? _applicationName; + private string? _pageTitle; protected override async Task OnInitializedAsync() { @@ -31,15 +34,24 @@ protected override async Task OnInitializedAsync() _disposalCts = new CancellationTokenSource(); await DashboardClient.WhenConnected.WaitAsync(_disposalCts.Token); } + } + + protected override void OnParametersSet() + { + string applicationName; if (ResourceName is not null && Loc is not null) { - _applicationName = string.Format(CultureInfo.InvariantCulture, Loc[ResourceName], DashboardClient.ApplicationName); + applicationName = string.Format(CultureInfo.InvariantCulture, Loc[ResourceName], DashboardClient.ApplicationName); } else { - _applicationName = DashboardClient.ApplicationName; + applicationName = DashboardClient.ApplicationName; } + + _pageTitle = AdditionalText is null + ? applicationName + : $"{applicationName} ({AdditionalText})"; } public void Dispose() diff --git a/src/Aspire.Dashboard/Components/Layout/MainLayout.razor b/src/Aspire.Dashboard/Components/Layout/MainLayout.razor index fe5dc78c97b..63921499024 100644 --- a/src/Aspire.Dashboard/Components/Layout/MainLayout.razor +++ b/src/Aspire.Dashboard/Components/Layout/MainLayout.razor @@ -16,7 +16,7 @@ {
diff --git a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor index 96ef60296aa..6f22c3c2ffd 100644 --- a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor @@ -5,14 +5,12 @@ @using Aspire.Dashboard.Resources @namespace Aspire.Dashboard.Components.Pages -@if (PageViewModel.SelectedResource is null) -{ - -} -else -{ - (@PageViewModel.SelectedResource.DisplayName) -} + + +
Loc - +
@@ -15,7 +15,7 @@
-

+

@* diff --git a/src/Aspire.Dashboard/Components/Pages/Metrics.razor b/src/Aspire.Dashboard/Components/Pages/Metrics.razor index ab52228dbdb..b8be7bdf8e7 100644 --- a/src/Aspire.Dashboard/Components/Pages/Metrics.razor +++ b/src/Aspire.Dashboard/Components/Pages/Metrics.razor @@ -10,7 +10,12 @@ @inject IStringLocalizer Loc @inject IStringLocalizer ControlsStringsLoc - + + +
ControlsStringsLoc @inject IStringLocalizer ColumnsLoc - + @{ var showDetailsView = SelectedResource is not null; diff --git a/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor b/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor index e5f6f77f0bc..1a4ff059bef 100644 --- a/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor @@ -13,7 +13,12 @@ @inject IStringLocalizer ControlsStringsLoc @inject IStringLocalizer FilterLoc - + + +
Loc @inject IStringLocalizer ControlStringsLoc - + + +
@if (_trace is { } trace) @@ -26,7 +31,7 @@

@GetResourceName(headerSpan.Source): @headerSpan.Name @OtlpHelpers.ToShortenedId(trace.TraceId) -

+
diff --git a/src/Aspire.Dashboard/Components/Pages/Traces.razor b/src/Aspire.Dashboard/Components/Pages/Traces.razor index 271ed10dc8a..46caa3f2198 100644 --- a/src/Aspire.Dashboard/Components/Pages/Traces.razor +++ b/src/Aspire.Dashboard/Components/Pages/Traces.razor @@ -13,7 +13,12 @@ @inject IStringLocalizer ControlsStringsLoc @implements IDisposable - + + +
diff --git a/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs b/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs index 13e0e1f3547..42e64608606 100644 --- a/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs +++ b/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs @@ -26,7 +26,7 @@ public void Render_DashboardClientDisabled_Success() Services.AddSingleton(new MockKnownPropertyLookup()); // Act - var cut = RenderComponent(); + var cut = RenderComponent(); // Assert cut.MarkupMatches("Aspire"); @@ -41,7 +41,7 @@ public void Render_DashboardClientEnabled_HtmlInName_Success() Services.AddSingleton(); // Act - var cut = RenderComponent(); + var cut = RenderComponent(); // Assert cut.MarkupMatches("<marquee>An HTML title!</marquee>"); From ee207f16f83b9d7eda631cbf61006a439543ba3a Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Thu, 19 Dec 2024 13:50:16 -0500 Subject: [PATCH 3/4] rename AspirePageTitle back to ApplicationName --- .../Controls/{AspirePageTitle.razor => ApplicationName.razor} | 0 .../{AspirePageTitle.razor.cs => ApplicationName.razor.cs} | 2 +- src/Aspire.Dashboard/Components/Layout/MainLayout.razor | 4 ++-- src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor | 2 +- src/Aspire.Dashboard/Components/Pages/Login.razor | 4 ++-- src/Aspire.Dashboard/Components/Pages/Metrics.razor | 2 +- src/Aspire.Dashboard/Components/Pages/Resources.razor | 2 +- src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor | 2 +- src/Aspire.Dashboard/Components/Pages/TraceDetail.razor | 2 +- src/Aspire.Dashboard/Components/Pages/Traces.razor | 2 +- .../Controls/ApplicationNameTests.cs | 4 ++-- 11 files changed, 13 insertions(+), 13 deletions(-) rename src/Aspire.Dashboard/Components/Controls/{AspirePageTitle.razor => ApplicationName.razor} (100%) rename src/Aspire.Dashboard/Components/Controls/{AspirePageTitle.razor.cs => ApplicationName.razor.cs} (96%) diff --git a/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor b/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor similarity index 100% rename from src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor rename to src/Aspire.Dashboard/Components/Controls/ApplicationName.razor diff --git a/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor.cs b/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs similarity index 96% rename from src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor.cs rename to src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs index c5a313d657a..4193596f1ec 100644 --- a/src/Aspire.Dashboard/Components/Controls/AspirePageTitle.razor.cs +++ b/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs @@ -8,7 +8,7 @@ namespace Aspire.Dashboard.Components; -public sealed partial class AspirePageTitle : ComponentBase, IDisposable +public sealed partial class ApplicationName : ComponentBase, IDisposable { private CancellationTokenSource? _disposalCts; diff --git a/src/Aspire.Dashboard/Components/Layout/MainLayout.razor b/src/Aspire.Dashboard/Components/Layout/MainLayout.razor index 63921499024..fe5dc78c97b 100644 --- a/src/Aspire.Dashboard/Components/Layout/MainLayout.razor +++ b/src/Aspire.Dashboard/Components/Layout/MainLayout.razor @@ -16,7 +16,7 @@ {
diff --git a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor index 6f22c3c2ffd..69447df45d0 100644 --- a/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor @@ -6,7 +6,7 @@ @namespace Aspire.Dashboard.Components.Pages - diff --git a/src/Aspire.Dashboard/Components/Pages/Login.razor b/src/Aspire.Dashboard/Components/Pages/Login.razor index 164d4e2f756..06d7b8b137a 100644 --- a/src/Aspire.Dashboard/Components/Pages/Login.razor +++ b/src/Aspire.Dashboard/Components/Pages/Login.razor @@ -4,7 +4,7 @@ @attribute [AllowAnonymous] @inject IStringLocalizer Loc - +
@@ -15,7 +15,7 @@
-

+

@* diff --git a/src/Aspire.Dashboard/Components/Pages/Metrics.razor b/src/Aspire.Dashboard/Components/Pages/Metrics.razor index b8be7bdf8e7..58bd20473ad 100644 --- a/src/Aspire.Dashboard/Components/Pages/Metrics.razor +++ b/src/Aspire.Dashboard/Components/Pages/Metrics.razor @@ -11,7 +11,7 @@ @inject IStringLocalizer ControlsStringsLoc - diff --git a/src/Aspire.Dashboard/Components/Pages/Resources.razor b/src/Aspire.Dashboard/Components/Pages/Resources.razor index 73a6d373557..878261ec091 100644 --- a/src/Aspire.Dashboard/Components/Pages/Resources.razor +++ b/src/Aspire.Dashboard/Components/Pages/Resources.razor @@ -10,7 +10,7 @@ @inject IStringLocalizer ControlsStringsLoc @inject IStringLocalizer ColumnsLoc - + @{ var showDetailsView = SelectedResource is not null; diff --git a/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor b/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor index 1a4ff059bef..b915d04af56 100644 --- a/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor @@ -14,7 +14,7 @@ @inject IStringLocalizer FilterLoc - diff --git a/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor b/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor index b6d38fffbec..2f1c48d8499 100644 --- a/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor +++ b/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor @@ -10,7 +10,7 @@ @inject IStringLocalizer ControlStringsLoc - diff --git a/src/Aspire.Dashboard/Components/Pages/Traces.razor b/src/Aspire.Dashboard/Components/Pages/Traces.razor index 46caa3f2198..9ea474ecaff 100644 --- a/src/Aspire.Dashboard/Components/Pages/Traces.razor +++ b/src/Aspire.Dashboard/Components/Pages/Traces.razor @@ -14,7 +14,7 @@ @implements IDisposable - diff --git a/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs b/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs index 42e64608606..13e0e1f3547 100644 --- a/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs +++ b/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs @@ -26,7 +26,7 @@ public void Render_DashboardClientDisabled_Success() Services.AddSingleton(new MockKnownPropertyLookup()); // Act - var cut = RenderComponent(); + var cut = RenderComponent(); // Assert cut.MarkupMatches("Aspire"); @@ -41,7 +41,7 @@ public void Render_DashboardClientEnabled_HtmlInName_Success() Services.AddSingleton(); // Act - var cut = RenderComponent(); + var cut = RenderComponent(); // Assert cut.MarkupMatches("<marquee>An HTML title!</marquee>"); From 094e629663134e28b863c3dcc3249ed7f4c7686b Mon Sep 17 00:00:00 2001 From: Adam Ratzman Date: Mon, 27 Jan 2025 17:44:33 -0500 Subject: [PATCH 4/4] Add test, update metrics and trace detail titles --- .../Controls/ApplicationName.razor.cs | 8 ++--- .../Components/Pages/Metrics.razor | 16 +++++++++- .../Components/Pages/TraceDetail.razor | 7 ++-- .../Components/Pages/TraceDetail.razor.cs | 11 +++++++ .../Controls/ApplicationNameTests.cs | 32 +++++++++++++++++++ 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs b/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs index 4193596f1ec..0c7397fc662 100644 --- a/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs +++ b/src/Aspire.Dashboard/Components/Controls/ApplicationName.razor.cs @@ -13,13 +13,13 @@ public sealed partial class ApplicationName : ComponentBase, IDisposable private CancellationTokenSource? _disposalCts; [Parameter] - public string? AdditionalText { get; init; } + public string? AdditionalText { get; set; } [Parameter] - public string? ResourceName { get; init; } + public string? ResourceName { get; set; } [Parameter] - public IStringLocalizer? Loc { get; init; } + public IStringLocalizer? Loc { get; set; } [Inject] public required IDashboardClient DashboardClient { get; init; } @@ -49,7 +49,7 @@ protected override void OnParametersSet() applicationName = DashboardClient.ApplicationName; } - _pageTitle = AdditionalText is null + _pageTitle = string.IsNullOrEmpty(AdditionalText) ? applicationName : $"{applicationName} ({AdditionalText})"; } diff --git a/src/Aspire.Dashboard/Components/Pages/Metrics.razor b/src/Aspire.Dashboard/Components/Pages/Metrics.razor index efa7a677fcb..bddb1c6146c 100644 --- a/src/Aspire.Dashboard/Components/Pages/Metrics.razor +++ b/src/Aspire.Dashboard/Components/Pages/Metrics.razor @@ -11,8 +11,22 @@ @inject IStringLocalizer ControlsStringsLoc + @{ + string? additionalText; + if (PageViewModel.SelectedApplication.Id is { ReplicaSetName: { } replicaSetName }) + { + additionalText = PageViewModel.SelectedInstrument is { } selectedInstrument + ? $"{replicaSetName} - {selectedInstrument.Name}" + : replicaSetName; + } + else + { + additionalText = null; + } + } + diff --git a/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor b/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor index 56b7a0ec516..0c8a9e6bc6d 100644 --- a/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor +++ b/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor @@ -11,7 +11,7 @@ @@ -24,12 +24,9 @@ MobileToolbarButtonText="@Loc[nameof(Dashboard.Resources.TraceDetail.TraceDetailMobileToolbarButtonText)]" IsSummaryDetailsViewOpen="@(SelectedSpan is not null)"> - @{ - var headerSpan = trace.RootOrFirstSpan; - } diff --git a/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor.cs b/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor.cs index 2889cc39cbf..722d94a8e9e 100644 --- a/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor.cs +++ b/src/Aspire.Dashboard/Components/Pages/TraceDetail.razor.cs @@ -95,6 +95,17 @@ private ValueTask> GetData(GridI }); } + private string? GetPageTitle() + { + if (_trace is null) + { + return null; + } + + var headerSpan = _trace.RootOrFirstSpan; + return $"{GetResourceName(headerSpan.Source)}: {headerSpan.Name}"; + } + private static Icon GetSpanIcon(OtlpSpan span) { switch (span.Kind) diff --git a/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs b/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs index 13e0e1f3547..a1d5023e778 100644 --- a/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs +++ b/tests/Aspire.Dashboard.Components.Tests/Controls/ApplicationNameTests.cs @@ -5,6 +5,7 @@ using Bunit; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; @@ -32,6 +33,29 @@ public void Render_DashboardClientDisabled_Success() cut.MarkupMatches("Aspire"); } + [Fact] + public void Render_With_Args() + { + // Arrange + Services.AddSingleton(new ConfigurationManager()); + Services.AddSingleton(NullLoggerFactory.Instance); + Services.AddSingleton(); + Services.AddSingleton(); + Services.AddSingleton(); + Services.AddSingleton(new MockKnownPropertyLookup()); + + // Act + var cut = RenderComponent(builder => + { + builder.Add(p => p.ResourceName, "{0} traces"); + builder.Add(p => p.Loc, new TestStringLocalizer()); + builder.Add(p => p.AdditionalText, "Hello World"); + }); + + // Assert + cut.MarkupMatches("Localized:Aspire traces (Hello World)"); + } + [Fact] public void Render_DashboardClientEnabled_HtmlInName_Success() { @@ -57,4 +81,12 @@ private sealed class MockDashboardClient : IDashboardClient public IAsyncEnumerable> SubscribeConsoleLogs(string resourceName, CancellationToken cancellationToken) => throw new NotImplementedException(); public Task SubscribeResourcesAsync(CancellationToken cancellationToken) => throw new NotImplementedException(); } + + private sealed class TestStringLocalizer : IStringLocalizer + { + public LocalizedString this[string name] => new LocalizedString(name, $"Localized:{name}"); + public LocalizedString this[string name, params object[] arguments] => new LocalizedString(name, $"Localized:{name}:" + string.Join("+", arguments)); + + public IEnumerable GetAllStrings(bool includeParentCultures) => []; + } }