Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/yellow-dragon-cloud/AbpMudBlazorFinal

MudBlazor Theme in ABP Blazor WebAssembly FINAL
https://github.com/yellow-dragon-cloud/AbpMudBlazorFinal

Last synced: 3 months ago
JSON representation

MudBlazor Theme in ABP Blazor WebAssembly FINAL

Awesome Lists containing this project

README

        

# MudBlazor Theme in ABP Blazor WebAssembly FINAL

## Introduction

In this part, I will show you how to customize/override pre-built Blazor pages of the [Identity Module](https://docs.abp.io/en/abp/latest/Modules/Identity) using [MudBlazor](https://www.mudblazor.com/) components. I assume that Tenant and Setting management pages are rarely used by end-users, so these modules are not covered in this sample to keep it short. You can customize every page using the principles shown here. All you need to do is:
1. Deriving a class that inherits the class you want to override
2. And adding the following attributes to the derived class:
```razor
@* to the razor file *@
@attribute [ExposeServices(typeof(BASE-CLASS))]
@attribute [Dependency(ReplaceServices = true)]
```
```charp
// or to the C# file
[ExposeServices(typeof(BASE-CLASS))]
[Dependency(ReplaceServices = true)]
```

See [Blazor UI: Customization / Overriding Components](https://docs.abp.io/en/abp/latest/UI/Blazor/Customization-Overriding-Components) for more information.

## 16. Make Sure You Have Completed Previous Parts

You must complete the steps in [Part 1](https://github.com/yellow-dragon-cloud/AbpMudBlazor), [Part 2](https://github.com/yellow-dragon-cloud/AbpMudBlazor2), [Part 3](https://github.com/yellow-dragon-cloud/AbpMudBlazor3), and [Part 4](https://github.com/yellow-dragon-cloud/AbpMudBlazor4) to continue.

## 17. Create Required Files

Create `Identity` folder under `Acme.BookStore.Blazor/Pages/`.

Create the following files in this folder:
1. `MudPermissionManagementModal.razor`
2. `MudPermissionManagementModal.razor.cs`
3. `MudRoleManagement.razor`
4. `MudRoleManagement.razor.cs`
5. `MudUserManagement.razor`
6. `MudUserManagement.razor.cs`

## 18. Modify These Files' Content As Shown Below

1. `MudPermissionManagementModal.razor`

```razor
@using Microsoft.Extensions.Localization
@using Volo.Abp.PermissionManagement.Blazor.Components
@using Volo.Abp.PermissionManagement.Localization
@inherits PermissionManagementModal



@L["Permissions"] - @_entityDisplayName





@L["SelectAllInAllTabs"]


@if (_groups != null)
{



@* ?! *@
    



@foreach (var group in _groups)
{




@group.DisplayName




@L["SelectAllInThisTab"]



@foreach (var permission in group.Permissions)
{




@GetShownName(permission)


}



}


}




@L["Cancel"]


@L["Save"]

```

***


2. `MudPermissionManagementModal.razor.cs`

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using MudBlazor;
using Volo.Abp.AspNetCore.Components.Web.Configuration;
using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.Localization;

namespace Acme.BookStore.Blazor.Pages.Identity;

public partial class MudPermissionManagementModal
{
[Inject] private IPermissionAppService PermissionAppService { get; set; }
[Inject] private ICurrentApplicationConfigurationCacheResetService CurrentApplicationConfigurationCacheResetService { get; set; }

private bool _isVisible;

protected virtual DialogOptions DialogOptions
{
get => new()
{
CloseButton = true,
CloseOnEscapeKey = true,
DisableBackdropClick = true,
MaxWidth = MaxWidth.Medium
};
}

private string _providerName;
private string _providerKey;

private string _entityDisplayName;
private List _groups;

private readonly List _disabledPermissions = new();

private int _grantedPermissionCount = 0;
private int _notGrantedPermissionCount = 0;

private bool GrantAll
{
get => _notGrantedPermissionCount == 0;
set
{
if (_groups == null) return;

_grantedPermissionCount = 0;
_notGrantedPermissionCount = 0;

foreach (var permission in _groups.SelectMany(x => x.Permissions))
{
if (IsDisabledPermission(permission)) continue;

permission.IsGranted = value;

if (value)
_grantedPermissionCount++;
else
_notGrantedPermissionCount++;
}
}
}

public MudPermissionManagementModal()
{
LocalizationResource = typeof(AbpPermissionManagementResource);
}

public async Task OpenDialogAsync(string providerName, string providerKey, string entityDisplayName = null)
{
try
{
_providerName = providerName;
_providerKey = providerKey;

var result = await PermissionAppService.GetAsync(_providerName, _providerKey);

_entityDisplayName = entityDisplayName ?? result.EntityDisplayName;
_groups = result.Groups;

_grantedPermissionCount = 0;
_notGrantedPermissionCount = 0;
foreach (var permission in _groups.SelectMany(x => x.Permissions))
{
if (permission.IsGranted && permission.GrantedProviders.All(x => x.ProviderName != _providerName))
{
_disabledPermissions.Add(permission);
continue;
}

if (permission.IsGranted)
_grantedPermissionCount++;
else
_notGrantedPermissionCount++;
}

_isVisible = true;
StateHasChanged();
}
catch (Exception e)
{
await HandleErrorAsync(e);
}
}

private async Task CloseModalAsync()
{
await InvokeAsync(() => { _isVisible = false; });
}

private async Task SaveAsync()
{
try
{
var updateDto = new UpdatePermissionsDto
{
Permissions = _groups
.SelectMany(g => g.Permissions)
.Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name })
.ToArray()
};

await PermissionAppService.UpdateAsync(_providerName, _providerKey, updateDto);

await CurrentApplicationConfigurationCacheResetService.ResetAsync();

await CloseModalAsync();
}
catch (Exception e)
{
await HandleErrorAsync(e);
}
}

private void GroupGrantAllChanged(bool value, PermissionGroupDto permissionGroup)
{
foreach (var permission in permissionGroup.Permissions)
{
if (!IsDisabledPermission(permission))
SetPermissionGrant(permission, value);
}
}

private void PermissionChanged(bool value, PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission)
{
SetPermissionGrant(permission, value);

if (value && permission.ParentName != null)
{
var parentPermission = GetParentPermission(permissionGroup, permission);

SetPermissionGrant(parentPermission, true);
}
else if (value == false)
{
var childPermissions = GetChildPermissions(permissionGroup, permission);

foreach (var childPermission in childPermissions)
{
SetPermissionGrant(childPermission, false);
}
}
}

private void SetPermissionGrant(PermissionGrantInfoDto permission, bool value)
{
if (permission.IsGranted == value) return;

if (value)
{
_grantedPermissionCount++;
_notGrantedPermissionCount--;
}
else
{
_grantedPermissionCount--;
_notGrantedPermissionCount++;
}

permission.IsGranted = value;
}

private static PermissionGrantInfoDto GetParentPermission(PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission)
{
return permissionGroup.Permissions.First(x => x.Name == permission.ParentName);
}

private static List GetChildPermissions(PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission)
{
return permissionGroup.Permissions.Where(x => x.Name.StartsWith(permission.Name)).ToList();
}

private bool IsDisabledPermission(PermissionGrantInfoDto permissionGrantInfo)
{
return _disabledPermissions.Any(x => x == permissionGrantInfo);
}

private string GetShownName(PermissionGrantInfoDto permissionGrantInfo)
{
if (!IsDisabledPermission(permissionGrantInfo))
return permissionGrantInfo.DisplayName;

return string.Format(
"{0} ({1})",
permissionGrantInfo.DisplayName,
permissionGrantInfo.GrantedProviders
.Where(p => p.ProviderName != _providerName)
.Select(p => p.ProviderName)
.JoinAsString(", ")
);
}
}
```

***

3. `MudRoleManagement.razor`
```razor
@using MudBlazor;
@using Blazorise
@using Blazorise.DataGrid
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.BlazoriseUI.Components
@using Volo.Abp.Identity
@using Microsoft.AspNetCore.Authorization
@using Volo.Abp.PermissionManagement.Blazor.Components
@using Volo.Abp.Identity.Localization
@using Volo.Abp.AspNetCore.Components.Web
@using Volo.Abp.AspNetCore.Components.Web.Theming
@using Volo.Abp.BlazoriseUI.Components.ObjectExtending
@using Volo.Abp.AspNetCore.Components.Web.Theming.Layout
@using Volo.Abp.DependencyInjection
@using Volo.Abp.Identity.Blazor.Pages.Identity
@attribute [Authorize(IdentityPermissions.Roles.Default)]
@attribute [ExposeServices(typeof(RoleManagement))]
@attribute [Dependency(ReplaceServices = true)]
@inject AbpBlazorMessageLocalizerHelper LH

@inherits RoleManagement

@* ************************* DATA GRID ************************* *@


@L["Roles"]


@L["NewRole"]





@if (HasUpdatePermission)
{


}
@if (HasDeletePermission)
{

}





@if (context.Item.IsDefault)
{

@L["DisplayName:IsDefault"]

}
@if (context.Item.IsPublic)
{

@L["DisplayName:IsPublic"]

}


@* ************************* CREATE MODAL ************************* *@
@if (HasCreatePermission)
{


@L["NewRole"]





NewEntity.Name) />



@L["DisplayName:IsDefault"]




@L["DisplayName:IsPublic"]







@L["Cancel"]


@L["Save"]



}

@* ************************* EDIT MODAL ************************* *@
@if (HasUpdatePermission)
{


@L["Edit"]





EditingEntity.Name) />



@L["DisplayName:IsDefault"]




@L["DisplayName:IsPublic"]







@L["Cancel"]


@L["Save"]



}

@if (HasManagePermissionsPermission)
{

}
```

***

4. `MudRoleManagement.razor.cs`
```csharp
using System.Threading.Tasks;
using MudBlazor;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;

namespace Acme.BookStore.Blazor.Pages.Identity;

public partial class MudRoleManagement
{
private MudForm _createForm;
private MudForm _editForm;
private bool _createDialogVisible;
private bool _editDialogVisible;
private MudDataGrid _dataGrid;
private MudPermissionManagementModal _permissionManagementModal;

protected async Task> LoadServerData(GridState state)
{
if (GetListInput is PagedAndSortedResultRequestDto pageResultRequest)
{
pageResultRequest.MaxResultCount = state.PageSize;
pageResultRequest.SkipCount = state.Page * state.PageSize;
}
var result = await AppService.GetListAsync(GetListInput);
return new()
{
Items = result.Items,
TotalItems = (int)result.TotalCount
};
}

protected override Task OpenCreateModalAsync()
{
NewEntity = new();
_createDialogVisible = true;
return Task.CompletedTask;
}

protected override Task CloseCreateModalAsync()
{
_createDialogVisible = false;
return Task.CompletedTask;
}

protected override async Task CreateEntityAsync()
{
if (_createForm.IsValid)
{
var createDto = MapToCreateInput(NewEntity);
await AppService.CreateAsync(createDto);
await _dataGrid.ReloadServerData();
_createDialogVisible = false;
}
}

protected override Task OpenEditModalAsync(IdentityRoleDto entity)
{
EditingEntityId = entity.Id;
EditingEntity = MapToEditingEntity(entity);
_editDialogVisible = true;
return Task.CompletedTask;
}

protected override Task CloseEditModalAsync()
{
_editDialogVisible = false;
return Task.CompletedTask;
}

protected override async Task UpdateEntityAsync()
{
if (_editForm.IsValid)
{
await base.UpdateEntityAsync();
await _dataGrid.ReloadServerData();
_editDialogVisible = false;
}
}

protected override async Task DeleteEntityAsync(IdentityRoleDto entity)
{
if (await Message.Confirm(GetDeleteConfirmationMessage(entity)))
{
await base.DeleteEntityAsync(entity);
await _dataGrid.ReloadServerData();
}
}

protected override Task OnUpdatedEntityAsync()
{
return Task.CompletedTask;
}

protected virtual async Task OpenPermissionsModalAsync(IdentityRoleDto entity)
{
await _permissionManagementModal.OpenDialogAsync(PermissionProviderName, entity.Name);
}

protected virtual DialogOptions DialogOptions
{
get => new()
{
CloseButton = true,
CloseOnEscapeKey = true,
DisableBackdropClick = true
};
}
}
```

***

5. `MudUserManagement.razor`
```razor
@using Microsoft.AspNetCore.Authorization
@using Volo.Abp.DependencyInjection
@using Volo.Abp.PermissionManagement.Blazor.Components
@using Volo.Abp.Identity.Localization
@using Volo.Abp.AspNetCore.Components.Web.Theming.Layout
@using Volo.Abp.Identity
@using Volo.Abp.Identity.Blazor.Pages.Identity
@attribute [Authorize(IdentityPermissions.Users.Default)]
@attribute [ExposeServices(typeof(UserManagement))]
@attribute [Dependency(ReplaceServices = true)]
@inject AbpBlazorMessageLocalizerHelper LH

