| File: Model\DashboardMessageBarService.cs | Web Access |
| Project: src\src\Aspire.Dashboard\Aspire.Dashboard.csproj (Aspire.Dashboard) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Dashboard.Components.Controls; using Microsoft.FluentUI.AspNetCore.Components; namespace Aspire.Dashboard.Model; public sealed class DashboardMessageBarContent { public string? Title { get; init; } public required string Message { get; init; } public bool UseMarkupString { get; init; } public bool AllowDismiss { get; init; } = true; public string? LinkText { get; init; } public string? LinkUrl { get; init; } public string? PrimaryAction { get; init; } public string? SecondaryAction { get; init; } } public sealed class DashboardMessageBarReference( IMessageBarInstance instance, Task<MessageBarResult> result, Microsoft.FluentUI.AspNetCore.Components.INotificationService notificationService) { public IMessageBarInstance Instance => instance; public Task<MessageBarResult> Result => result; public Task CloseAsync(object? data = null) { return notificationService.CloseAsync(instance, data); } } public sealed class DashboardMessageBarService(Microsoft.FluentUI.AspNetCore.Components.INotificationService notificationService) { public async Task<DashboardMessageBarReference> ShowAsync( DashboardMessageBarContent content, MessageBarIntent intent, string section, Func<MessageBarResult, Task>? onClose = null) { var opened = new TaskCompletionSource<IMessageBarInstance>(TaskCreationOptions.RunContinuationsAsynchronously); var options = new MessageBarOptions { Intent = intent, Section = section, AllowDismiss = content.AllowDismiss, ResultTiming = MessageBarResultTiming.Closed, OnStatusChange = args => { if (args.Status == MessageBarLifecycleStatus.Visible && args.Instance is { } instance) { opened.TrySetResult(instance); } } }; options.Parameters[nameof(DashboardMessageBar.Content)] = content; var resultTask = notificationService.ShowMessageBarAsync<DashboardMessageBar>(options); var instance = await WaitForVisibleAsync(opened.Task, resultTask).ConfigureAwait(false); var reference = new DashboardMessageBarReference(instance, resultTask, notificationService); if (onClose is not null) { _ = InvokeOnCloseAsync(resultTask, onClose); } return reference; } internal static async Task<IMessageBarInstance> WaitForVisibleAsync( Task<IMessageBarInstance> openedTask, Task<MessageBarResult> resultTask) { var firstCompleted = await Task.WhenAny(openedTask, resultTask).ConfigureAwait(false); if (firstCompleted == openedTask) { return await openedTask.ConfigureAwait(false); } await resultTask.ConfigureAwait(false); throw new InvalidOperationException("The message bar closed before becoming visible."); } private static async Task InvokeOnCloseAsync(Task<MessageBarResult> resultTask, Func<MessageBarResult, Task> onClose) { var result = await resultTask.ConfigureAwait(false); await onClose(result).ConfigureAwait(false); } }