Skip to content
Closed
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
4 changes: 2 additions & 2 deletions src/Aspire.Dashboard/Components/Pages/ConsoleLogs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private async ValueTask LoadLogsAsync()
{
var task = _logViewer.SetLogSourceAsync(
subscription,
convertTimestampsFromUtc: _selectedResource is ContainerViewModel);
convertTimestampsFromUtc: _selectedResource.ResourceType is "Container");

_initialisedSuccessfully = true;
_status = Loc[Dashboard.Resources.ConsoleLogs.ConsoleLogsWatchingLogs];
Expand All @@ -168,7 +168,7 @@ private async ValueTask LoadLogsAsync()
else
{
_initialisedSuccessfully = false;
_status = Loc[_selectedResource is ContainerViewModel
_status = Loc[_selectedResource.ResourceType is "Container"
? Dashboard.Resources.ConsoleLogs.ConsoleLogsFailedToInitialize
: Dashboard.Resources.ConsoleLogs.ConsoleLogsLogsNotYetAvailable];
}
Expand Down
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Components/Pages/Resources.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public partial class Resources : ComponentBase, IDisposable
private readonly CancellationTokenSource _watchTaskCancellationTokenSource = new();
private readonly Dictionary<string, ResourceViewModel> _resourcesMap = [];
// TODO populate resource types from server data
private readonly ImmutableArray<string> _allResourceTypes = ["Project", "Executable", "Container"];
private readonly ImmutableArray<string> _allResourceTypes = [KnownResourceTypes.Project, KnownResourceTypes.Executable, KnownResourceTypes.Container];
private readonly HashSet<string> _visibleResourceTypes;
private string _filter = "";
private bool _isTypeFilterVisible;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@

<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
<span><FluentHighlighter HighlightedText="@FilterText" Text="@FormatName(Resource)" /></span>
@if (Resource is ContainerViewModel containerViewModel)
@if (Resource.TryGetContainerId(out var containerId))
{
<div class="subtext">
<GridValue Value="@containerViewModel.ContainerId"
<GridValue Value="@containerId"
MaxDisplayLength="8"
EnableHighlighting="false"
PreCopyToolTip="@Loc[Columns.ResourceNameDisplayCopyContainerIdText]"
ToolTip="@string.Format(Loc[Columns.ResourceNameDisplayContainerIdText], containerViewModel.ContainerId)"/>
ToolTip="@string.Format(Loc[Columns.ResourceNameDisplayContainerIdText], containerId)"/>
</div>
}
else if (Resource is ExecutableViewModel executableViewModel)
else if (Resource.TryGetProcessId(out int processId))
{
// NOTE projects are also executables, so this will handle both
var title = string.Format(Loc[Columns.ResourceNameDisplayProcessIdText], executableViewModel.ProcessId);
<span class="subtext" title="@title" aria-label="@title">@executableViewModel.ProcessId</span>
var title = string.Format(Loc[Columns.ResourceNameDisplayProcessIdText], processId);
<span class="subtext" title="@title" aria-label="@title">@processId</span>
}
</FluentStack>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,71 @@
@using Aspire.Dashboard.Resources
@inject IStringLocalizer<Columns> Loc

@if (Resource is ProjectViewModel projectViewModel)
@if (Resource.IsProject() && Resource.TryGetProjectPath(out var projectPath))
{
// NOTE projects are also executables, so we have to check for projects first
<GridValue Value="@Path.GetFileName(projectViewModel.ProjectPath)"
ValueToCopy="@projectViewModel.ProjectPath"
<GridValue Value="@Path.GetFileName(projectPath)"
ValueToCopy="@projectPath"
EnableHighlighting="true"
HighlightText="@FilterText"
PreCopyToolTip="@Loc[Columns.SourceColumnSourceCopyFullPathToClipboard]"
ToolTip="@projectViewModel.ProjectPath" />
ToolTip="@projectPath" />
}
else if (Resource is ExecutableViewModel executableViewModel)
else if (Resource.TryGetExecutablePath(out var executablePath) && Resource.TryGetWorkingDirectory(out var workingDirectory))
{
var arguments = string.Join(" ", executableViewModel.Arguments ?? []);
var fullCommandLine = $"{executableViewModel.ExecutablePath} {arguments}";
Resource.TryGetExecutableArguments(out var arguments);
var argumentsString = arguments.IsDefaultOrEmpty ? "" : string.Join(" ", arguments);
var fullCommandLine = $"{executablePath} {argumentsString}";

<GridValue Value="@Path.GetFileName(executableViewModel.ExecutablePath)"
<GridValue Value="@Path.GetFileName(executablePath)"
ValueToCopy="@fullCommandLine"
EnableHighlighting="true"
HighlightText="@FilterText"
PreCopyToolTip="@Loc[Columns.SourceColumnSourceCopyFullPathToClipboard]"
ToolTip="@executableViewModel.ExecutablePath">
ToolTip="@executablePath">
<ContentAfterValue>
<span class="subtext">@arguments</span>
<span class="subtext">@argumentsString</span>
</ContentAfterValue>
</GridValue>

<div class="ellipsis-overflow" title="@executableViewModel.WorkingDirectory" aria-label="@executableViewModel.WorkingDirectory">@string.Format(Loc[Columns.SourceColumnDisplayWorkingDirectory], executableViewModel.WorkingDirectory?.TrimMiddle(35))</div>
<div class="ellipsis-overflow" title="@workingDirectory" aria-label="@workingDirectory">@string.Format(Loc[Columns.SourceColumnDisplayWorkingDirectory], workingDirectory?.TrimMiddle(35))</div>
}
else if (Resource is ContainerViewModel containerViewModel)
else if (Resource.TryGetContainerImage(out var containerImage) && Resource.TryGetContainerPorts(out var ports))
{
var ports = string.Join("; ", containerViewModel.Ports);
<GridValue Value="@containerViewModel.Image"
var portsString = string.Join("; ", ports);
<GridValue Value="@containerImage"
EnableHighlighting="true"
HighlightText="@FilterText"
PreCopyToolTip="@Loc[Columns.SourceColumnSourceCopyContainerToClipboard]"
ToolTip="@containerViewModel.Image">
ToolTip="@containerImage">
<ContentAfterValue>
@if (containerViewModel.Ports.Length > 0)
@if (ports.Length > 0)
{
var title = string.Format(
Loc[containerViewModel.Ports.Length == 1
Loc[ports.Length == 1
? Columns.SourceColumnDisplayPort
: Columns.SourceColumnDisplayPorts],
ports);
<span class="subtext" aria-label="@title">@title</span>
}
</ContentAfterValue>
</GridValue>
</GridValue>
<FluentStack Orientation="Orientation.Horizontal">
@if (containerViewModel.Command is not null)
@if (Resource.TryGetContainerCommand(out var command))
{
<div class="ellipsis-overflow" title="@Loc[Columns.SourceColumnDisplayContainerCommandTitle]">@Loc[Columns.SourceColumnDisplayContainerCommand, containerViewModel.Command]</div>
<div class="ellipsis-overflow" title="@Loc[Columns.SourceColumnDisplayContainerCommandTitle]">@Loc[Columns.SourceColumnDisplayContainerCommand, command]</div>
}
@if (containerViewModel.Args is not null)
@if (Resource.TryGetContainerArgs(out var args))
{
var args = string.Join(" ", containerViewModel.Args);
<div class="ellipsis-overflow" title="@Loc[Columns.SourceColumnDisplayContainerArgsTitle]">@args</div>
var argsString = string.Join(" ", args);
<div class="ellipsis-overflow" title="@Loc[Columns.SourceColumnDisplayContainerArgsTitle]">@argsString</div>
}
</FluentStack>
}
else
{
// TODO we need to add support for arbitrary resource types. Until then, they'll just show an empty source column.
}

@code {
[Parameter, EditorRequired]
Expand Down
26 changes: 0 additions & 26 deletions src/Aspire.Dashboard/Model/ContainerViewModel.cs

This file was deleted.

22 changes: 0 additions & 22 deletions src/Aspire.Dashboard/Model/ExecutableViewModel.cs

This file was deleted.

4 changes: 3 additions & 1 deletion src/Aspire.Dashboard/Model/IResourceService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Immutable;

namespace Aspire.Dashboard.Model;

/// <summary>
Expand Down Expand Up @@ -34,5 +36,5 @@ public interface IResourceService
}

public sealed record ResourceSubscription(
List<ResourceViewModel> Snapshot,
ImmutableArray<ResourceViewModel> InitialState,
IAsyncEnumerable<ResourceChange> Subscription);
12 changes: 12 additions & 0 deletions src/Aspire.Dashboard/Model/KnownResourceTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Aspire.Dashboard.Model;

// TODO use these constants throughout
public static class KnownResourceTypes
{
public const string Executable = "Executable";
public const string Project = "Project";
public const string Container = "Container";
}
14 changes: 0 additions & 14 deletions src/Aspire.Dashboard/Model/ProjectViewModel.cs

This file was deleted.

39 changes: 39 additions & 0 deletions src/Aspire.Dashboard/Model/ResourceDataKeys.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Aspire.Dashboard.Model;

public static class ResourceDataKeys
{
public static class Resource
{
public const string Uid = "resource.uid";
public const string Name = "resource.name";
public const string Type = "resource.type";
public const string DisplayName = "resource.displayName";
public const string State = "resource.state";
public const string CreateTime = "resource.createTime";
}

public static class Container
{
public const string Id = "container.id";
public const string Image = "container.image";
public const string Ports = "container.ports";
public const string Command = "container.command";
public const string Args = "container.args";
}

public static class Executable
{
public const string Path = "executable.path";
public const string Pid = "executable.pid";
public const string WorkDir = "executable.workDir";
public const string Args = "executable.args";
}

public static class Project
{
public const string Path = "project.path";
}
}
Loading