mirror of https://github.com/abpframework/abp.git
committed by
GitHub
47 changed files with 427 additions and 149 deletions
@ -0,0 +1,38 @@ |
|||
# Blazor UI: Block/Busy Service |
|||
|
|||
UI Block disables (blocks) the page or a part of the page. |
|||
|
|||
## Quick Example |
|||
|
|||
Simply [inject](../../Dependency-Injection.md) `IBlockUiService` to your page or component and call the `Block/UnBlock` method to disables (blocks) the element. |
|||
|
|||
```csharp |
|||
namespace MyProject.Blazor.Pages |
|||
{ |
|||
public partial class Index |
|||
{ |
|||
private readonly IBlockUiService _blockUiService; |
|||
|
|||
public Index(IBlockUiService _blockUiService) |
|||
{ |
|||
_blockUiService = blockUiService; |
|||
} |
|||
|
|||
public async Task BlockForm() |
|||
{ |
|||
/* |
|||
Parameters of Block method: |
|||
selectors: A string containing one or more selectors to match. https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#selectors |
|||
busy : Set to true to show a progress indicator on the blocked area. |
|||
*/ |
|||
await _blockUiService.Block(selectors: "#MySelectors", busy: true); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
The resulting UI will look like below: |
|||
|
|||
 |
|||
|
|||
Then you can use `_blockUiService.UnBlock()` to re-enable the busy area/page. |
|||
@ -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"); |
|||
} |
|||
} |
|||
@ -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 !important; |
|||
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; |
|||
} |
|||
@ -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(); |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -1,47 +1,60 @@ |
|||
import { Component, computed, inject } from '@angular/core'; |
|||
import { NgIf } from '@angular/common' |
|||
import { InternetConnectionService , LocalizationModule } from '@abp/ng.core'; |
|||
import { Component, inject } from '@angular/core'; |
|||
import { InternetConnectionService, LocalizationModule } from '@abp/ng.core'; |
|||
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; |
|||
|
|||
@Component({ |
|||
selector: 'abp-internet-status', |
|||
standalone: true, |
|||
imports:[NgIf, LocalizationModule], |
|||
imports: [LocalizationModule, NgbTooltip], |
|||
template: ` |
|||
<div class="status-icon" *ngIf="!isOnline()"> |
|||
<i data-toggle="tooltip" title="{{ 'AbpUi::InternetConnectionInfo' | abpLocalization }}" data-placement="left" class="fa fa-circle text-blinking blink"> |
|||
</i> |
|||
</div> |
|||
`,
|
|||
styles: [` |
|||
.blink { |
|||
animation: blinker 0.9s cubic-bezier(.5, 0, 1, 1) infinite alternate; |
|||
} |
|||
@keyframes blinker { |
|||
0% { color:#c1c1c1 } |
|||
70% { color: #DC3545 } |
|||
100% { color: #DC3545 } |
|||
} |
|||
|
|||
.text-blinking{ |
|||
font-size:1.2rem; |
|||
@if (!isOnline()) { |
|||
<div class="status-icon"> |
|||
<i |
|||
ngbTooltip="{{ 'AbpUi::InternetConnectionInfo' | abpLocalization }}" |
|||
container="body" |
|||
placement="left-top" |
|||
class="fa fa-wifi text-blinking blink" |
|||
> |
|||
</i> |
|||
</div> |
|||
} |
|||
`,
|
|||
styles: [ |
|||
` |
|||
.blink { |
|||
animation: blinker 0.9s cubic-bezier(0.5, 0, 1, 1) infinite alternate; |
|||
} |
|||
@keyframes blinker { |
|||
0% { |
|||
color: #c1c1c1; |
|||
} |
|||
70% { |
|||
color: #fa2379; |
|||
} |
|||
100% { |
|||
color: #fa2379; |
|||
} |
|||
} |
|||
|
|||
.status-icon{ |
|||
position: fixed; |
|||
z-index: 999999; |
|||
top: 10px; |
|||
right: 10px; |
|||
} |
|||
.text-blinking { |
|||
font-size: 30px; |
|||
} |
|||
|
|||
@media (width < 768px){ |
|||
.status-icon{ |
|||
top: 26px; |
|||
right: 134px; |
|||
.status-icon { |
|||
position: fixed; |
|||
z-index: 999999; |
|||
top: 50%; |
|||
left: 50%; |
|||
width: 30px; |
|||
text-align: center; |
|||
margin-left: -15px; |
|||
margin-top: -15px; |
|||
translate: transform(-50%, -50%); |
|||
} |
|||
} |
|||
`]
|
|||
`,
|
|||
], |
|||
}) |
|||
export class InternetConnectionStatusComponent{ |
|||
export class InternetConnectionStatusComponent { |
|||
internetConnectionService = inject(InternetConnectionService); |
|||
isOnline = this.internetConnectionService.networkStatus |
|||
isOnline = this.internetConnectionService.networkStatus; |
|||
} |
|||
|
|||
@ -0,0 +1,4 @@ |
|||
export * from './validation'; |
|||
export * from './default-errors'; |
|||
export * from './styles'; |
|||
export * from './scripts'; |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue