From 9d583a7b52d7788dd8cc5ce4604e1e04201f7d44 Mon Sep 17 00:00:00 2001 From: "Diego M. Ribeiro" Date: Tue, 3 Sep 2024 15:23:37 -0300 Subject: [PATCH 1/4] [Dialog] Add event before closing panel to allow validation of the data. (#1508) --- ...crosoft.FluentUI.AspNetCore.Components.xml | 8 +++ .../Examples/DialogPanelWithValidation.razor | 6 ++ .../DialogPanelWithValidation.razor.cs | 58 +++++++++++++++++++ .../Pages/Panel/Examples/SimplePanel.razor | 4 +- .../Demo/Shared/Pages/Panel/PanelPage.razor | 8 +++ .../Components/Dialog/FluentDialog.razor.cs | 10 ++++ .../Dialog/Parameters/DialogParameters.cs | 8 +++ 7 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor create mode 100644 examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index d2911222f3..b8c40ae60a 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -3561,6 +3561,14 @@ This method is only called when using the . + + + Function that is called and awaited before the dialog is closed. + + + This is a suitable callback to use when you need to validate the data in the dialog before it closes. + + Parameters for a dialog. diff --git a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor new file mode 100644 index 0000000000..9dafc240fa --- /dev/null +++ b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor @@ -0,0 +1,6 @@ +@inject IDialogService DialogService +@inject IMessageService MessageService + + + Open panel (>>) + diff --git a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs new file mode 100644 index 0000000000..a7157d9559 --- /dev/null +++ b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------ +// MIT License - Copyright (c) Microsoft Corporation. All rights reserved. +// ------------------------------------------------------------------------ + +using FluentUI.Demo.Shared.SampleData; +using Microsoft.FluentUI.AspNetCore.Components; + +namespace FluentUI.Demo.Shared.Pages.Panel.Examples; +public partial class DialogPanelWithValidation +{ + private IDialogReference? _dialog; + + private readonly SimplePerson simplePerson = new() + { + Firstname = "Steve", + Lastname = "Roth", + Age = 42, + }; + + private async Task OpenPanelRightAsync() + { + DemoLogger.WriteLine($"Open right panel"); + + MessageService.Clear(); + + _dialog = await DialogService.ShowPanelAsync(simplePerson, new DialogParameters() + { + Content = simplePerson, + Alignment = HorizontalAlignment.Right, + Title = $"Hello {simplePerson.Firstname}", + PrimaryAction = "Yes", + SecondaryAction = "No", + PreventDismissOnOverlayClick = true, + OnDialogValidation = () => + { + var result = simplePerson.Firstname.Length > 0 && simplePerson.Lastname.Length > 0; + + if (!result) + { + DemoLogger.WriteLine("Panel cannot be closed because of validation errors."); + + MessageService.ShowMessageBar(options => + { + options.Intent = MessageIntent.Error; + options.Title = "Validation error"; + options.Body = "First name and last name cannot be empty"; + options.Timestamp = DateTime.Now; + options.Section = App.MESSAGES_DIALOG; + }); + } + + return result; + } + }); + + DialogResult result = await _dialog.Result; + } +} diff --git a/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor b/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor index 0e7fc67e50..122f73fd06 100644 --- a/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor +++ b/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor @@ -1,5 +1,7 @@ @implements IDialogContentComponent + +

Hello @Content.Firstname

Your lastname is @Content.Lastname and you are @Content.Age years young

@@ -12,4 +14,4 @@ @code { [Parameter] public SimplePerson Content { get; set; } = default!; -} \ No newline at end of file +} diff --git a/examples/Demo/Shared/Pages/Panel/PanelPage.razor b/examples/Demo/Shared/Pages/Panel/PanelPage.razor index faf759c461..c721627a72 100644 --- a/examples/Demo/Shared/Pages/Panel/PanelPage.razor +++ b/examples/Demo/Shared/Pages/Panel/PanelPage.razor @@ -52,6 +52,14 @@ + + + The panel that is anchored to the right side of the screen can be dismissed by clicking the dismiss button (at the top), + 'No' button (at the bottom) or 'Yes' button (at the bottom).
+ Before the panel is closed, it will validate the data and, if not ok, will prevent the dialog from closing using the 'Yes' button. +
+
+

Documentation

