Skip to content

Commit a5b3bcf

Browse files
authored
Add command annotations and wire up (#5538)
1 parent 4d80745 commit a5b3bcf

File tree

49 files changed

+1239
-285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1239
-285
lines changed

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
<PackageVersion Include="Grpc.Tools" Version="2.66.0" />
110110
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
111111
<PackageVersion Include="KubernetesClient" Version="14.0.9" />
112+
<PackageVersion Include="JsonPatch.Net" Version="3.1.1" />
112113
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.2" />
113114
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components" Version="4.9.3" />
114115
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="4.9.3" />

src/Aspire.Dashboard/Components/Controls/AspireMenuButton.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
}
2525
else
2626
{
27-
<FluentMenuItem OnClick="() => HandleItemClicked(item)" title="@item.Tooltip">
27+
<FluentMenuItem OnClick="() => HandleItemClicked(item)" title="@item.Tooltip" Disabled="@item.IsDisabled">
2828
@item.Text
2929
@if (item.Icon != null)
3030
{

src/Aspire.Dashboard/Components/Controls/ResourceActions.razor

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
@using Aspire.Dashboard.Model
33
@using Microsoft.FluentUI.AspNetCore.Components
44

5-
@foreach (var highlightedCommand in Commands.Where(c => c.IsHighlighted))
5+
@foreach (var highlightedCommand in Commands.Where(c => c.IsHighlighted && c.State != CommandViewModelState.Hidden))
66
{
7-
<FluentButton Appearance="Appearance.Lightweight" Title="@(highlightedCommand.DisplayDescription ?? highlightedCommand.DisplayName)" OnClick="@(() => CommandSelected.InvokeAsync(highlightedCommand))">
7+
<FluentButton Appearance="Appearance.Lightweight" Title="@(highlightedCommand.DisplayDescription ?? highlightedCommand.DisplayName)" OnClick="@(() => CommandSelected.InvokeAsync(highlightedCommand))" Disabled="@(highlightedCommand.State == CommandViewModelState.Disabled)">
88
@if (!string.IsNullOrEmpty(highlightedCommand.IconName) && CommandViewModel.ResolveIconName(highlightedCommand.IconName) is { } icon)
99
{
10-
<FluentIcon Value="icon" />
10+
<FluentIcon Value="@icon" />
1111
}
1212
else
1313
{

src/Aspire.Dashboard/Components/Controls/ResourceActions.razor.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ protected override void OnParametersSet()
4949
OnClick = OnConsoleLogs.InvokeAsync
5050
});
5151

52-
var menuCommands = Commands.Where(c => !c.IsHighlighted).ToList();
52+
var menuCommands = Commands.Where(c => !c.IsHighlighted && c.State != CommandViewModelState.Hidden).ToList();
5353
if (menuCommands.Count > 0)
5454
{
5555
_menuItems.Add(new MenuButtonItem { IsDivider = true });
@@ -63,7 +63,8 @@ protected override void OnParametersSet()
6363
Text = command.DisplayName,
6464
Tooltip = command.DisplayDescription,
6565
Icon = icon,
66-
OnClick = () => CommandSelected.InvokeAsync(command)
66+
OnClick = () => CommandSelected.InvokeAsync(command),
67+
IsDisabled = command.State == CommandViewModelState.Disabled
6768
});
6869
}
6970
}

