diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/ComponentsComponentsBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/ComponentsComponentsBundleContributor.cs index 30e3c6548c..5e03821176 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/ComponentsComponentsBundleContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/ComponentsComponentsBundleContributor.cs @@ -23,7 +23,7 @@ public class ComponentsComponentsBundleContributor : IBundleContributor Source = "_content/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/libs/fontawesome/css/all.css" }); } - + context.Add("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/css/abp.css"); context.Add("_content/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/libs/flag-icon/css/flag-icon.css"); context.Add("_content/Blazorise/blazorise.css"); context.Add("_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css"); diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalStyleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalStyleContributor.cs index 3a94e1a568..5a1f119c06 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalStyleContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalStyleContributor.cs @@ -14,6 +14,7 @@ public class BlazorGlobalStyleContributor : BundleContributor { public override void ConfigureBundle(BundleConfigurationContext context) { + context.Files.AddIfNotContains("/_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/css/abp.css"); context.Files.AddIfNotContains("/_content/Blazorise/blazorise.css"); context.Files.AddIfNotContains("/_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css"); context.Files.AddIfNotContains("/_content/Blazorise.Snackbar/blazorise.snackbar.css"); diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/BlockUi/AbpBlockUiService.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/BlockUi/AbpBlockUiService.cs new file mode 100644 index 0000000000..61631a4d76 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/BlockUi/AbpBlockUiService.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Microsoft.JSInterop; +using Volo.Abp.AspNetCore.Components.BlockUi; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.BlockUi; + +[Dependency(ReplaceServices = true)] +public class AbpBlockUiService : IBlockUiService, IScopedDependency +{ + public IJSRuntime JsRuntime { get; } + + public AbpBlockUiService(IJSRuntime jsRuntime) + { + JsRuntime = jsRuntime; + } + + public async Task Block(string? selectors, bool busy = false) + { + await JsRuntime.InvokeVoidAsync("abp.ui.block", selectors, busy); + } + + public async Task UnBlock() + { + await JsRuntime.InvokeVoidAsync("abp.ui.unblock"); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/css/abp.css b/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/css/abp.css new file mode 100644 index 0000000000..ddf9cae5b2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/css/abp.css @@ -0,0 +1,56 @@ +@keyframes spin { + 0% { + transform: translateZ(0) rotate(0deg); + } + + 100% { + transform: translateZ(0) rotate(360deg); + } +} + +.abp-block-area { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 102; + background-color: #fff; + opacity: .8; + transition: opacity .25s; +} + + .abp-block-area.abp-block-area-disappearing { + opacity: 0; + } + + .abp-block-area.abp-block-area-busy:after { + content: attr(data-text); + display: block; + max-width: 125px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 20px; + font-family: sans-serif; + color: #343a40; + text-align: center; + text-transform: uppercase; + } + + .abp-block-area.abp-block-area-busy:before { + content: ""; + display: block; + width: 150px; + height: 150px; + border-radius: 50%; + border-width: 2px; + border-style: solid; + border-color: transparent #228ae6 #228ae6 #228ae6; + position: absolute; + top: calc(50% - 75px); + left: calc(50% - 75px); + will-change: transform; + animation: spin .75s infinite ease-in-out; + } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/js/abp.js b/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/js/abp.js index 55bd36d0db..1b36a720c9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/js/abp.js +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/js/abp.js @@ -182,4 +182,52 @@ var abp = abp || {}; } } } + + /* UI *******************************************************/ + + abp.ui = abp.ui || {}; + + /* UI BLOCK */ + //Defines UI Block API and implements basically + + var $abpBlockArea = document.createElement('div'); + $abpBlockArea.classList.add('abp-block-area'); + + /* opts: { //Can be an object with options or a string for query a selector + * elm: a query selector (optional - default: document.body) + * busy: boolean (optional - default: false) + * } + */ + abp.ui.block = function (elm, busy) { + var $elm = document.querySelector(elm) || document.body; + + if (busy) { + $abpBlockArea.classList.add('abp-block-area-busy'); + } else { + $abpBlockArea.classList.remove('abp-block-area-busy'); + } + + if (document.querySelector(elm)) { + $abpBlockArea.style.position = 'absolute'; + } else { + $abpBlockArea.style.position = 'fixed'; + } + + $elm.appendChild($abpBlockArea); + }; + + abp.ui.unblock = function () { + var element = document.querySelector('.abp-block-area'); + if (element) { + element.classList.add('abp-block-area-disappearing'); + setTimeout(function () { + if (element) { + element.classList.remove('abp-block-area-disappearing'); + if (element.parentElement) { + element.parentElement.removeChild(element); + } + } + }, 250); + } + }; })(); diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ComponentsComponentsBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ComponentsComponentsBundleContributor.cs index 057220ce4b..942edd473c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ComponentsComponentsBundleContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ComponentsComponentsBundleContributor.cs @@ -25,6 +25,7 @@ public class ComponentsComponentsBundleContributor : IBundleContributor }); } + context.Add("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/css/abp.css"); context.Add("_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/flag-icon/css/flag-icon.css"); context.Add("_content/Blazorise/blazorise.css"); context.Add("_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css"); diff --git a/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/BlockUi/IBlockUiService.cs b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/BlockUi/IBlockUiService.cs new file mode 100644 index 0000000000..254a0f6e5f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/BlockUi/IBlockUiService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.BlockUi; + +public interface IBlockUiService +{ + Task Block(string? selectors, bool busy = false); + + Task UnBlock(); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/BlockUi/NullBlockUiService.cs b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/BlockUi/NullBlockUiService.cs new file mode 100644 index 0000000000..6c3b56bc7f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/BlockUi/NullBlockUiService.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.BlockUi; + +public class NullBlockUiService : IBlockUiService, ISingletonDependency +{ + public Task Block(string? selectors, bool busy = false) + { + return Task.CompletedTask; + } + + public Task UnBlock() + { + return Task.CompletedTask; + } +}