187 lines
8.1 KiB
C#
187 lines
8.1 KiB
C#
using DevExpress.Blazor;
|
|
using Microsoft.AspNetCore.Components.Web;
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
namespace TIAMSharedUI.Shared.Components
|
|
{
|
|
/// <summary>
|
|
/// A MessageBox (async and synchronized) component to provide a way to show informational messages.
|
|
/// </summary>
|
|
public partial class PopupMessageBox
|
|
{
|
|
|
|
public static readonly string ButtonOk = "Ok";
|
|
public static readonly string ButtonCancel = "Cancel";
|
|
public static readonly string ButtonYes = "Yes";
|
|
public static readonly string ButtonNo = "No";
|
|
|
|
[Inject]
|
|
private NavigationManager Navigation { get; set; } = default!;
|
|
|
|
/// <summary>
|
|
/// The MessageBox popup. This is a DxPopup that is called asynchronously so it is displayed and control returns
|
|
/// to the caller.
|
|
/// </summary>
|
|
private DxPopup MessageBoxPopup { get; set; } = default!;
|
|
|
|
/// <summary>
|
|
/// The header text in the MessageBox popup. This is a MarkupString so do not put any user entered text in this!
|
|
/// </summary>
|
|
private string HeaderText { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// The message text in the MessageBox popup. This is a MarkupString so do not put any user entered text in this!
|
|
/// </summary>
|
|
private string MessageHtml { get; set; } = string.Empty;
|
|
|
|
private Func<string, object?, Task>? OnClick { get; set; }
|
|
|
|
private Func<object?, Task>? OnClose { get; set; }
|
|
|
|
/// <summary>
|
|
/// This is passed in in the call to Show() and returned in the calls to OnClick() and OnClose().
|
|
/// </summary>
|
|
private object? Tag { get; set; }
|
|
|
|
/// <summary>
|
|
/// Used to make the popup synchronous.
|
|
/// </summary>
|
|
private TaskCompletionSource<string> _taskCompletionSource = new();
|
|
|
|
/// <inheritdoc />
|
|
public PopupMessageBox()
|
|
{
|
|
ButtonVisible = new bool[4];
|
|
ButtonText = new string[4];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Displays the MessageBox. This is a static object so you can't create multiple instances of it. But you
|
|
/// can create another instance in the onClick or onCLose calls as the existing instance will be closed by
|
|
/// then.
|
|
/// </summary>
|
|
/// <param name="header">The header text in the message box.</param>
|
|
/// <param name="message">The main message in the message box. This is treated as html
|
|
/// so use <code>HttpUtility.HtmlEncode()</code> on any user generated text in the message.</param>
|
|
/// <param name="tag">Caller defined data returned in the OnClick/OnClose calls.</param>
|
|
/// <param name="onClick">Will call this method when a button is clicked. Passes the button text as the parameter.</param>
|
|
/// <param name="onClose">Will call this when the popup is closed. Including after receiving the onClick call.</param>
|
|
/// <param name="buttonText">The text for the button(s). Can be 1 .. 4 buttons.</param>
|
|
/// <returns>The task for the underlying DxPopup.ShowAsync() call.</returns>
|
|
public Task<bool> ShowAsync(string header, string message, object? tag, Func<string, object?, Task>? onClick,
|
|
Func<object?, Task>? onClose, params string[] buttonText)
|
|
{
|
|
|
|
HeaderText = header;
|
|
MessageHtml = message;
|
|
Tag = tag;
|
|
OnClick = onClick;
|
|
OnClose = onClose;
|
|
|
|
if (buttonText.Length == 0 || buttonText.Length > 4)
|
|
throw new ArgumentOutOfRangeException(nameof(buttonText), "Must have between 1 and 4 buttons");
|
|
Array.Clear(ButtonVisible);
|
|
Array.Clear(ButtonText);
|
|
for (var index = 0; index < buttonText.Length; index++)
|
|
{
|
|
ButtonVisible[index] = true;
|
|
ButtonText[index] = buttonText[index];
|
|
}
|
|
|
|
StateHasChanged();
|
|
|
|
return MessageBoxPopup.ShowAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Displays the MessageBox. Then when click OK, goes to the url. This is a static object so you can't create
|
|
/// multiple instances of it.
|
|
/// </summary>
|
|
/// <param name="header">The header text in the message box.</param>
|
|
/// <param name="message">The main message in the message box. This is treated as html
|
|
/// so use <code>HttpUtility.HtmlEncode()</code> on any user generated text in the message.</param>
|
|
/// <param name="url">The url to navigate to when click OK.</param>
|
|
/// <returns>The task for the underlying DxPopup.ShowAsync() call.</returns>
|
|
public Task<bool> ShowThenRedirectAsync(string header, string message, string url)
|
|
{
|
|
return ShowAsync(header, message, null,
|
|
(_, _) =>
|
|
{
|
|
Navigation.NavigateTo(url, false);
|
|
return Task.CompletedTask;
|
|
},
|
|
null, PopupMessageBox.ButtonOk);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Displays the MessageBox synchronously. Returns the text of the button clicked. This is a static object
|
|
/// so you can't create multiple instances of it. But you can create another instance when it returns as the
|
|
/// existing instance will be closed by then.
|
|
/// </summary>
|
|
/// <param name="header">The header text in the message box.</param>
|
|
/// <param name="message">The main message in the message box. This is treated as html
|
|
/// so use <code>HttpUtility.HtmlEncode()</code> on any user generated text in the message.</param>
|
|
/// <param name="buttonText">The text for the button(s). Can be 1 .. 4 buttons.</param>
|
|
/// <returns>The text of the button clicked.</returns>
|
|
public Task<string> Show(string header, string message, params string[] buttonText)
|
|
{
|
|
_taskCompletionSource = new TaskCompletionSource<string>();
|
|
|
|
ShowAsync(header, message, null, ShowOnClick, null, buttonText);
|
|
|
|
// we return the Task from the TaskCompletionSource that is not completed
|
|
return _taskCompletionSource.Task;
|
|
}
|
|
|
|
private Task ShowOnClick(string buttonText, object? tag)
|
|
{
|
|
// as this is called from the OnClick handler, the popup has been closed.
|
|
|
|
// sets the TaskCompletionSource to completed. Any await-ers will now complete
|
|
_taskCompletionSource.SetResult(buttonText);
|
|
return Task.FromResult(_taskCompletionSource);
|
|
}
|
|
|
|
private string[] ButtonText { get; }
|
|
|
|
private bool[] ButtonVisible { get; }
|
|
|
|
private async Task Button0Click(MouseEventArgs arg)
|
|
{
|
|
// need to close before calling OnClick because OnClick may call ShowAsync again
|
|
await MessageBoxPopup.CloseAsync();
|
|
if (OnClick != null)
|
|
await OnClick.Invoke(ButtonText[0], Tag);
|
|
}
|
|
|
|
private async Task Button1Click(MouseEventArgs arg)
|
|
{
|
|
// need to close before calling OnClick because OnClick may call ShowAsync again
|
|
await MessageBoxPopup.CloseAsync();
|
|
if (OnClick != null)
|
|
await OnClick.Invoke(ButtonText[1], Tag);
|
|
}
|
|
private async Task Button2Click(MouseEventArgs arg)
|
|
{
|
|
// need to close before calling OnClick because OnClick may call ShowAsync again
|
|
await MessageBoxPopup.CloseAsync();
|
|
if (OnClick != null)
|
|
await OnClick.Invoke(ButtonText[2], Tag);
|
|
}
|
|
private async Task Button3Click(MouseEventArgs arg)
|
|
{
|
|
// need to close before calling OnClick because OnClick may call ShowAsync again
|
|
await MessageBoxPopup.CloseAsync();
|
|
if (OnClick != null)
|
|
await OnClick.Invoke(ButtonText[3], Tag);
|
|
}
|
|
|
|
private async Task PopupClosed(PopupClosedEventArgs arg)
|
|
{
|
|
// need to close before calling OnClose because OnClose may call ShowAsync again
|
|
await MessageBoxPopup.CloseAsync();
|
|
if (OnClose != null)
|
|
await OnClose.Invoke(Tag);
|
|
}
|
|
}
|
|
} |