Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,80 +1,83 @@
@using Aspire.Dashboard.Model
@namespace Aspire.Dashboard.Components

@if (DisplayedEndpoints.Count == 1)
@if (DisplayedEndpoints.Count > 0)
{
var displayedEndpoint = DisplayedEndpoints[0];
if (displayedEndpoint.Url != null)
{
<a href="@displayedEndpoint.Url" target="_blank">@displayedEndpoint.Text</a>
}
else
{
@displayedEndpoint.Text
}
}
else
{
<FluentOverflow Class="endpoint-overflow">
<ChildContent>
@for (var i = 0; i < DisplayedEndpoints.Count; i++)
<div class="endpoint-container">
<div class="endpoint-first">
@WriteEndpoint(DisplayedEndpoints[0])
@if (DisplayedEndpoints.Count > 1)
{
var displayedEndpoint = DisplayedEndpoints[i];
var isLast = i == DisplayedEndpoints.Count - 1;

<FluentOverflowItem Data="displayedEndpoint">
@if (displayedEndpoint.Url != null)
{
<a href="@displayedEndpoint.Url" target="_blank">@displayedEndpoint.Text</a>
}
else
{
@displayedEndpoint.Text
}
@if (!isLast)
{
<span>,</span>
}
</FluentOverflowItem>
}
</ChildContent>
<MoreButtonTemplate Context="overflow">
<FluentButton Appearance="Appearance.Accent" OnClick="() => _popoverVisible = !_popoverVisible" Class="endpoint-button">
@($"+{overflow.ItemsOverflow.Count()}")
</FluentButton>
</MoreButtonTemplate>
<OverflowTemplate Context="overflow">
@{
var items = overflow.ItemsOverflow.ToList();
<span>,&nbsp;</span>
}
<FluentPopover AnchorId="@overflow.IdMoreButton" @bind-Open="_popoverVisible" VerticalThreshold="200" AutoFocus="false">
<Header>
Endpoints
</Header>
<Body>
<div class="endpoint-popup">
@foreach (var item in items)
</div>
<div>
@if (DisplayedEndpoints.Count > 1)
{
<FluentOverflow Class="endpoint-overflow">
<ChildContent>
@for (var i = 1; i < DisplayedEndpoints.Count; i++)
{
var d = (DisplayedEndpoint)item.Data!;
<div class="endpoint-link">
@if (d.Url != null)
{
<a href="@d.Url" target="_blank" title="@d.Text">@d.Text</a>
}
else
var displayedEndpoint = DisplayedEndpoints[i];
var isLast = i == DisplayedEndpoints.Count - 1;

<FluentOverflowItem Data="displayedEndpoint">
@WriteEndpoint(displayedEndpoint)

@if (!isLast)
{
<span title="@d.Text">@d.Text</span>
<span>,</span>
}
</div>
</FluentOverflowItem>
}
</div>
</Body>
</FluentPopover>
</OverflowTemplate>
</FluentOverflow>
</ChildContent>
<MoreButtonTemplate Context="overflow">
<FluentButton Appearance="Appearance.Accent" OnClick="() => _popoverVisible = !_popoverVisible" Class="endpoint-button">
@($"+{overflow.ItemsOverflow.Count()}")
</FluentButton>
</MoreButtonTemplate>
<OverflowTemplate Context="overflow">
@{
var items = overflow.ItemsOverflow.ToList();
}
<FluentPopover AnchorId="@overflow.IdMoreButton" @bind-Open="_popoverVisible" VerticalThreshold="200" AutoFocus="false">
<Header>
Endpoints
</Header>
<Body>
<div class="endpoint-popup">
@foreach (var item in items)
{
var d = (DisplayedEndpoint)item.Data!;
<div class="endpoint-link">
@WriteEndpoint(d)
</div>
}
</div>
</Body>
</FluentPopover>
</OverflowTemplate>
</FluentOverflow>
}
</div>
</div>
}

@if (!string.IsNullOrEmpty(AdditionalMessage))
{
<div>@AdditionalMessage</div>
}