diff --git a/src/Core/Components/Dialog/FluentDialog.razor.cs b/src/Core/Components/Dialog/FluentDialog.razor.cs index 2efbed4b19..d2cd0355c7 100644 --- a/src/Core/Components/Dialog/FluentDialog.razor.cs +++ b/src/Core/Components/Dialog/FluentDialog.razor.cs @@ -241,6 +241,16 @@ public async Task CloseAsync(DialogResult dialogResult) { await Instance.Parameters.OnDialogClosing.InvokeAsync(Instance); } + + if (Instance.Parameters.OnDialogValidation != null && !dialogResult.Cancelled) + { + var isValid = Instance.Parameters.OnDialogValidation(); + + if (!isValid) + { + return; + } + } } DialogContext?.DialogContainer.DismissInstance(Id!, dialogResult); if (Instance is not null) diff --git a/src/Core/Components/Dialog/Parameters/DialogParameters.cs b/src/Core/Components/Dialog/Parameters/DialogParameters.cs index 1edb4f7067..f6085de2e3 100644 --- a/src/Core/Components/Dialog/Parameters/DialogParameters.cs +++ b/src/Core/Components/Dialog/Parameters/DialogParameters.cs @@ -150,6 +150,14 @@ public class DialogParameters : ComponentParameters, IDialogParameters /// This method is only called when using the . /// public EventCallback OnDialogOpened { get; set; } = default!; + + /// + /// Function that is called and awaited before the dialog is closed. + /// + /// + /// This is a suitable callback to use when you need to validate the data in the dialog before it closes. + /// + public Func OnDialogValidation { get; set; } = default!; } /// From afaffe0a3ac524db6555a443e0d06cec9c1c23d0 Mon Sep 17 00:00:00 2001 From: "Diego M. Ribeiro" Date: Tue, 3 Sep 2024 15:23:37 -0300 Subject: [PATCH 2/4] [Dialog] Add event before closing panel to allow validation of the data. (#1508) --- ...crosoft.FluentUI.AspNetCore.Components.xml | 8 +++ .../Examples/DialogPanelWithValidation.razor | 6 ++ .../DialogPanelWithValidation.razor.cs | 58 +++++++++++++++++++ .../Pages/Panel/Examples/SimplePanel.razor | 4 +- .../Demo/Shared/Pages/Panel/PanelPage.razor | 8 +++ .../Components/Dialog/FluentDialog.razor.cs | 10 ++++ .../Dialog/Parameters/DialogParameters.cs | 8 +++ 7 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor create mode 100644 examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index a22fbf879f..716ee6b2ae 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -3660,6 +3660,14 @@ This method is only called when using the . + + + Function that is called and awaited before the dialog is closed. + + + This is a suitable callback to use when you need to validate the data in the dialog before it closes. + + Parameters for a dialog. diff --git a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor new file mode 100644 index 0000000000..9dafc240fa --- /dev/null +++ b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor @@ -0,0 +1,6 @@ +@inject IDialogService DialogService +@inject IMessageService MessageService + + + Open panel (>>) + diff --git a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs new file mode 100644 index 0000000000..a7157d9559 --- /dev/null +++ b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------ +// MIT License - Copyright (c) Microsoft Corporation. All rights reserved. +// ------------------------------------------------------------------------ + +using FluentUI.Demo.Shared.SampleData; +using Microsoft.FluentUI.AspNetCore.Components; + +namespace FluentUI.Demo.Shared.Pages.Panel.Examples; +public partial class DialogPanelWithValidation +{ + private IDialogReference? _dialog; + + private readonly SimplePerson simplePerson = new() + { + Firstname = "Steve", + Lastname = "Roth", + Age = 42, + }; + + private async Task OpenPanelRightAsync() + { + DemoLogger.WriteLine($"Open right panel"); + + MessageService.Clear(); + + _dialog = await DialogService.ShowPanelAsync(simplePerson, new DialogParameters() + { + Content = simplePerson, + Alignment = HorizontalAlignment.Right, + Title = $"Hello {simplePerson.Firstname}", + PrimaryAction = "Yes", + SecondaryAction = "No", + PreventDismissOnOverlayClick = true, + OnDialogValidation = () => + { + var result = simplePerson.Firstname.Length > 0 && simplePerson.Lastname.Length > 0; + + if (!result) + { + DemoLogger.WriteLine("Panel cannot be closed because of validation errors."); + + MessageService.ShowMessageBar(options => + { + options.Intent = MessageIntent.Error; + options.Title = "Validation error"; + options.Body = "First name and last name cannot be empty"; + options.Timestamp = DateTime.Now; + options.Section = App.MESSAGES_DIALOG; + }); + } + + return result; + } + }); + + DialogResult result = await _dialog.Result; + } +} diff --git a/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor b/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor index 0e7fc67e50..122f73fd06 100644 --- a/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor +++ b/examples/Demo/Shared/Pages/Panel/Examples/SimplePanel.razor @@ -1,5 +1,7 @@ @implements IDialogContentComponent + +

