From affd00df93ab8258dd71e4d72b861cc37511467f Mon Sep 17 00:00:00 2001 From: stavroskasidis Date: Thu, 20 Jun 2024 11:59:37 +0300 Subject: [PATCH] Major updates and features for BlazorDialog - Updated BlazorDialog package version from 2.3.0 to 3.0.0. - Renamed `Unregister` method to `Remove` in BlazorDialogStore.cs for clarity. - Introduced `PreventNavigation` property in ComponentAsDialogContainer.razor to block navigation during open dialogs. - Added `PreventNavigation` parameter in Dialog.razor to control browser navigation. - Updated target framework to .NET 8.0 and Microsoft packages version in Directory.Build.props. - Updated SDK version to 8.0.302 in global.json. - Added `ILocationChangingHandler` interface and `LocationChangingHandler` class for managing location changes and dialog navigation prevention. --- BlazorDialog/BlazorDialog.csproj | 2 +- BlazorDialog/BlazorDialogStore.cs | 3 +- .../ComponentAsDialogContainer.razor | 6 +- BlazorDialog/Components/Dialog.razor | 15 +++- BlazorDialog/IBlazorDialogStore.cs | 7 +- BlazorDialog/ILocationChangingHandler.cs | 15 ++++ BlazorDialog/LocationChangingHandler.cs | 68 +++++++++++++++++++ BlazorDialog/Properties/launchSettings.json | 7 -- BlazorDialog/ServiceCollectionExtensions.cs | 1 + Directory.Build.props | 4 +- README.md | 8 ++- .../IndexCommon.razor | 2 +- .../Properties/launchSettings.json | 9 +-- global.json | 2 +- 14 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 BlazorDialog/ILocationChangingHandler.cs create mode 100644 BlazorDialog/LocationChangingHandler.cs diff --git a/BlazorDialog/BlazorDialog.csproj b/BlazorDialog/BlazorDialog.csproj index b623abb..b42a31a 100644 --- a/BlazorDialog/BlazorDialog.csproj +++ b/BlazorDialog/BlazorDialog.csproj @@ -12,7 +12,7 @@ blazor blazor-component blazor-dialog dialog modal blazor-modal blazordialog blazormodaldialog blazormodal razor razor-components razorcomponents $(VersionSuffix) - 2.3.0 + 3.0.0 $(Version)-$(VersionSuffix) BlazorDialog diff --git a/BlazorDialog/BlazorDialogStore.cs b/BlazorDialog/BlazorDialogStore.cs index ae7f087..b72493a 100644 --- a/BlazorDialog/BlazorDialogStore.cs +++ b/BlazorDialog/BlazorDialogStore.cs @@ -11,6 +11,7 @@ internal class BlazorDialogStore : IBlazorDialogStore { private Dictionary registeredDialogs = new Dictionary(); private Dictionary registeredComponentDialogs = new Dictionary(); + public event Func OnComponentAsDialogsChanged; public Dialog GetById(string id) @@ -47,7 +48,7 @@ public async Task RegisterComponentDialog(string id, ComponentDialog options) } } - public void Unregister(Dialog blazorDialog) + public void Remove(Dialog blazorDialog) { if (blazorDialog.Id != null && registeredDialogs.ContainsKey(blazorDialog.Id)) { diff --git a/BlazorDialog/Components/ComponentAsDialogContainer.razor b/BlazorDialog/Components/ComponentAsDialogContainer.razor index bbc3283..f436c63 100644 --- a/BlazorDialog/Components/ComponentAsDialogContainer.razor +++ b/BlazorDialog/Components/ComponentAsDialogContainer.razor @@ -7,7 +7,8 @@ Centered="ComponentDialog.Options.Centered" CssClass="@ComponentDialog.Options.CssClass" Size="ComponentDialog.Options.Size" OnAfterRender="EventUtil.AsNonRenderingEventCallback((bool firstLoad) => OnAfterDialogRender(firstLoad))" OnAfterHide="ComponentDialog.Options.OnAfterHide" OnAfterShow="ComponentDialog.Options.OnAfterShow" - OnBeforeHide="ComponentDialog.Options.OnBeforeHide" OnBeforeShow="ComponentDialog.Options.OnBeforeShow"> + OnBeforeHide="ComponentDialog.Options.OnBeforeHide" OnBeforeShow="ComponentDialog.Options.OnBeforeShow" + PreventNavigation="ComponentDialog.Options.PreventNavigation"> } @@ -16,7 +17,8 @@ + OnBeforeHide="ComponentDialog.Options.OnBeforeHide" OnBeforeShow="ComponentDialog.Options.OnBeforeShow" + PreventNavigation="ComponentDialog.Options.PreventNavigation"> } diff --git a/BlazorDialog/Components/Dialog.razor b/BlazorDialog/Components/Dialog.razor index 2c14a27..2ca4630 100644 --- a/BlazorDialog/Components/Dialog.razor +++ b/BlazorDialog/Components/Dialog.razor @@ -2,6 +2,7 @@ @inject IBlazorDialogStore dialogStore @namespace BlazorDialog @implements IDisposable +@inject ILocationChangingHandler locationChangingHandler @if (isShowing) { @@ -99,6 +100,11 @@ /// [Parameter] public EventCallback OnAfterRender { get; set; } + /// + /// Allows you to prevent browser navigation when the dialog is shown. Defaults to true. + /// + [Parameter] public bool PreventNavigation { get; set; } = true; + protected TaskCompletionSource taskCompletionSource; internal Action OnDialogHide; protected void NotifyDialogHidden(object result) => OnDialogHide?.Invoke(result); @@ -188,9 +194,12 @@ var args = new DialogAfterShowEventArgs(this); await OnAfterShow.InvokeAsync(args); } + + locationChangingHandler.RegisterLocationChangingHandler(this); } else if (isShowingChanged && IsShowing == false && isShowing) { + locationChangingHandler.RemoveLocationChangingHandler(this); if (OnBeforeHide.HasDelegate) { var args = new DialogBeforeHideEventArgs(this); @@ -207,7 +216,8 @@ public void Dispose() { - dialogStore.Unregister(this); + dialogStore.Remove(this); + locationChangingHandler.RemoveLocationChangingHandler(this); if (taskCompletionSource != null) { taskCompletionSource.TrySetCanceled(); @@ -260,6 +270,8 @@ taskCompletionSource = null; } + locationChangingHandler.RegisterLocationChangingHandler(this); + taskCompletionSource = new TaskCompletionSource(); return await taskCompletionSource.Task; } @@ -267,6 +279,7 @@ public async Task Hide(TResult result) { + locationChangingHandler.RemoveLocationChangingHandler(this); if (OnBeforeHide.HasDelegate) { var args = new DialogBeforeHideEventArgs(this); diff --git a/BlazorDialog/IBlazorDialogStore.cs b/BlazorDialog/IBlazorDialogStore.cs index dd77243..5282e8b 100644 --- a/BlazorDialog/IBlazorDialogStore.cs +++ b/BlazorDialog/IBlazorDialogStore.cs @@ -53,6 +53,11 @@ public ComponentAsDialogOptions(Type componentType) /// public DialogSize Size { get; set; } = DialogSize.Normal; + /// + /// Allows you to prevent browser navigation when the dialog is shown. Defaults to true. + /// + public bool PreventNavigation { get; set; } = true; + /// /// An event that is triggered before the dialog appears. /// @@ -143,7 +148,7 @@ public interface IBlazorDialogStore { void Register(Dialog blazorDialog); - void Unregister(Dialog blazorDialog); + void Remove(Dialog blazorDialog); Dialog GetById(string id); int GetVisibleDialogsCount(); diff --git a/BlazorDialog/ILocationChangingHandler.cs b/BlazorDialog/ILocationChangingHandler.cs new file mode 100644 index 0000000..3257ebd --- /dev/null +++ b/BlazorDialog/ILocationChangingHandler.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Components.Routing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorDialog +{ + public interface ILocationChangingHandler + { + void RegisterLocationChangingHandler(Dialog dialog); + void RemoveLocationChangingHandler(Dialog dialog); + } +} diff --git a/BlazorDialog/LocationChangingHandler.cs b/BlazorDialog/LocationChangingHandler.cs new file mode 100644 index 0000000..ec5f0b9 --- /dev/null +++ b/BlazorDialog/LocationChangingHandler.cs @@ -0,0 +1,68 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorDialog +{ + public class LocationChangingHandler : ILocationChangingHandler, IDisposable + { + private readonly NavigationManager _navigationManager; + private IDisposable? _currentRegistration; + private List _dialogsStack = new List(); + + public LocationChangingHandler(NavigationManager navigationManager) + { + _navigationManager = navigationManager; + } + + public void RegisterLocationChangingHandler(Dialog dialog) + { + if (!_dialogsStack.Contains(dialog)) + { + _dialogsStack.Add(dialog); + } + + if(_currentRegistration == null) + { + _currentRegistration = _navigationManager.RegisterLocationChangingHandler(OnLocationChanging); + } + } + + private ValueTask OnLocationChanging(LocationChangingContext context) + { + if (!context.IsNavigationIntercepted && _dialogsStack.Any(x => x.PreventNavigation)) + { + context.PreventNavigation(); + } + return ValueTask.CompletedTask; + } + + public void RemoveLocationChangingHandler(Dialog dialog) + { + if (_dialogsStack.Contains(dialog)) + { + _dialogsStack.Remove(dialog); + } + + // if there are no dialogs left in the stack, we can remove the location changing handler + if (_currentRegistration != null && _dialogsStack.Count == 0) + { + _currentRegistration.Dispose(); + _currentRegistration = null; + } + } + + public void Dispose() + { + if(_currentRegistration != null) + { + _currentRegistration.Dispose(); + _currentRegistration = null; + } + } + } +} diff --git a/BlazorDialog/Properties/launchSettings.json b/BlazorDialog/Properties/launchSettings.json index f43ad5d..42780ab 100644 --- a/BlazorDialog/Properties/launchSettings.json +++ b/BlazorDialog/Properties/launchSettings.json @@ -8,13 +8,6 @@ } }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "BlazorDialog": { "commandName": "Project", "launchBrowser": true, diff --git a/BlazorDialog/ServiceCollectionExtensions.cs b/BlazorDialog/ServiceCollectionExtensions.cs index 9a669cb..e44fe7c 100644 --- a/BlazorDialog/ServiceCollectionExtensions.cs +++ b/BlazorDialog/ServiceCollectionExtensions.cs @@ -12,6 +12,7 @@ public static IServiceCollection AddBlazorDialog(this IServiceCollection service { services.AddScoped(); services.AddScoped(); + services.AddScoped(); return services; } } diff --git a/Directory.Build.props b/Directory.Build.props index becaf25..a5200c4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ - net6.0 - 6.0.26 + net8.0 + 8.0.* enable enable diff --git a/README.md b/README.md index a4bb21c..6470a86 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,13 @@ Make sure that there is a call to `app.UseStaticFiles();` in your server project ## Release Notes -
2.3 +
3.0 + +>- Migrate to .NET 8.0 +>- Add PreventNavigation option to prevent navigation when dialog is open. +
+ +
2.3 >- Expose dialog options as cascading parameter when using ComponentAsDialog.
diff --git a/TestApps/BlazorDialog.TestAppsCommon/IndexCommon.razor b/TestApps/BlazorDialog.TestAppsCommon/IndexCommon.razor index 17156ef..598e047 100644 --- a/TestApps/BlazorDialog.TestAppsCommon/IndexCommon.razor +++ b/TestApps/BlazorDialog.TestAppsCommon/IndexCommon.razor @@ -110,7 +110,7 @@
- +

@context.Input

diff --git a/TestApps/Wasm/BlazorDialog.BlazorTestApp.Server/Properties/launchSettings.json b/TestApps/Wasm/BlazorDialog.BlazorTestApp.Server/Properties/launchSettings.json index d3a9294..ebd33d8 100644 --- a/TestApps/Wasm/BlazorDialog.BlazorTestApp.Server/Properties/launchSettings.json +++ b/TestApps/Wasm/BlazorDialog.BlazorTestApp.Server/Properties/launchSettings.json @@ -8,17 +8,10 @@ } }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "BlazorDialog.BlazorTestApp.Server": { "commandName": "Project", "launchBrowser": true, + "dotnetRunMessages": true, "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/global.json b/global.json index adf50e1..2434529 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "6.0.412" + "version": "8.0.302" } } \ No newline at end of file