src/Aspire.Dashboard/Components/Pages/Resources.razor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,16 +312,18 @@ private async Task ExecuteResourceCommandAsync(ResourceViewModel resource, Comma
312312

313313
var response = await DashboardClient.ExecuteResourceCommandAsync(resource.Name, resource.ResourceType, command, CancellationToken.None);
314314

315+
var messageResourceName = GetResourceName(resource);
316+
315317
if (response.Kind == ResourceCommandResponseKind.Succeeded)
316318
{
317-
ToastService.ShowSuccess(string.Format(CultureInfo.InvariantCulture, Loc[nameof(Dashboard.Resources.Resources.ResourceCommandSuccess)], command.DisplayName));
319+
ToastService.ShowSuccess(string.Format(CultureInfo.InvariantCulture, Loc[nameof(Dashboard.Resources.Resources.ResourceCommandSuccess)], command.DisplayName + " " + messageResourceName));
318320
}
319321
else
320322
{
321323
ToastService.ShowCommunicationToast(new ToastParameters<CommunicationToastContent>()
322324
{
323325
Intent = ToastIntent.Error,
324-
Title = string.Format(CultureInfo.InvariantCulture, Loc[nameof(Dashboard.Resources.Resources.ResourceCommandFailed)], command.DisplayName),
326+
Title = string.Format(CultureInfo.InvariantCulture, Loc[nameof(Dashboard.Resources.Resources.ResourceCommandFailed)], command.DisplayName + " " + messageResourceName),
325327
PrimaryAction = Loc[nameof(Dashboard.Resources.Resources.ResourceCommandToastViewLogs)],
326328
OnPrimaryAction = EventCallback.Factory.Create<ToastResult>(this, () => NavigationManager.NavigateTo(DashboardUrls.ConsoleLogsUrl(resource: resource.Name))),
327329
Content = new CommunicationToastContent()

src/Aspire.Dashboard/Components/ResourcesGridColumns/StateColumnDisplay.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
Class="severity-icon" />
3535
}
3636
}
37-
else if (Resource.IsStartingOrBuildingOrWaiting())
37+
else if (Resource.IsUnusableTransitoryState())
3838
{
3939
<FluentIcon Icon="Icons.Regular.Size16.CircleHint"
4040
Color="Color.Info"

src/Aspire.Dashboard/Extensions/ResourceViewModelExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public static bool IsStopped(this ResourceViewModel resource)
2727
return resource.KnownState is KnownResourceState.Exited or KnownResourceState.Finished or KnownResourceState.FailedToStart;
2828
}
2929

30-
public static bool IsStartingOrBuildingOrWaiting(this ResourceViewModel resource)
30+
public static bool IsUnusableTransitoryState(this ResourceViewModel resource)
3131
{
32-
return resource.KnownState is KnownResourceState.Starting or KnownResourceState.Building or KnownResourceState.Waiting;
32+
return resource.KnownState is KnownResourceState.Starting or KnownResourceState.Building or KnownResourceState.Waiting or KnownResourceState.Stopping;
3333
}
3434

3535
public static bool HasNoState(this ResourceViewModel resource) => string.IsNullOrEmpty(resource.State);

src/Aspire.Dashboard/Model/KnownResourceState.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ public enum KnownResourceState
1212
Running,
1313
Building,
1414
Hidden,
15-
Waiting
15+
Waiting,
16+
Stopping
1617
}

src/Aspire.Dashboard/Model/MenuButtonItem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ public class MenuButtonItem
1212
public string? Tooltip { get; set; }
1313
public Icon? Icon { get; set; }
1414
public Func<Task>? OnClick { get; set; }
15+
public bool IsDisabled { get; set; }
1516
}

src/Aspire.Dashboard/Model/ResourceViewModel.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,21 @@ public sealed class CommandViewModel
7474
private static readonly ConcurrentDictionary<string, CustomIcon?> s_iconCache = new();
7575

7676
public string CommandType { get; }
77+
public CommandViewModelState State { get; }
7778
public string DisplayName { get; }
7879
public string? DisplayDescription { get; }
7980
public string? ConfirmationMessage { get; }
8081
public Value? Parameter { get; }
8182
public bool IsHighlighted { get; }
8283
public string? IconName { get; }
8384

84-
public CommandViewModel(string commandType, string displayName, string? displayDescription, string? confirmationMessage, Value? parameter, bool isHighlighted, string? iconName)
85+
public CommandViewModel(string commandType, CommandViewModelState state, string displayName, string? displayDescription, string? confirmationMessage, Value? parameter, bool isHighlighted, string? iconName)
8586
{
8687
ArgumentException.ThrowIfNullOrWhiteSpace(commandType);
8788
ArgumentException.ThrowIfNullOrWhiteSpace(displayName);
8889

8990
CommandType = commandType;
91+
State = state;
9092
DisplayName = displayName;
9193
DisplayDescription = displayDescription;
9294
ConfirmationMessage = confirmationMessage;
@@ -118,6 +120,13 @@ public CommandViewModel(string commandType, string displayName, string? displayD
118120
}
119121
}
120122

123+
public enum CommandViewModelState
124+
{
125+
Enabled,
126+
Disabled,
127+
Hidden
128+
}
129+
121130
[DebuggerDisplay("Name = {Name}, Value = {Value}, FromSpec = {FromSpec}, IsValueMasked = {IsValueMasked}")]
122131
public sealed class EnvironmentVariableViewModel
123132
{

0 commit comments

Comments
 (0)