@code {
RenderFragment WriteEndpoint(DisplayedEndpoint displayedEndpoint)
{
if (displayedEndpoint.Url != null)
{
return @<a href="@displayedEndpoint.Url" target="_blank">@displayedEndpoint.Text</a>;
}
else
{
return @<span title="@displayedEndpoint.Text">@displayedEndpoint.Text</span>;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
::deep.endpoint-container {
display: grid;
/*
Two columns:
-The first endpoint. Max width is the width of the endpoint text, min width is nothing so the overflow button is always displayed.
-The endpoint overflow. Max width is all remaining space, min width is the overflow button.
*/
grid-template-columns: minmax(0px, max-content) minmax(min-content, auto);
}

::deep.endpoint-first {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}

::deep.endpoint-list {
margin: 0;
padding: 0;
Expand Down
2 changes: 1 addition & 1 deletion tests/Aspire.Workload.Tests/StarterTemplateRunTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public StarterTemplateRunTestsBase(T fixture, ITestOutputHelper testOutput)

[Fact]
[ActiveIssue("https://github.com/dotnet/aspire/issues/4623", typeof(PlaywrightProvider), nameof(PlaywrightProvider.DoesNotHavePlaywrightSupport))]
public async Task ResourcesShowUpOnDashboad()
public async Task ResourcesShowUpOnDashboard()
{
await using var context = await CreateNewBrowserContextAsync();
await CheckDashboardHasResourcesAsync(
Expand Down
20 changes: 9 additions & 11 deletions tests/Aspire.Workload.Tests/WorkloadTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,25 +105,23 @@ protected static async Task<ResourceRow[]> CheckDashboardHasResourcesAsync(IPage
int matchingEndpoints = 0;
var expectedEndpoints = expectedRow.Endpoints;

string[] endpointsFound =
var endpointsFound =
(await rowLoc.Locator("//div[@class='fluent-overflow-item']").AllAsync())
.Select(async e => await e.InnerTextAsync())
.Select(t => t.Result.Trim(','))
.ToArray();
// FIXME: this could still return "+2"
if (endpointsFound.Length == 0)
{
var cellText = await cellLocs[5].InnerTextAsync();
endpointsFound = cellText.Trim().Split(',', StringSplitOptions.RemoveEmptyEntries);
}
if (expectedEndpoints.Length != endpointsFound.Length)
.ToList();

var firstEndpoint = await rowLoc.Locator("//div[@class='endpoint-first']").InnerTextAsync();
endpointsFound.Insert(0, firstEndpoint.Trim().Trim(','));

if (expectedEndpoints.Length != endpointsFound.Count)
{
// _testOutput.WriteLine($"For resource '{resourceName}, found ")
// _testOutput.WriteLine($"-- expected: {expectedEndpoints.Length} found: {endpointsFound.Length}, expected: {string.Join(',', expectedEndpoints)} found: {string.Join(',', endpointsFound)} for {resourceName}");
continue;
}

AssertEqual(expectedEndpoints.Length, endpointsFound.Length, $"#endpoints for {resourceName}");
AssertEqual(expectedEndpoints.Length, endpointsFound.Count, $"#endpoints for {resourceName}");

// endpointsFound: ["foo", "https://localhost:7589/weatherforecast"]
foreach (var endpointFound in endpointsFound)
Expand All @@ -142,7 +140,7 @@ protected static async Task<ResourceRow[]> CheckDashboardHasResourcesAsync(IPage
// Check 'Source' column
AssertEqual(expectedRow.Source, await cellLocs[4].InnerTextAsync(), $"Source for {resourceName}");

foundRows.Add(expectedRow with { Endpoints = endpointsFound });
foundRows.Add(expectedRow with { Endpoints = endpointsFound.ToArray() });
foundNames.Add(resourceName);
}
}
Expand Down
4 changes: 4 additions & 0 deletions tests/Shared/WorkloadTesting/BuildEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ static void CleanupTestRootPath()
}
}
}
catch (Exception ex)
{
throw new InvalidOperationException($"Error deleting '{TestRootPath}'.", ex);
}
}
}

Expand Down