-
Notifications
You must be signed in to change notification settings - Fork 736
Add command annotations and wire up #5538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,12 +2,12 @@ | |
| @using Aspire.Dashboard.Model | ||
| @using Microsoft.FluentUI.AspNetCore.Components | ||
|
|
||
| @foreach (var highlightedCommand in Commands.Where(c => c.IsHighlighted)) | ||
| @foreach (var highlightedCommand in Commands.Where(c => c.IsHighlighted && c.State != CommandViewModelState.Hidden)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be a maximum number of highlighted commands? Or rather only the first N highlighted commands?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe. It's easy to change if necessary. |
||
| { | ||
| <FluentButton Appearance="Appearance.Lightweight" Title="@(highlightedCommand.DisplayDescription ?? highlightedCommand.DisplayName)" OnClick="@(() => CommandSelected.InvokeAsync(highlightedCommand))"> | ||
| <FluentButton Appearance="Appearance.Lightweight" Title="@(highlightedCommand.DisplayDescription ?? highlightedCommand.DisplayName)" OnClick="@(() => CommandSelected.InvokeAsync(highlightedCommand))" Disabled="@(highlightedCommand.State == CommandViewModelState.Disabled)"> | ||
| @if (!string.IsNullOrEmpty(highlightedCommand.IconName) && CommandViewModel.ResolveIconName(highlightedCommand.IconName) is { } icon) | ||
| { | ||
| <FluentIcon Value="icon" /> | ||
| <FluentIcon Value="@icon" /> | ||
| } | ||
| else | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ protected override void OnParametersSet() | |
| OnClick = OnConsoleLogs.InvokeAsync | ||
| }); | ||
|
|
||
| var menuCommands = Commands.Where(c => !c.IsHighlighted).ToList(); | ||
| var menuCommands = Commands.Where(c => !c.IsHighlighted && c.State != CommandViewModelState.Hidden).ToList(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the context menu show all commands regardless of whether they are highlighted or not?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dunno. It's easy to change. |
||
| if (menuCommands.Count > 0) | ||
| { | ||
| _menuItems.Add(new MenuButtonItem { IsDivider = true }); | ||
|
|
@@ -63,7 +63,8 @@ protected override void OnParametersSet() | |
| Text = command.DisplayName, | ||
| Tooltip = command.DisplayDescription, | ||
| Icon = icon, | ||
| OnClick = () => CommandSelected.InvokeAsync(command) | ||
| OnClick = () => CommandSelected.InvokeAsync(command), | ||
| IsDisabled = command.State == CommandViewModelState.Disabled | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,7 +34,7 @@ | |
| Class="severity-icon" /> | ||
| } | ||
| } | ||
| else if (Resource.IsStartingOrBuildingOrWaiting()) | ||
| else if (Resource.IsUnusableTransitoryState()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a race with #5770 :) |
||
| { | ||
| <FluentIcon Icon="Icons.Regular.Size16.CircleHint" | ||
| Color="Color.Info" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,5 +12,6 @@ public enum KnownResourceState | |
| Running, | ||
| Building, | ||
| Hidden, | ||
| Waiting | ||
| Waiting, | ||
| Stopping | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using Aspire.Hosting.Dcp; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
|
|
||
| namespace Aspire.Hosting.ApplicationModel; | ||
|
|
||
| internal static class CommandsConfigurationExtensions | ||
| { | ||
| internal const string StartType = "start"; | ||
| internal const string StopType = "stop"; | ||
| internal const string RestartType = "restart"; | ||
|
|
||
| internal static IResourceBuilder<T> WithLifeCycleCommands<T>(this IResourceBuilder<T> builder) where T : IResource | ||
| { | ||
| builder.WithCommand( | ||
| type: StartType, | ||
| displayName: "Start", | ||
| executeCommand: async context => | ||
| { | ||
| var executor = context.ServiceProvider.GetRequiredService<ApplicationExecutor>(); | ||
|
|
||
| await executor.StartResourceAsync(context.ResourceName, context.CancellationToken).ConfigureAwait(false); | ||
| return CommandResults.Success(); | ||
| }, | ||
| updateState: context => | ||
| { | ||
| if (IsStarting(context.ResourceSnapshot.State?.Text)) | ||
| { | ||
| return ResourceCommandState.Disabled; | ||
| } | ||
| else if (IsStopped(context.ResourceSnapshot.State?.Text)) | ||
| { | ||
| return ResourceCommandState.Enabled; | ||
| } | ||
| else | ||
| { | ||
| return ResourceCommandState.Hidden; | ||
| } | ||
| }, | ||
| iconName: "Play", | ||
| isHighlighted: true); | ||
|
|
||
| builder.WithCommand( | ||
| type: StopType, | ||
| displayName: "Stop", | ||
| executeCommand: async context => | ||
| { | ||
| var executor = context.ServiceProvider.GetRequiredService<ApplicationExecutor>(); | ||
|
|
||
| await executor.StopResourceAsync(context.ResourceName, context.CancellationToken).ConfigureAwait(false); | ||
| return CommandResults.Success(); | ||
| }, | ||
| updateState: context => | ||
| { | ||
| if (IsWaiting(context.ResourceSnapshot.State?.Text) || IsStopping(context.ResourceSnapshot.State?.Text)) | ||
| { | ||
| return ResourceCommandState.Disabled; | ||
| } | ||
| else if (!IsStopped(context.ResourceSnapshot.State?.Text) && !IsStarting(context.ResourceSnapshot.State?.Text)) | ||
| { | ||
| return ResourceCommandState.Enabled; | ||
| } | ||
| else | ||
| { | ||
| return ResourceCommandState.Hidden; | ||
| } | ||
| }, | ||
| iconName: "Stop", | ||
| isHighlighted: true); | ||
|
|
||
| builder.WithCommand( | ||
| type: RestartType, | ||
| displayName: "Restart", | ||
| executeCommand: async context => | ||
| { | ||
| var executor = context.ServiceProvider.GetRequiredService<ApplicationExecutor>(); | ||
|
|
||
| await executor.StopResourceAsync(context.ResourceName, context.CancellationToken).ConfigureAwait(false); | ||
| await executor.StartResourceAsync(context.ResourceName, context.CancellationToken).ConfigureAwait(false); | ||
| return CommandResults.Success(); | ||
| }, | ||
| updateState: context => | ||
| { | ||
| if (IsWaiting(context.ResourceSnapshot.State?.Text) || IsStarting(context.ResourceSnapshot.State?.Text) || IsStopping(context.ResourceSnapshot.State?.Text) || IsStopped(context.ResourceSnapshot.State?.Text)) | ||
| { | ||
| return ResourceCommandState.Disabled; | ||
| } | ||
| else | ||
| { | ||
| return ResourceCommandState.Enabled; | ||
| } | ||
| }, | ||
| iconName: "ArrowCounterclockwise", | ||
| isHighlighted: false); | ||
|
|
||
| return builder; | ||
|
|
||
| static bool IsStopped(string? state) => state is "Exited" or "Finished" or "FailedToStart"; | ||
| static bool IsStopping(string? state) => state is "Stopping"; | ||
| static bool IsStarting(string? state) => state is "Starting"; | ||
| static bool IsWaiting(string? state) => state is "Waiting"; | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.