@inherits UserManagement

@* ************************* DATA GRID ************************* *@


@L["Users"]


@L["NewUser"]





@if (HasUpdatePermission)
{


}
@if (HasDeletePermission)
{

}





@* ************************* CREATE MODAL ************************* *@
@if (HasCreatePermission)
{


@L["NewUser"]




























@L["DisplayName:IsActive"]




@L["DisplayName:LockoutEnabled"]








@if (NewUserRoles != null)
{
@foreach (var role in NewUserRoles)
{


@role.Name


}
}
else
{

N/A

}









@L["Cancel"]


@L["Save"]



}

@* ************************* EDIT MODAL ************************* *@
@if (HasUpdatePermission)
{


@L["Edit"]




























@L["DisplayName:IsActive"]




@L["DisplayName:LockoutEnabled"]








@if (EditUserRoles != null)
{
@foreach (var role in EditUserRoles)
{


@role.Name


}
}
else
{

N/A

}









@L["Cancel"]


@L["Save"]



}

@if (HasManagePermissionsPermission)
{

}
```

***

6. `MudUserManagement.razor.cs`
```csharp
using System.Linq;
using System.Threading.Tasks;
using MudBlazor;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;
using Volo.Abp.Identity.Blazor.Pages.Identity;

namespace Acme.BookStore.Blazor.Pages.Identity;