Hello @Content.Firstname

Your lastname is @Content.Lastname and you are @Content.Age years young

@@ -12,4 +14,4 @@ @code { [Parameter] public SimplePerson Content { get; set; } = default!; -} \ No newline at end of file +} diff --git a/examples/Demo/Shared/Pages/Panel/PanelPage.razor b/examples/Demo/Shared/Pages/Panel/PanelPage.razor index faf759c461..c721627a72 100644 --- a/examples/Demo/Shared/Pages/Panel/PanelPage.razor +++ b/examples/Demo/Shared/Pages/Panel/PanelPage.razor @@ -52,6 +52,14 @@ + + + The panel that is anchored to the right side of the screen can be dismissed by clicking the dismiss button (at the top), + 'No' button (at the bottom) or 'Yes' button (at the bottom).
+ Before the panel is closed, it will validate the data and, if not ok, will prevent the dialog from closing using the 'Yes' button. +
+
+

Documentation

diff --git a/src/Core/Components/Dialog/FluentDialog.razor.cs b/src/Core/Components/Dialog/FluentDialog.razor.cs index 2efbed4b19..d2cd0355c7 100644 --- a/src/Core/Components/Dialog/FluentDialog.razor.cs +++ b/src/Core/Components/Dialog/FluentDialog.razor.cs @@ -241,6 +241,16 @@ public async Task CloseAsync(DialogResult dialogResult) { await Instance.Parameters.OnDialogClosing.InvokeAsync(Instance); } + + if (Instance.Parameters.OnDialogValidation != null && !dialogResult.Cancelled) + { + var isValid = Instance.Parameters.OnDialogValidation(); + + if (!isValid) + { + return; + } + } } DialogContext?.DialogContainer.DismissInstance(Id!, dialogResult); if (Instance is not null) diff --git a/src/Core/Components/Dialog/Parameters/DialogParameters.cs b/src/Core/Components/Dialog/Parameters/DialogParameters.cs index 166e0d4615..bdc60aa1b4 100644 --- a/src/Core/Components/Dialog/Parameters/DialogParameters.cs +++ b/src/Core/Components/Dialog/Parameters/DialogParameters.cs @@ -167,6 +167,14 @@ public virtual HorizontalAlignment Alignment /// This method is only called when using the . /// public EventCallback OnDialogOpened { get; set; } = default!; + + /// + /// Function that is called and awaited before the dialog is closed. + /// + /// + /// This is a suitable callback to use when you need to validate the data in the dialog before it closes. + /// + public Func OnDialogValidation { get; set; } = default!; } /// From ddb5b00299527044d23452227410b16191bc43e7 Mon Sep 17 00:00:00 2001 From: "Diego M. Ribeiro" Date: Fri, 15 Nov 2024 10:28:23 -0300 Subject: [PATCH 3/4] [Dialog] Add event before closing panel to allow validation of the data. (#1508) --- .../Pages/Panel/Examples/DialogPanelWithValidation.razor.cs | 4 +++- src/Core/Components/Dialog/FluentDialog.razor.cs | 2 +- src/Core/Components/Dialog/Parameters/DialogParameters.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs index a7157d9559..f163148fd1 100644 --- a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs +++ b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs @@ -31,7 +31,7 @@ private async Task OpenPanelRightAsync() PrimaryAction = "Yes", SecondaryAction = "No", PreventDismissOnOverlayClick = true, - OnDialogValidation = () => + OnDialogValidation = async () => { var result = simplePerson.Firstname.Length > 0 && simplePerson.Lastname.Length > 0; @@ -49,6 +49,8 @@ private async Task OpenPanelRightAsync() }); } + await Task.Delay(100); + return result; } }); diff --git a/src/Core/Components/Dialog/FluentDialog.razor.cs b/src/Core/Components/Dialog/FluentDialog.razor.cs index d2cd0355c7..2e62a40578 100644 --- a/src/Core/Components/Dialog/FluentDialog.razor.cs +++ b/src/Core/Components/Dialog/FluentDialog.razor.cs @@ -244,7 +244,7 @@ public async Task CloseAsync(DialogResult dialogResult) if (Instance.Parameters.OnDialogValidation != null && !dialogResult.Cancelled) { - var isValid = Instance.Parameters.OnDialogValidation(); + var isValid = await Instance.Parameters.OnDialogValidation(); if (!isValid) { diff --git a/src/Core/Components/Dialog/Parameters/DialogParameters.cs b/src/Core/Components/Dialog/Parameters/DialogParameters.cs index f6085de2e3..905c4cfbe3 100644 --- a/src/Core/Components/Dialog/Parameters/DialogParameters.cs +++ b/src/Core/Components/Dialog/Parameters/DialogParameters.cs @@ -157,7 +157,7 @@ public class DialogParameters : ComponentParameters, IDialogParameters /// /// This is a suitable callback to use when you need to validate the data in the dialog before it closes. /// - public Func OnDialogValidation { get; set; } = default!; + public Func> OnDialogValidation { get; set; } = default!; } /// From de0b4f1cfbc195777dab713e51246e141a0ee0b3 Mon Sep 17 00:00:00 2001 From: "Diego M. Ribeiro" Date: Thu, 5 Dec 2024 09:03:58 -0300 Subject: [PATCH 4/4] Rename OnDialogValidation to ValidateDialogAsync Renamed the property OnDialogValidation to ValidateDialogAsync across multiple files in the Microsoft.FluentUI.AspNetCore.Components library. Updated the member name in the XML documentation, and modified the property assignments and invocations in DialogPanelWithValidation.razor.cs, FluentDialog.razor.cs, and DialogParameters.cs to reflect this change. --- .../Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml | 2 +- .../Pages/Panel/Examples/DialogPanelWithValidation.razor.cs | 2 +- src/Core/Components/Dialog/FluentDialog.razor.cs | 4 ++-- src/Core/Components/Dialog/Parameters/DialogParameters.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index 716ee6b2ae..591e8e4790 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -3660,7 +3660,7 @@ This method is only called when using the . - + Function that is called and awaited before the dialog is closed. diff --git a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs index f163148fd1..2da3622973 100644 --- a/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs +++ b/examples/Demo/Shared/Pages/Panel/Examples/DialogPanelWithValidation.razor.cs @@ -31,7 +31,7 @@ private async Task OpenPanelRightAsync() PrimaryAction = "Yes", SecondaryAction = "No", PreventDismissOnOverlayClick = true, - OnDialogValidation = async () => + ValidateDialogAsync = async () => { var result = simplePerson.Firstname.Length > 0 && simplePerson.Lastname.Length > 0; diff --git a/src/Core/Components/Dialog/FluentDialog.razor.cs b/src/Core/Components/Dialog/FluentDialog.razor.cs index 2e62a40578..f4caa3cd03 100644 --- a/src/Core/Components/Dialog/FluentDialog.razor.cs +++ b/src/Core/Components/Dialog/FluentDialog.razor.cs @@ -242,9 +242,9 @@ public async Task CloseAsync(DialogResult dialogResult) await Instance.Parameters.OnDialogClosing.InvokeAsync(Instance); } - if (Instance.Parameters.OnDialogValidation != null && !dialogResult.Cancelled) + if (Instance.Parameters.ValidateDialogAsync != null && !dialogResult.Cancelled) { - var isValid = await Instance.Parameters.OnDialogValidation(); + var isValid = await Instance.Parameters.ValidateDialogAsync(); if (!isValid) { diff --git a/src/Core/Components/Dialog/Parameters/DialogParameters.cs b/src/Core/Components/Dialog/Parameters/DialogParameters.cs index 30d982710e..78aee66286 100644 --- a/src/Core/Components/Dialog/Parameters/DialogParameters.cs +++ b/src/Core/Components/Dialog/Parameters/DialogParameters.cs @@ -174,7 +174,7 @@ public virtual HorizontalAlignment Alignment /// /// This is a suitable callback to use when you need to validate the data in the dialog before it closes. /// - public Func> OnDialogValidation { get; set; } = default!; + public Func> ValidateDialogAsync { get; set; } = default!; } ///