Skip to content

Fix dashboard UI to show no message for cancelled commands #10893

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Aug 9, 2025

This PR adds cancellation support to ExecuteCommandResult and fixes the dashboard UI to properly handle cancelled commands by showing no messages at all.

Problem

When a command uses the interaction service and the dialog is dismissed, the dashboard UI was incorrectly showing a success message. There was no clean way to cancel commands without displaying unwanted messages to users.

Solution

Extended ExecuteCommandResult with:

  1. New Canceled property - A boolean flag indicating whether the command was canceled by the user
  2. New CommandResults.Canceled() factory method - Produces a canceled result with Success = false and Canceled = true
  3. Enhanced logging - Cancelled commands are logged at Debug level instead of Information level to avoid unnecessary noise
  4. Dashboard integration - Updated mapping logic to properly return ExecuteCommandResultType.Canceled when commands are cancelled
  5. Multi-resource handling - Enhanced aggregation logic to properly distinguish between actual failures and cancellations
  6. Fixed dashboard UI behavior - Cancelled commands now close any existing toast and show no success or error messages

Usage Example

public static async Task<ExecuteCommandResult> ExecuteDeleteCommand(ExecuteCommandContext context)
{
    var interactionService = context.ServiceProvider.GetRequiredService<IInteractionService>();
    
    var result = await interactionService.PromptConfirmationAsync(
        "Confirm Delete", 
        $"Are you sure you want to delete '{context.ResourceName}'?");

    // Before: No clean way to handle cancellation
    if (result.Canceled)
        return new ExecuteCommandResult { Success = false, ErrorMessage = "Cancelled" }; // Shows error!

    // After: Clean cancellation support
    if (result.Canceled)
        return CommandResults.Canceled(); // No message shown in UI!
    
    // ... rest of command logic
}

Key Fix

The critical issue was in DashboardCommandExecutor.cs where cancelled commands were falling through to the error handling logic and showing success messages. The fix specifically handles ResourceCommandResponseKind.Cancelled by:

  • Closing any existing "starting" toast
  • Not showing any success or error messages
  • Providing a silent cancellation experience

Benefits

  • No unwanted messages when users dismiss interaction dialogs
  • Clean user experience - cancellation is silent as expected
  • Backward compatibility - existing Success/Failure patterns unchanged
  • Dashboard integration - properly maps to existing ExecuteCommandResultType.Canceled

This provides a much better user experience when users change their mind about executing commands, especially those that prompt for confirmation or input.

Fixes #10368.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@Copilot Copilot AI changed the title [WIP] Extend ExecuteCommandResult to support cancellation of interactions Extend ExecuteCommandResult to support cancellation of interactions Aug 9, 2025
@Copilot Copilot AI requested a review from davidfowl August 9, 2025 11:51
Copilot finished work on behalf of davidfowl August 9, 2025 11:51
@davidfowl davidfowl requested a review from JamesNK August 9, 2025 14:28
@davidfowl
Copy link
Member

@copilot The dashboard UI is still showing a success message when the command returns cancelled. It shouldn't show any UI at all.

When commands return cancelled results, the dashboard UI now:
- Closes any existing "starting" toast
- Shows no success or error message
- Provides a silent cancellation experience as expected

This fixes the issue where cancelled commands were incorrectly showing success messages in the dashboard UI.

Co-authored-by: davidfowl <[email protected]>
Copy link
Contributor Author

Copilot AI commented Aug 9, 2025

@copilot The dashboard UI is still showing a success message when the command returns cancelled. It shouldn't show any UI at all.

Fixed in ad77f0b. The dashboard UI now specifically handles cancelled commands by closing any existing toast and not showing any success or error messages. When a command returns ResourceCommandResponseKind.Cancelled, the UI provides a silent cancellation experience as expected.

@Copilot Copilot AI changed the title Extend ExecuteCommandResult to support cancellation of interactions Fix dashboard UI to show no message for cancelled commands Aug 9, 2025
Copilot finished work on behalf of davidfowl August 9, 2025 14:42
@davidfowl
Copy link
Member

@JamesNK this works but now I'm wondering it if should say command cancelled.

@davidfowl davidfowl marked this pull request as ready for review August 10, 2025 02:35
@Copilot Copilot AI review requested due to automatic review settings August 10, 2025 02:35
@davidfowl davidfowl requested a review from mitchdenny as a code owner August 10, 2025 02:35
@davidfowl
Copy link
Member

Screen.Recording.2025-08-09.at.10.31.39.PM.mov

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive cancellation support to command execution in Aspire, specifically addressing the issue where cancelled commands incorrectly displayed success messages in the dashboard UI. The solution introduces a new Canceled property to ExecuteCommandResult and updates the entire command execution pipeline to properly handle cancellations.

  • Introduces Canceled property and CommandResults.Canceled() factory method for clean cancellation handling
  • Updates command aggregation logic to distinguish between actual failures and user cancellations
  • Fixes dashboard UI to show no messages when commands are cancelled, providing a silent cancellation experience

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Aspire.Hosting/ApplicationModel/ResourceCommandAnnotation.cs Adds Canceled property to ExecuteCommandResult and CommandResults.Canceled() factory method
src/Aspire.Hosting/ApplicationModel/ResourceCommandService.cs Updates aggregation logic to separate cancellations from failures and adds debug logging for cancelled commands
src/Aspire.Hosting/Dashboard/DashboardServiceData.cs Maps cancelled results to ExecuteCommandResultType.Canceled
src/Aspire.Dashboard/Model/DashboardCommandExecutor.cs Handles cancelled commands by closing toasts without showing messages
src/Aspire.Hosting/api/Aspire.Hosting.cs Updates generated API surface with new cancellation members
tests/Aspire.Hosting.Tests/ResourceCommandServiceTests.cs Adds comprehensive test coverage for cancellation scenarios

Comment on lines 84 to 94
if (!results[i].Success)
{
failures.Add((names[i], results[i]));
if (results[i].Canceled)
{
cancellations.Add((names[i], results[i]));
}
else
{
failures.Add((names[i], results[i]));
}
}
Copy link
Preview

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The nested if-else structure could be simplified using pattern matching or early returns to improve readability. Consider restructuring to handle Success, Canceled, and Failed cases more clearly.

Suggested change
if (!results[i].Success)
{
failures.Add((names[i], results[i]));
if (results[i].Canceled)
{
cancellations.Add((names[i], results[i]));
}
else
{
failures.Add((names[i], results[i]));
}
}
var result = results[i];
if (result.Success)
{
// Do nothing, success case
continue;
}
else if (result.Canceled)
{
cancellations.Add((names[i], result));
}
else
{
failures.Add((names[i], result));
}

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extend ExecuteCommandResult to support cancellation of interactions
2 participants