public partial class MudUserManagement
{
private MudForm _createForm;
private MudForm _editForm;
private bool _createDialogVisible;
private bool _editDialogVisible;
private MudDataGrid _dataGrid;
private MudPermissionManagementModal _permissionManagementModal;

protected async Task> LoadServerData(GridState state)
{
if (GetListInput is PagedAndSortedResultRequestDto pageResultRequest)
{
pageResultRequest.MaxResultCount = state.PageSize;
pageResultRequest.SkipCount = state.Page * state.PageSize;
}
var result = await AppService.GetListAsync(GetListInput);
return new()
{
Items = result.Items,
TotalItems = (int)result.TotalCount
};
}

protected override Task OpenCreateModalAsync()
{
NewEntity = new() { IsActive = true };
NewUserRoles = Roles.Select(i => new AssignedRoleViewModel
{
Name = i.Name,
IsAssigned = i.IsDefault
}).ToArray();
_createDialogVisible = true;
return Task.CompletedTask;
}

protected override Task CloseCreateModalAsync()
{
_createDialogVisible = false;
return Task.CompletedTask;
}

protected override async Task CreateEntityAsync()
{
if (_createForm.IsValid)
{
var createDto = MapToCreateInput(NewEntity);
await AppService.CreateAsync(createDto);
await _dataGrid.ReloadServerData();
await CloseCreateModalAsync();
}
}

protected override async Task OpenEditModalAsync(IdentityUserDto entity)
{
var userRoleNames = (await AppService.GetRolesAsync(entity.Id)).Items.Select(r => r.Name).ToList();
EditUserRoles = Roles.Select(x => new AssignedRoleViewModel
{
Name = x.Name,
IsAssigned = userRoleNames.Contains(x.Name)
}).ToArray();
EditingEntityId = entity.Id;
EditingEntity = MapToEditingEntity(entity);
_editDialogVisible = true;
}

protected override Task CloseEditModalAsync()
{
_editDialogVisible = false;
return Task.CompletedTask;
}

protected override async Task UpdateEntityAsync()
{
if (_editForm.IsValid)
{
await AppService.UpdateAsync(EditingEntityId, EditingEntity);
await _dataGrid.ReloadServerData();
await CloseEditModalAsync();
}
}

protected override async Task DeleteEntityAsync(IdentityUserDto entity)
{
if (await Message.Confirm(GetDeleteConfirmationMessage(entity)))
{
await base.DeleteEntityAsync(entity);
await _dataGrid.ReloadServerData();
}
}

protected override Task OnUpdatedEntityAsync()
{
return Task.CompletedTask;
}

protected virtual async Task OpenPermissionsModalAsync(IdentityUserDto entity)
{
await _permissionManagementModal.OpenDialogAsync(
PermissionProviderName, entity.Id.ToString());
}

protected virtual DialogOptions DialogOptions
{
get => new()
{
CloseButton = true,
CloseOnEscapeKey = true,
DisableBackdropClick = true
};
}
}
```

***

## Screenshots

![image](images/screenshot5.png)

![image](images/screenshot6.png)

## Source Code

The source code of this project is [available on Github](https://github.com/yellow-dragon-cloud/AbpMudBlazorFinal)