mirror of https://github.com/abpframework/abp.git
156 changed files with 3740 additions and 219 deletions
@ -0,0 +1,20 @@ |
|||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreComponentsWebAssemblyBasicThemeModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpRouterOptions>(options => |
||||
|
{ |
||||
|
options.AdditionalAssemblies.Add(typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeModule).Assembly); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@page "/authentication/{action}" |
||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
|
<RemoteAuthenticatorView Action="@Action" /> |
||||
|
|
||||
|
@code{ |
||||
|
[Parameter] public string Action { get; set; } |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
@using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing |
||||
|
@using Microsoft.Extensions.Options |
||||
|
@inject IOptions<AbpRouterOptions> RouterOptions |
||||
|
<CascadingAuthenticationState> |
||||
|
<Router AppAssembly="RouterOptions.Value.AppAssembly" |
||||
|
AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies"> |
||||
|
<Found Context="routeData"> |
||||
|
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> |
||||
|
<NotAuthorized> |
||||
|
@if (!context.User.Identity.IsAuthenticated) |
||||
|
{ |
||||
|
<RedirectToLogin /> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<p>You are not authorized to access this resource.</p> |
||||
|
} |
||||
|
</NotAuthorized> |
||||
|
</AuthorizeRouteView> |
||||
|
</Found> |
||||
|
<NotFound> |
||||
|
<LayoutView Layout="@typeof(MainLayout)"> |
||||
|
<p>Sorry, there's nothing at this address.</p> |
||||
|
</LayoutView> |
||||
|
</NotFound> |
||||
|
</Router> |
||||
|
</CascadingAuthenticationState> |
||||
@ -0,0 +1,65 @@ |
|||||
|
@using Volo.Abp.Localization |
||||
|
@using System.Globalization |
||||
|
@using System.Collections.Immutable |
||||
|
@inject ILanguageProvider LanguageProvider |
||||
|
@inject IJSRuntime JsRuntime |
||||
|
@if (_otherLanguages != null && _otherLanguages.Any()) |
||||
|
{ |
||||
|
<Dropdown> |
||||
|
<DropdownToggle Color="Color.None"> |
||||
|
@_currentLanguage.DisplayName |
||||
|
</DropdownToggle> |
||||
|
<DropdownMenu> |
||||
|
@foreach (var language in _otherLanguages) |
||||
|
{ |
||||
|
<DropdownItem Clicked="() => ChangeLanguageAsync(language)">@language.DisplayName</DropdownItem> |
||||
|
} |
||||
|
</DropdownMenu> |
||||
|
</Dropdown> |
||||
|
} |
||||
|
@code { |
||||
|
private IReadOnlyList<LanguageInfo> _otherLanguages; |
||||
|
private LanguageInfo _currentLanguage; |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
var selectedLanguageName = await JsRuntime.InvokeAsync<string>( |
||||
|
"localStorage.getItem", |
||||
|
"Abp.SelectedLanguage" |
||||
|
); |
||||
|
|
||||
|
_otherLanguages = await LanguageProvider.GetLanguagesAsync(); |
||||
|
|
||||
|
if (!_otherLanguages.Any()) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!selectedLanguageName.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
_currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName); |
||||
|
} |
||||
|
|
||||
|
if (_currentLanguage == null) |
||||
|
{ |
||||
|
_currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name); |
||||
|
} |
||||
|
|
||||
|
if (_currentLanguage == null) |
||||
|
{ |
||||
|
_currentLanguage = _otherLanguages.FirstOrDefault(); |
||||
|
} |
||||
|
|
||||
|
_otherLanguages = _otherLanguages.Where(l => l != _currentLanguage).ToImmutableList(); |
||||
|
} |
||||
|
|
||||
|
private async Task ChangeLanguageAsync(LanguageInfo language) |
||||
|
{ |
||||
|
await JsRuntime.InvokeVoidAsync( |
||||
|
"localStorage.setItem", |
||||
|
"Abp.SelectedLanguage", language.UiCultureName |
||||
|
); |
||||
|
|
||||
|
await JsRuntime.InvokeVoidAsync("location.reload"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
|
@using Volo.Abp.Users |
||||
|
@inject ICurrentUser CurrentUser |
||||
|
@inject NavigationManager Navigation |
||||
|
@inject SignOutSessionStateManager SignOutManager |
||||
|
<AuthorizeView> |
||||
|
<Authorized> |
||||
|
<Dropdown> |
||||
|
<DropdownToggle Color="Color.None"> |
||||
|
@CurrentUser.UserName |
||||
|
</DropdownToggle> |
||||
|
<DropdownMenu> |
||||
|
<DropdownItem Clicked="BeginSignOut">Logout</DropdownItem> |
||||
|
</DropdownMenu> |
||||
|
</Dropdown> |
||||
|
</Authorized> |
||||
|
<NotAuthorized> |
||||
|
<a class="nav-link" href="authentication/login">Log in</a> |
||||
|
</NotAuthorized> |
||||
|
</AuthorizeView> |
||||
|
@code{ |
||||
|
private async Task BeginSignOut() |
||||
|
{ |
||||
|
await SignOutManager.SetSignOutState(); |
||||
|
Navigation.NavigateTo("authentication/logout"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
@inherits LayoutComponentBase |
||||
|
@using Volo.Abp.Ui.Branding |
||||
|
@inject IBrandingProvider BrandingProvider |
||||
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark shadow-sm flex-column flex-md-row mb-4" id="main-navbar" style="min-height: 4rem;"> |
||||
|
<div class="container"> |
||||
|
<a class="navbar-brand" href="/">@BrandingProvider.AppName</a> |
||||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" |
||||
|
data-target="#main-navbar-collapse" aria-controls="main-navbar-collapse" |
||||
|
aria-expanded="false" aria-label="Toggle navigation"> |
||||
|
<span class="navbar-toggler-icon"></span> |
||||
|
</button> |
||||
|
<div class="collapse navbar-collapse" id="main-navbar-collapse"> |
||||
|
<ul class="navbar-nav mx-auto"> |
||||
|
<NavMenu/> |
||||
|
</ul> |
||||
|
<ul class="navbar-nav"> |
||||
|
<li class="nav-item"> |
||||
|
<LanguageSwitch/> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<LoginDisplay/> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</nav> |
||||
|
<div class="container"> |
||||
|
@Body |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@if (Menu != null) |
||||
|
{ |
||||
|
foreach (var menuItem in Menu.Items) |
||||
|
{ |
||||
|
<NavMenuItem MenuItem="@menuItem" /> |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic |
||||
|
{ |
||||
|
public partial class NavMenu |
||||
|
{ |
||||
|
[Inject] protected IMenuManager MenuManager { get; set; } |
||||
|
|
||||
|
protected ApplicationMenu Menu { get; set; } |
||||
|
|
||||
|
private bool collapseNavMenu = true; |
||||
|
|
||||
|
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
Menu = await MenuManager.GetAsync(StandardMenus.Main); |
||||
|
} |
||||
|
|
||||
|
private void ToggleNavMenu() |
||||
|
{ |
||||
|
collapseNavMenu = !collapseNavMenu; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
@using Volo.Abp.UI.Navigation |
||||
|
@{ |
||||
|
var elementId = MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_"); |
||||
|
var cssClass = string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass; |
||||
|
var url = string.IsNullOrEmpty(MenuItem.Url) ? "#" : MenuItem.Url; |
||||
|
} |
||||
|
@if (MenuItem.IsLeaf) |
||||
|
{ |
||||
|
if (MenuItem.Url != null) |
||||
|
{ |
||||
|
<li class="nav-item @cssClass" disabled="@MenuItem.IsDisabled"> |
||||
|
<NavLink class="nav-link" href="@url" id="@elementId"> |
||||
|
@if (MenuItem.Icon != null) |
||||
|
{ |
||||
|
if (MenuItem.Icon.StartsWith("fa")) |
||||
|
{ |
||||
|
<i class="@MenuItem.Icon"></i> |
||||
|
} |
||||
|
} |
||||
|
@MenuItem.DisplayName |
||||
|
</NavLink> |
||||
|
</li> |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<li class="nav-item"> |
||||
|
<div class="dropdown"> |
||||
|
<a class="nav-link dropdown-toggle" href="#" id="@elementId" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
||||
|
@if (MenuItem.Icon != null) |
||||
|
{ |
||||
|
if (MenuItem.Icon.StartsWith("fa")) |
||||
|
{ |
||||
|
<i class="@MenuItem.Icon"></i> |
||||
|
} |
||||
|
} |
||||
|
@MenuItem.DisplayName |
||||
|
</a> |
||||
|
<div class="dropdown-menu border-0 shadow-sm" aria-labelledby="@elementId"> |
||||
|
@foreach (var childMenuItem in MenuItem.Items) |
||||
|
{ |
||||
|
<NavMenuItem MenuItem="@childMenuItem" /> |
||||
|
} |
||||
|
</div> |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
} |
||||
|
@code { |
||||
|
[Parameter] |
||||
|
public ApplicationMenuItem MenuItem { get; set; } |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
@inject NavigationManager Navigation |
||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
|
@code { |
||||
|
protected override void OnInitialized() |
||||
|
{ |
||||
|
Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
@using System.Net.Http |
||||
|
@using Microsoft.AspNetCore.Components.Authorization |
||||
|
@using Microsoft.AspNetCore.Components.Forms |
||||
|
@using Microsoft.AspNetCore.Components.Routing |
||||
|
@using Microsoft.AspNetCore.Components.Web |
||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Http |
||||
|
@using Microsoft.JSInterop |
||||
|
@using Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
@using Blazorise |
||||
|
@using Blazorise.DataGrid |
||||
@ -0,0 +1,16 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RazorLangVersion>3.0</RazorLangVersion> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme</PackageId> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,105 @@ |
|||||
|
|
||||
|
#main-navbar-tools a.dropdown-toggle { |
||||
|
text-decoration: none; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
.navbar .dropdown-submenu { |
||||
|
position: relative; |
||||
|
} |
||||
|
.navbar .dropdown-menu { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.navbar .dropdown-menu a { |
||||
|
font-size: .9em; |
||||
|
padding: 10px 15px; |
||||
|
display: block; |
||||
|
min-width: 210px; |
||||
|
text-align: left; |
||||
|
border-radius: 0.25rem; |
||||
|
min-height: 44px; |
||||
|
} |
||||
|
.navbar .dropdown-submenu a::after { |
||||
|
transform: rotate(-90deg); |
||||
|
position: absolute; |
||||
|
right: 16px; |
||||
|
top: 18px; |
||||
|
} |
||||
|
.navbar .dropdown-submenu .dropdown-menu { |
||||
|
top: 0; |
||||
|
left: 100%; |
||||
|
} |
||||
|
|
||||
|
.card-header .btn { |
||||
|
padding: 2px 6px; |
||||
|
} |
||||
|
.card-header h5 { |
||||
|
margin: 0; |
||||
|
} |
||||
|
.container > .card { |
||||
|
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; |
||||
|
} |
||||
|
|
||||
|
@media screen and (min-width: 768px) { |
||||
|
.navbar .dropdown:hover > .dropdown-menu { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
.navbar .dropdown-submenu:hover > .dropdown-menu { |
||||
|
display: block; |
||||
|
} |
||||
|
} |
||||
|
.input-validation-error { |
||||
|
border-color: #dc3545; |
||||
|
} |
||||
|
.field-validation-error { |
||||
|
font-size: 0.8em; |
||||
|
} |
||||
|
|
||||
|
.dataTables_scrollBody { |
||||
|
min-height: 248px; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_wrapper div.dataTables_info { |
||||
|
padding-top: 11px; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_wrapper div.dataTables_length label { |
||||
|
padding-top: 10px; |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.rtl .dropdown-menu-right { |
||||
|
right: auto; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.rtl .dropdown-menu-right a { |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.rtl .navbar .dropdown-menu a { |
||||
|
text-align: right; |
||||
|
} |
||||
|
.rtl .navbar .dropdown-submenu .dropdown-menu { |
||||
|
top: 0; |
||||
|
left: auto; |
||||
|
right: 100%; |
||||
|
} |
||||
|
|
||||
|
/* TEMP */ |
||||
|
|
||||
|
.navbar-dark .navbar-nav .nav-link { |
||||
|
color: #000 !important; |
||||
|
} |
||||
|
|
||||
|
.navbar-nav > .nav-item > .nav-link, |
||||
|
.navbar-nav > .nav-item > .dropdown > .nav-link { |
||||
|
color: #fff !important; |
||||
|
} |
||||
|
|
||||
|
.navbar-nav>.nav-item>div>button{ |
||||
|
color:#fff; |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
$(function () { |
||||
|
$('.dropdown-menu a.dropdown-toggle').on('click', function (e) { |
||||
|
if (!$(this).next().hasClass('show')) { |
||||
|
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show"); |
||||
|
} |
||||
|
|
||||
|
var $subMenu = $(this).next(".dropdown-menu"); |
||||
|
$subMenu.toggleClass('show'); |
||||
|
|
||||
|
$(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function (e) { |
||||
|
$('.dropdown-submenu .show').removeClass("show"); |
||||
|
}); |
||||
|
|
||||
|
return false; |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,17 @@ |
|||||
|
using Volo.Abp.BlazoriseUI; |
||||
|
using Volo.Abp.Http.Client.IdentityModel.WebAssembly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpBlazoriseUIModule), |
||||
|
typeof(AbpHttpClientIdentityModelWebAssemblyModule), |
||||
|
typeof(AbpUiNavigationModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreComponentsWebAssemblyThemingModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing |
||||
|
{ |
||||
|
public class AbpRouterOptions |
||||
|
{ |
||||
|
public Assembly AppAssembly { get; set; } |
||||
|
|
||||
|
public RouterAssemblyList AdditionalAssemblies { get; } |
||||
|
|
||||
|
public AbpRouterOptions() |
||||
|
{ |
||||
|
AdditionalAssemblies = new RouterAssemblyList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing |
||||
|
{ |
||||
|
public class RouterAssemblyList : List<Assembly> |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RazorLangVersion>3.0</RazorLangVersion> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Http.Client.IdentityModel.WebAssembly\Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.UI.Navigation\Volo.Abp.UI.Navigation.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,51 @@ |
|||||
|
using System; |
||||
|
using System.Reflection; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting |
||||
|
{ |
||||
|
public static class AbpWebAssemblyHostBuilderExtensions |
||||
|
{ |
||||
|
public static IAbpApplicationWithExternalServiceProvider AddApplication<TStartupModule>( |
||||
|
[NotNull] this WebAssemblyHostBuilder builder, |
||||
|
Action<AbpWebAssemblyApplicationCreationOptions> options) |
||||
|
where TStartupModule : IAbpModule |
||||
|
{ |
||||
|
Check.NotNull(builder, nameof(builder)); |
||||
|
|
||||
|
builder.Services.AddSingleton<IConfiguration>(builder.Configuration); |
||||
|
builder.Services.AddSingleton(builder); |
||||
|
|
||||
|
var application = builder.Services.AddApplication<TStartupModule>(opts => |
||||
|
{ |
||||
|
options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); |
||||
|
}); |
||||
|
|
||||
|
return application; |
||||
|
} |
||||
|
|
||||
|
public static async Task InitializeAsync( |
||||
|
[NotNull] this IAbpApplicationWithExternalServiceProvider application, |
||||
|
[NotNull] IServiceProvider serviceProvider) |
||||
|
{ |
||||
|
Check.NotNull(application, nameof(application)); |
||||
|
Check.NotNull(serviceProvider, nameof(serviceProvider)); |
||||
|
|
||||
|
application.Initialize(serviceProvider); |
||||
|
|
||||
|
using (var scope = serviceProvider.CreateScope()) |
||||
|
{ |
||||
|
await scope.ServiceProvider |
||||
|
.GetRequiredService<ICachedApplicationConfigurationClient>() |
||||
|
.InitializeAsync(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.AspNetCore.Components.WebAssembly</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.Client.Common\Volo.Abp.AspNetCore.Mvc.Client.Common.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.UI\Volo.Abp.UI.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="3.1.6" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,26 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.UI; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreMvcClientCommonModule), |
||||
|
typeof(AbpUiModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule |
||||
|
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
PreConfigure<AbpHttpClientBuilderOptions>(options => |
||||
|
{ |
||||
|
options.ProxyClientBuildActions.Add((_, builder) => |
||||
|
{ |
||||
|
builder.AddHttpMessageHandler<AbpBlazorClientHttpMessageHandler>(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System; |
||||
|
using System.Net.Http; |
||||
|
using System.Net.Http.Headers; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.JSInterop; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency |
||||
|
{ |
||||
|
private readonly IJSRuntime _jsRuntime; |
||||
|
|
||||
|
public AbpBlazorClientHttpMessageHandler(IJSRuntime jsRuntime) |
||||
|
{ |
||||
|
_jsRuntime = jsRuntime; |
||||
|
} |
||||
|
|
||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
await SetLanguageAsync(request, cancellationToken); |
||||
|
|
||||
|
return await base.SendAsync(request, cancellationToken); |
||||
|
} |
||||
|
|
||||
|
private async Task SetLanguageAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
var selectedLanguage = await _jsRuntime.InvokeAsync<string>( |
||||
|
"localStorage.getItem", |
||||
|
cancellationToken, |
||||
|
"Abp.SelectedLanguage" |
||||
|
); |
||||
|
|
||||
|
if (!selectedLanguage.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
request.Headers.AcceptLanguage.Clear(); |
||||
|
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class AbpWebAssemblyApplicationCreationOptions |
||||
|
{ |
||||
|
public WebAssemblyHostBuilder HostBuilder { get; } |
||||
|
|
||||
|
public AbpApplicationCreationOptions ApplicationCreationOptions { get; } |
||||
|
|
||||
|
public AbpWebAssemblyApplicationCreationOptions( |
||||
|
WebAssemblyHostBuilder hostBuilder, |
||||
|
AbpApplicationCreationOptions applicationCreationOptions) |
||||
|
{ |
||||
|
HostBuilder = hostBuilder; |
||||
|
ApplicationCreationOptions = applicationCreationOptions; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class ApplicationConfigurationCache : ISingletonDependency |
||||
|
{ |
||||
|
protected ApplicationConfigurationDto Configuration { get; set; } |
||||
|
|
||||
|
public virtual ApplicationConfigurationDto Get() |
||||
|
{ |
||||
|
return Configuration; |
||||
|
} |
||||
|
|
||||
|
internal void Set(ApplicationConfigurationDto configuration) |
||||
|
{ |
||||
|
Configuration = configuration; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public interface IUiMessageService |
||||
|
{ |
||||
|
Task<bool> ConfirmAsync(string message, string title = null); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.JSInterop; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class UiMessageService : IUiMessageService, ITransientDependency |
||||
|
{ |
||||
|
protected IJSRuntime JsRuntime { get; } |
||||
|
|
||||
|
public UiMessageService(IJSRuntime jsRuntime) |
||||
|
{ |
||||
|
JsRuntime = jsRuntime; |
||||
|
} |
||||
|
|
||||
|
public async Task<bool> ConfirmAsync(string message, string title = null) |
||||
|
{ |
||||
|
//TODO: Implement with sweetalert in a new package
|
||||
|
return await JsRuntime.InvokeAsync<bool>("confirm", message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client.DynamicProxying; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency |
||||
|
{ |
||||
|
protected IHttpClientProxy<IAbpApplicationConfigurationAppService> Proxy { get; } |
||||
|
|
||||
|
protected ApplicationConfigurationCache Cache { get; } |
||||
|
|
||||
|
public WebAssemblyCachedApplicationConfigurationClient( |
||||
|
IHttpClientProxy<IAbpApplicationConfigurationAppService> proxy, |
||||
|
ApplicationConfigurationCache cache) |
||||
|
{ |
||||
|
Proxy = proxy; |
||||
|
Cache = cache; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task InitializeAsync() |
||||
|
{ |
||||
|
Cache.Set(await Proxy.Service.GetAsync()); |
||||
|
} |
||||
|
|
||||
|
public virtual Task<ApplicationConfigurationDto> GetAsync() |
||||
|
{ |
||||
|
return Task.FromResult(GetConfigurationByChecking()); |
||||
|
} |
||||
|
|
||||
|
public virtual ApplicationConfigurationDto Get() |
||||
|
{ |
||||
|
return GetConfigurationByChecking(); |
||||
|
} |
||||
|
|
||||
|
private ApplicationConfigurationDto GetConfigurationByChecking() |
||||
|
{ |
||||
|
var configuration = Cache.Get(); |
||||
|
if (configuration == null) |
||||
|
{ |
||||
|
throw new AbpException( |
||||
|
$"{nameof(WebAssemblyCachedApplicationConfigurationClient)} should be initialized before using it."); |
||||
|
} |
||||
|
|
||||
|
return configuration; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Security.Claims; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class WebAssemblyCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency |
||||
|
{ |
||||
|
protected ICachedApplicationConfigurationClient ConfigurationClient { get; } |
||||
|
|
||||
|
public WebAssemblyCurrentPrincipalAccessor( |
||||
|
ICachedApplicationConfigurationClient configurationClient) |
||||
|
{ |
||||
|
ConfigurationClient = configurationClient; |
||||
|
} |
||||
|
|
||||
|
protected override ClaimsPrincipal GetClaimsPrincipal() |
||||
|
{ |
||||
|
var configuration = ConfigurationClient.Get(); |
||||
|
|
||||
|
var claims = new List<Claim>(); |
||||
|
|
||||
|
if (!configuration.CurrentUser.UserName.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.UserName,configuration.CurrentUser.UserName)); |
||||
|
} |
||||
|
|
||||
|
if (!configuration.CurrentUser.Email.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.Email,configuration.CurrentUser.Email)); |
||||
|
} |
||||
|
|
||||
|
if (configuration.CurrentUser.Id != null) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.UserId,configuration.CurrentUser.Id.ToString())); |
||||
|
} |
||||
|
|
||||
|
if (configuration.CurrentUser.TenantId != null) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentUser.TenantId.ToString())); |
||||
|
} |
||||
|
else if (configuration.CurrentTenant.Id != null) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentTenant.Id.ToString())); |
||||
|
} |
||||
|
|
||||
|
foreach (var role in configuration.CurrentUser.Roles) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.Role, role)); |
||||
|
} |
||||
|
|
||||
|
return new ClaimsPrincipal(new ClaimsIdentity(claims)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.AspNetCore.Mvc.MultiTenancy; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client.DynamicProxying; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class WebAssemblyRemoteTenantStore : ITenantStore, ITransientDependency |
||||
|
{ |
||||
|
protected IHttpClientProxy<IAbpTenantAppService> Proxy { get; } |
||||
|
|
||||
|
public WebAssemblyRemoteTenantStore( |
||||
|
IHttpClientProxy<IAbpTenantAppService> proxy) |
||||
|
{ |
||||
|
Proxy = proxy; |
||||
|
} |
||||
|
|
||||
|
public async Task<TenantConfiguration> FindAsync(string name) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name)); |
||||
|
} |
||||
|
|
||||
|
public async Task<TenantConfiguration> FindAsync(Guid id) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id)); |
||||
|
} |
||||
|
|
||||
|
public TenantConfiguration Find(string name) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name))); |
||||
|
} |
||||
|
|
||||
|
public TenantConfiguration Find(Guid id) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id))); |
||||
|
} |
||||
|
|
||||
|
protected virtual TenantConfiguration CreateTenantConfiguration(FindTenantResultDto tenantResultDto) |
||||
|
{ |
||||
|
if (!tenantResultDto.Success || tenantResultDto.TenantId == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name); |
||||
|
} |
||||
|
|
||||
|
protected virtual string CreateCacheKey(string tenantName) |
||||
|
{ |
||||
|
return $"RemoteTenantStore_Name_{tenantName}"; |
||||
|
} |
||||
|
|
||||
|
protected virtual string CreateCacheKey(Guid tenantId) |
||||
|
{ |
||||
|
return $"RemoteTenantStore_Id_{tenantId:N}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,24 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.AspNetCore.Mvc.Client.Common</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Mvc.Client.Common</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.Contracts\Volo.Abp.AspNetCore.Mvc.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Caching\Volo.Abp.Caching.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Http.Client\Volo.Abp.Http.Client.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,33 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.Client |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpHttpClientModule), |
||||
|
typeof(AbpAspNetCoreMvcContractsModule), |
||||
|
typeof(AbpCachingModule), |
||||
|
typeof(AbpLocalizationModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreMvcClientCommonModule : AbpModule |
||||
|
{ |
||||
|
public const string RemoteServiceName = "AbpMvcClient"; |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddHttpClientProxies( |
||||
|
typeof(AbpAspNetCoreMvcContractsModule).Assembly, |
||||
|
RemoteServiceName, |
||||
|
asDefaultServices: false |
||||
|
); |
||||
|
|
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.GlobalContributors.Add<RemoteLocalizationContributor>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,33 +1,11 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Volo.Abp.Modularity; |
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.Http.Client; |
|
||||
using Volo.Abp.Localization; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.Client |
namespace Volo.Abp.AspNetCore.Mvc.Client |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(AbpHttpClientModule), |
typeof(AbpAspNetCoreMvcClientCommonModule) |
||||
typeof(AbpAspNetCoreMvcContractsModule), |
|
||||
typeof(AbpCachingModule), |
|
||||
typeof(AbpLocalizationModule) |
|
||||
)] |
)] |
||||
public class AbpAspNetCoreMvcClientModule : AbpModule |
public class AbpAspNetCoreMvcClientModule : AbpModule |
||||
{ |
{ |
||||
public const string RemoteServiceName = "AbpMvcClient"; |
|
||||
|
|
||||
public override void ConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
context.Services.AddHttpClientProxies( |
|
||||
typeof(AbpAspNetCoreMvcContractsModule).Assembly, |
|
||||
RemoteServiceName, |
|
||||
asDefaultServices: false |
|
||||
); |
|
||||
|
|
||||
Configure<AbpLocalizationOptions>(options => |
|
||||
{ |
|
||||
options.GlobalContributors.Add<RemoteLocalizationContributor>(); |
|
||||
}); |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using Autofac; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting |
||||
|
{ |
||||
|
public static class AbpWebAssemblyApplicationCreationOptionsAutofacExtensions |
||||
|
{ |
||||
|
public static void UseAutofac( |
||||
|
[NotNull] this AbpWebAssemblyApplicationCreationOptions options, |
||||
|
[CanBeNull] Action<ContainerBuilder> configure = null) |
||||
|
{ |
||||
|
options.HostBuilder.Services.AddAutofacServiceProviderFactory(); |
||||
|
options.HostBuilder.ConfigureContainer( |
||||
|
options.HostBuilder.Services.GetSingletonInstance<IServiceProviderFactory<ContainerBuilder>>(), |
||||
|
configure |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly\Volo.Abp.AspNetCore.Components.WebAssembly.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.Autofac.WebAssembly |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(AbpAspNetCoreComponentsWebAssemblyModule) |
||||
|
)] |
||||
|
public class AbpAutofacWebAssemblyModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,24 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly\Volo.Abp.AspNetCore.Components.WebAssembly.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Blazorise" Version="0.9.1.2" /> |
||||
|
<PackageReference Include="Blazorise.DataGrid" Version="0.9.1.2" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,23 @@ |
|||||
|
using Blazorise; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreComponentsWebAssemblyModule) |
||||
|
)] |
||||
|
public class AbpBlazoriseUIModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
ConfigureBlazorise(context); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureBlazorise(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services |
||||
|
.AddBlazorise(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,235 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Blazorise; |
||||
|
using Blazorise.DataGrid; |
||||
|
using Localization.Resources.AbpUi; |
||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI |
||||
|
{ |
||||
|
public abstract class BlazoriseCrudPageBase<TAppService, TEntityDto, TKey> |
||||
|
: BlazoriseCrudPageBase<TAppService, TEntityDto, TKey, PagedAndSortedResultRequestDto> |
||||
|
where TAppService : ICrudAppService<TEntityDto, TKey> |
||||
|
where TEntityDto : IEntityDto<TKey>, new() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public abstract class BlazoriseCrudPageBase<TAppService, TEntityDto, TKey, TGetListInput> |
||||
|
: BlazoriseCrudPageBase<TAppService, TEntityDto, TKey, TGetListInput, TEntityDto> |
||||
|
where TAppService : ICrudAppService<TEntityDto, TKey, TGetListInput> |
||||
|
where TEntityDto : IEntityDto<TKey>, new() |
||||
|
where TGetListInput : new() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public abstract class BlazoriseCrudPageBase<TAppService, TEntityDto, TKey, TGetListInput, TCreateInput> |
||||
|
: BlazoriseCrudPageBase<TAppService, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput> |
||||
|
where TAppService : ICrudAppService<TEntityDto, TKey, TGetListInput, TCreateInput> |
||||
|
where TEntityDto : IEntityDto<TKey> |
||||
|
where TCreateInput : new() |
||||
|
where TGetListInput : new() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public abstract class BlazoriseCrudPageBase<TAppService, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput> |
||||
|
: BlazoriseCrudPageBase<TAppService, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput> |
||||
|
where TAppService : ICrudAppService<TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput> |
||||
|
where TEntityDto : IEntityDto<TKey> |
||||
|
where TCreateInput : new() |
||||
|
where TUpdateInput : new() |
||||
|
where TGetListInput : new() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public abstract class BlazoriseCrudPageBase<TAppService, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput> |
||||
|
: OwningComponentBase |
||||
|
where TAppService : ICrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput> |
||||
|
where TGetOutputDto : IEntityDto<TKey> |
||||
|
where TGetListOutputDto : IEntityDto<TKey> |
||||
|
where TCreateInput : new() |
||||
|
where TUpdateInput : new() |
||||
|
where TGetListInput : new() |
||||
|
{ |
||||
|
[Inject] protected TAppService AppService { get; set; } |
||||
|
[Inject] protected IUiMessageService UiMessageService { get; set; } |
||||
|
[Inject] protected IStringLocalizer<AbpUiResource> UiLocalizer { get; set; } |
||||
|
|
||||
|
protected virtual int PageSize { get; } = LimitedResultRequestDto.DefaultMaxResultCount; |
||||
|
|
||||
|
protected int CurrentPage; |
||||
|
protected string CurrentSorting; |
||||
|
protected int? TotalCount; |
||||
|
protected IReadOnlyList<TGetListOutputDto> Entities = Array.Empty<TGetListOutputDto>(); |
||||
|
protected TCreateInput NewEntity; |
||||
|
protected TKey EditingEntityId; |
||||
|
protected TUpdateInput EditingEntity; |
||||
|
protected Modal CreateModal; |
||||
|
protected Modal EditModal; |
||||
|
|
||||
|
protected Type ObjectMapperContext { get; set; } |
||||
|
|
||||
|
protected IObjectMapper ObjectMapper |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (_objectMapper != null) |
||||
|
{ |
||||
|
return _objectMapper; |
||||
|
} |
||||
|
|
||||
|
if (ObjectMapperContext == null) |
||||
|
{ |
||||
|
return LazyGetRequiredService(ref _objectMapper); |
||||
|
} |
||||
|
|
||||
|
return LazyGetRequiredService( |
||||
|
typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), |
||||
|
ref _objectMapper |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private IObjectMapper _objectMapper; |
||||
|
|
||||
|
protected TService LazyGetRequiredService<TService>(ref TService reference) |
||||
|
=> LazyGetRequiredService(typeof(TService), ref reference); |
||||
|
|
||||
|
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
reference = (TRef) ScopedServices.GetRequiredService(serviceType); |
||||
|
} |
||||
|
|
||||
|
return reference; |
||||
|
} |
||||
|
|
||||
|
protected BlazoriseCrudPageBase() |
||||
|
{ |
||||
|
NewEntity = new TCreateInput(); |
||||
|
EditingEntity = new TUpdateInput(); |
||||
|
} |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
await GetEntitiesAsync(); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task GetEntitiesAsync() |
||||
|
{ |
||||
|
var input = await CreateGetListInputAsync(); |
||||
|
var result = await AppService.GetListAsync(input); |
||||
|
Entities = result.Items; |
||||
|
TotalCount = (int?) result.TotalCount; |
||||
|
} |
||||
|
|
||||
|
protected virtual Task<TGetListInput> CreateGetListInputAsync() |
||||
|
{ |
||||
|
var input = new TGetListInput(); |
||||
|
|
||||
|
if (input is ISortedResultRequest sortedResultRequestInput) |
||||
|
{ |
||||
|
sortedResultRequestInput.Sorting = CurrentSorting; |
||||
|
} |
||||
|
|
||||
|
if (input is IPagedResultRequest pagedResultRequestInput) |
||||
|
{ |
||||
|
pagedResultRequestInput.SkipCount = CurrentPage * PageSize; |
||||
|
} |
||||
|
|
||||
|
if (input is ILimitedResultRequest limitedResultRequestInput) |
||||
|
{ |
||||
|
limitedResultRequestInput.MaxResultCount = PageSize; |
||||
|
} |
||||
|
|
||||
|
return Task.FromResult(input); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task OnDataGridReadAsync(DataGridReadDataEventArgs<TGetListOutputDto> e) |
||||
|
{ |
||||
|
CurrentSorting = e.Columns |
||||
|
.Where(c => c.Direction != SortDirection.None) |
||||
|
.Select(c => c.Field + (c.Direction == SortDirection.Descending ? " DESC" : "")) |
||||
|
.JoinAsString(","); |
||||
|
CurrentPage = e.Page - 1; |
||||
|
|
||||
|
await GetEntitiesAsync(); |
||||
|
|
||||
|
StateHasChanged(); |
||||
|
} |
||||
|
|
||||
|
protected virtual Task OpenCreateModalAsync() |
||||
|
{ |
||||
|
NewEntity = new TCreateInput(); |
||||
|
CreateModal.Show(); |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
protected virtual Task CloseCreateModalAsync() |
||||
|
{ |
||||
|
CreateModal.Hide(); |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task OpenEditModalAsync(TKey id) |
||||
|
{ |
||||
|
var entityDto = await AppService.GetAsync(id); |
||||
|
EditingEntityId = id; |
||||
|
EditingEntity = MapToEditingEntity(entityDto); |
||||
|
EditModal.Show(); |
||||
|
} |
||||
|
|
||||
|
protected virtual TUpdateInput MapToEditingEntity(TGetOutputDto entityDto) |
||||
|
{ |
||||
|
return ObjectMapper.Map<TGetOutputDto, TUpdateInput>(entityDto); |
||||
|
} |
||||
|
|
||||
|
protected virtual Task CloseEditModalAsync() |
||||
|
{ |
||||
|
EditModal.Hide(); |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task CreateEntityAsync() |
||||
|
{ |
||||
|
await AppService.CreateAsync(NewEntity); |
||||
|
await GetEntitiesAsync(); |
||||
|
CreateModal.Hide(); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task UpdateEntityAsync() |
||||
|
{ |
||||
|
await AppService.UpdateAsync(EditingEntityId, EditingEntity); |
||||
|
await GetEntitiesAsync(); |
||||
|
EditModal.Hide(); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task DeleteEntityAsync(TGetListOutputDto entity) |
||||
|
{ |
||||
|
if (!await UiMessageService.ConfirmAsync(GetDeleteConfirmationMessage(entity))) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await AppService.DeleteAsync(entity.Id); |
||||
|
await GetEntitiesAsync(); |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetDeleteConfirmationMessage(TGetListOutputDto entity) |
||||
|
{ |
||||
|
return UiLocalizer["ItemWillBeDeletedMessage"]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,25 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.Http.Client.IdentityModel.WebAssembly</AssemblyName> |
||||
|
<PackageId>Volo.Abp.Http.Client.IdentityModel.WebAssembly</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="3.2.1" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.Http.Client.IdentityModel\Volo.Abp.Http.Client.IdentityModel.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,13 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpHttpClientIdentityModelModule) |
||||
|
)] |
||||
|
public class AbpHttpClientIdentityModelWebAssemblyModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using IdentityModel.Client; |
||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Authentication; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client.Authentication; |
||||
|
using Volo.Abp.IdentityModel; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly |
||||
|
{ |
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator |
||||
|
{ |
||||
|
protected IAccessTokenProvider AccessTokenProvider { get; } |
||||
|
|
||||
|
public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator( |
||||
|
IIdentityModelAuthenticationService identityModelAuthenticationService, |
||||
|
IAccessTokenProvider accessTokenProvider) |
||||
|
: base(identityModelAuthenticationService) |
||||
|
{ |
||||
|
AccessTokenProvider = accessTokenProvider; |
||||
|
} |
||||
|
|
||||
|
public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) |
||||
|
{ |
||||
|
if (context.RemoteService.GetUseCurrentAccessToken() != false) |
||||
|
{ |
||||
|
var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync(); |
||||
|
if (accessToken != null) |
||||
|
{ |
||||
|
context.Request.SetBearerToken(accessToken); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
await base.Authenticate(context); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<string> GetAccessTokenFromAccessTokenProviderOrNullAsync() |
||||
|
{ |
||||
|
var result = await AccessTokenProvider.RequestAccessToken(); |
||||
|
if (result.Status != AccessTokenResultStatus.Success) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
result.TryGetToken(out var token); |
||||
|
return token.Value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client |
||||
|
{ |
||||
|
public class AbpHttpClientBuilderOptions |
||||
|
{ |
||||
|
public List<Action<string, IHttpClientBuilder>> ProxyClientBuildActions { get; } |
||||
|
|
||||
|
internal HashSet<string> ConfiguredProxyClients { get; } |
||||
|
|
||||
|
public AbpHttpClientBuilderOptions() |
||||
|
{ |
||||
|
ProxyClientBuildActions = new List<Action<string, IHttpClientBuilder>>(); |
||||
|
ConfiguredProxyClients = new HashSet<string>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
using System.Security.Claims; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Volo.Abp.Security.Claims |
||||
|
{ |
||||
|
public abstract class CurrentPrincipalAccessorBase : ICurrentPrincipalAccessor |
||||
|
{ |
||||
|
public ClaimsPrincipal Principal => _currentPrincipal.Value ?? GetClaimsPrincipal(); |
||||
|
|
||||
|
private readonly AsyncLocal<ClaimsPrincipal> _currentPrincipal = new AsyncLocal<ClaimsPrincipal>(); |
||||
|
|
||||
|
protected abstract ClaimsPrincipal GetClaimsPrincipal(); |
||||
|
|
||||
|
public virtual IDisposable Change(ClaimsPrincipal principal) |
||||
|
{ |
||||
|
return SetCurrent(principal); |
||||
|
} |
||||
|
|
||||
|
private IDisposable SetCurrent(ClaimsPrincipal principal) |
||||
|
{ |
||||
|
var parent = Principal; |
||||
|
_currentPrincipal.Value = principal; |
||||
|
return new DisposeAction(() => |
||||
|
{ |
||||
|
_currentPrincipal.Value = parent; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,34 +1,14 @@ |
|||||
using System; |
using System.Security.Claims; |
||||
using System.Security.Claims; |
|
||||
using System.Threading; |
using System.Threading; |
||||
using Volo.Abp.DependencyInjection; |
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
namespace Volo.Abp.Security.Claims |
namespace Volo.Abp.Security.Claims |
||||
{ |
{ |
||||
public class ThreadCurrentPrincipalAccessor : ICurrentPrincipalAccessor, ISingletonDependency |
public class ThreadCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ISingletonDependency |
||||
{ |
{ |
||||
public ClaimsPrincipal Principal => _currentPrincipal.Value ?? GetClaimsPrincipal(); |
protected override ClaimsPrincipal GetClaimsPrincipal() |
||||
|
|
||||
private readonly AsyncLocal<ClaimsPrincipal> _currentPrincipal = new AsyncLocal<ClaimsPrincipal>(); |
|
||||
|
|
||||
protected virtual ClaimsPrincipal GetClaimsPrincipal() |
|
||||
{ |
{ |
||||
return Thread.CurrentPrincipal as ClaimsPrincipal; |
return Thread.CurrentPrincipal as ClaimsPrincipal; |
||||
} |
} |
||||
|
|
||||
public virtual IDisposable Change(ClaimsPrincipal principal) |
|
||||
{ |
|
||||
return SetCurrent(principal); |
|
||||
} |
|
||||
|
|
||||
private IDisposable SetCurrent(ClaimsPrincipal principal) |
|
||||
{ |
|
||||
var parent = Principal; |
|
||||
_currentPrincipal.Value = principal; |
|
||||
return new DisposeAction(() => |
|
||||
{ |
|
||||
_currentPrincipal.Value = parent; |
|
||||
}); |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,13 @@ |
|||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Ui.Branding |
||||
|
{ |
||||
|
public class DefaultBrandingProvider : IBrandingProvider, ITransientDependency |
||||
|
{ |
||||
|
public virtual string AppName => "MyApplication"; |
||||
|
|
||||
|
public virtual string LogoUrl => null; |
||||
|
|
||||
|
public virtual string LogoReverseUrl => null; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
namespace Volo.Abp.Ui.Branding |
||||
|
{ |
||||
|
public interface IBrandingProvider |
||||
|
{ |
||||
|
string AppName { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Logo on white background
|
||||
|
/// </summary>
|
||||
|
string LogoUrl { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Logo on dark background
|
||||
|
/// </summary>
|
||||
|
string LogoReverseUrl { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement.Blazor |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule), |
||||
|
typeof(AbpAutoMapperModule), |
||||
|
typeof(AbpFeatureManagementHttpApiClientModule) |
||||
|
)] |
||||
|
public class AbpFeatureManagementBlazorModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
@using Microsoft.Extensions.Localization |
||||
|
@using Volo.Abp.FeatureManagement.Localization |
||||
|
@using Volo.Abp.Validation.StringValues |
||||
|
@inject IStringLocalizer<AbpFeatureManagementResource> L |
||||
|
|
||||
|
<Modal @ref="_modal"> |
||||
|
<ModalBackdrop /> |
||||
|
<ModalContent Size="ModalSize.Large" IsCentered="true"> |
||||
|
<ModalHeader> |
||||
|
<ModalTitle>@L["Features"]</ModalTitle> |
||||
|
<CloseButton Clicked="CloseModal" /> |
||||
|
</ModalHeader> |
||||
|
<ModalBody MaxHeight="50"> |
||||
|
@if (_groups == null) |
||||
|
{ |
||||
|
<span>@L["NoFeatureFoundMessage"]</span> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<Tabs TabPosition="TabPosition.Left" Pills="true" SelectedTab="@GetNormalizedGroupName(_groups.First().Name)"> |
||||
|
<Items> |
||||
|
@foreach (var group in _groups) |
||||
|
{ |
||||
|
<Tab Name="@GetNormalizedGroupName(group.Name)"> |
||||
|
<span>@group.DisplayName</span> |
||||
|
</Tab> |
||||
|
} |
||||
|
</Items> |
||||
|
<Content> |
||||
|
@foreach (var group in _groups) |
||||
|
{ |
||||
|
<TabPanel Name="@GetNormalizedGroupName(group.Name)"> |
||||
|
<h4>@group.DisplayName</h4> |
||||
|
|
||||
|
@foreach (var feature in group.Features) |
||||
|
{ |
||||
|
var disabled = IsDisabled(feature.Provider.Name); |
||||
|
|
||||
|
if (feature.ValueType is FreeTextStringValueType) |
||||
|
{ |
||||
|
<Field> |
||||
|
<FieldLabel>@feature.DisplayName</FieldLabel> |
||||
|
<TextEdit Disabled="@disabled" @bind-text="@feature.Value" /> |
||||
|
@if (feature.Description != null) |
||||
|
{ |
||||
|
<span>@feature.Description</span> |
||||
|
} |
||||
|
</Field> |
||||
|
} |
||||
|
|
||||
|
if (feature.ValueType is SelectionStringValueType) |
||||
|
{ |
||||
|
var items = ((SelectionStringValueType) feature.ValueType).ItemSource.Items; |
||||
|
|
||||
|
<Field> |
||||
|
<FieldLabel>@feature.DisplayName</FieldLabel> |
||||
|
<Select TValue="string" SelectedValue="feature.Value"> |
||||
|
@foreach (var item in items) |
||||
|
{ |
||||
|
<SelectItem Value="@item.Value">@item.DisplayText</SelectItem> |
||||
|
} |
||||
|
</Select> |
||||
|
</Field> |
||||
|
} |
||||
|
|
||||
|
if (feature.ValueType is ToggleStringValueType) |
||||
|
{ |
||||
|
<Field> |
||||
|
<Check TValue="bool" @bind-checked="@ToggleValues[feature.Name]">@feature.DisplayName</Check> |
||||
|
</Field> |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
</TabPanel> |
||||
|
} |
||||
|
</Content> |
||||
|
</Tabs> |
||||
|
} |
||||
|
</ModalBody> |
||||
|
<ModalFooter> |
||||
|
<Button Color="Color.Secondary" Clicked="CloseModal">@L["Cancel"]</Button> |
||||
|
<Button Color="Color.Primary" Clicked="SaveAsync">@L["Save"]</Button> |
||||
|
</ModalFooter> |
||||
|
</ModalContent> |
||||
|
</Modal> |
||||
@ -0,0 +1,70 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Blazorise; |
||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Volo.Abp.Features; |
||||
|
using Volo.Abp.Validation.StringValues; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement.Blazor.Components |
||||
|
{ |
||||
|
public partial class FeatureManagementModal |
||||
|
{ |
||||
|
[Inject] private IFeatureAppService FeatureAppService { get; set; } |
||||
|
|
||||
|
private Modal _modal; |
||||
|
|
||||
|
private string _providerName; |
||||
|
private string _providerKey; |
||||
|
|
||||
|
private List<FeatureGroupDto> _groups { get; set; } |
||||
|
|
||||
|
private Dictionary<string, bool> ToggleValues; |
||||
|
|
||||
|
public async Task OpenAsync(string providerName, string providerKey) |
||||
|
{ |
||||
|
_providerName = providerName; |
||||
|
_providerKey = providerKey; |
||||
|
|
||||
|
_groups = (await FeatureAppService.GetAsync(_providerName, _providerKey)).Groups; |
||||
|
|
||||
|
ToggleValues = _groups |
||||
|
.SelectMany(x => x.Features) |
||||
|
.Where(x => x.ValueType is ToggleStringValueType) |
||||
|
.ToDictionary(x => x.Name, x => bool.Parse(x.Value)); |
||||
|
|
||||
|
_modal.Show(); |
||||
|
} |
||||
|
|
||||
|
private void CloseModal() |
||||
|
{ |
||||
|
_modal.Hide(); |
||||
|
} |
||||
|
|
||||
|
private async Task SaveAsync() |
||||
|
{ |
||||
|
var features = new UpdateFeaturesDto |
||||
|
{ |
||||
|
Features = _groups.SelectMany(g => g.Features).Select(f => new UpdateFeatureDto |
||||
|
{ |
||||
|
Name = f.Name, |
||||
|
Value = f.ValueType is ToggleStringValueType ? ToggleValues[f.Name].ToString() : f.Value |
||||
|
}).ToList() |
||||
|
}; |
||||
|
|
||||
|
await FeatureAppService.UpdateAsync(_providerName, _providerKey, features); |
||||
|
|
||||
|
_modal.Hide(); |
||||
|
} |
||||
|
|
||||
|
public string GetNormalizedGroupName(string name) |
||||
|
{ |
||||
|
return "FeatureGroup_" + name.Replace(".", "_"); |
||||
|
} |
||||
|
|
||||
|
public virtual bool IsDisabled(string providerName) |
||||
|
{ |
||||
|
return providerName != _providerName && providerName != DefaultValueFeatureValueProvider.ProviderName; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,29 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RazorLangVersion>3.0</RazorLangVersion> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.FeatureManagement.HttpApi.Client\Volo.Abp.FeatureManagement.HttpApi.Client.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Content Update="_Imports.razor"> |
||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> |
||||
|
</Content> |
||||
|
<Content Update="Components\FeatureManagementModal.razor"> |
||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> |
||||
|
</Content> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,5 @@ |
|||||
|
@using Microsoft.AspNetCore.Components.Web |
||||
|
@using Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
@using Volo.Abp.BlazoriseUI |
||||
|
@using Blazorise |
||||
|
@using Blazorise.DataGrid |
||||
@ -0,0 +1,4 @@ |
|||||
|
src/Volo.Abp.Identity.HttpApi/Properties/launchSettings.json |
||||
|
src/Volo.Abp.Identity.Web/Properties/launchSettings.json |
||||
|
test/Volo.Abp.Identity.AspNetCore.Tests/Properties/launchSettings.json |
||||
|
src/Volo.Abp.Identity.AspNetCore/Properties/launchSettings.json |
||||
@ -0,0 +1,24 @@ |
|||||
|
using AutoMapper; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.Blazor |
||||
|
{ |
||||
|
public class AbpIdentityBlazorAutoMapperProfile : Profile |
||||
|
{ |
||||
|
public AbpIdentityBlazorAutoMapperProfile() |
||||
|
{ |
||||
|
CreateMap<IdentityUserDto, IdentityUserUpdateDto>() |
||||
|
.MapExtraProperties() |
||||
|
.Ignore(x => x.Password) |
||||
|
.Ignore(x => x.RoleNames); |
||||
|
|
||||
|
CreateMap<IdentityRoleDto, IdentityRoleUpdateDto>() |
||||
|
.MapExtraProperties(); |
||||
|
|
||||
|
CreateMap<IdentityUserDto, IdentityUserUpdateDto>() |
||||
|
.Ignore(x => x.Password) |
||||
|
.Ignore(x => x.RoleNames) |
||||
|
.MapExtraProperties(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.PermissionManagement.Blazor; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.Blazor |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpIdentityHttpApiClientModule), |
||||
|
typeof(AbpAutoMapperModule), |
||||
|
typeof(AbpPermissionManagementBlazorModule) |
||||
|
)] |
||||
|
public class AbpIdentityBlazorModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddAutoMapperObjectMapper<AbpIdentityBlazorModule>(); |
||||
|
|
||||
|
Configure<AbpAutoMapperOptions>(options => |
||||
|
{ |
||||
|
options.AddProfile<AbpIdentityBlazorAutoMapperProfile>(validate: true); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpNavigationOptions>(options => |
||||
|
{ |
||||
|
options.MenuContributors.Add(new AbpIdentityWebMainMenuContributor()); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpRouterOptions>(options => |
||||
|
{ |
||||
|
options.AdditionalAssemblies.Add(typeof(AbpIdentityBlazorModule).Assembly); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Identity.Localization; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.Blazor |
||||
|
{ |
||||
|
public class AbpIdentityWebMainMenuContributor : IMenuContributor |
||||
|
{ |
||||
|
public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context) |
||||
|
{ |
||||
|
if (context.Menu.Name != StandardMenus.Main) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var hasRolePermission = await context.IsGrantedAsync(IdentityPermissions.Roles.Default); |
||||
|
var hasUserPermission = await context.IsGrantedAsync(IdentityPermissions.Users.Default); |
||||
|
|
||||
|
if (hasRolePermission || hasUserPermission) |
||||
|
{ |
||||
|
var administrationMenu = context.Menu.GetAdministration(); |
||||
|
|
||||
|
var l = context.GetLocalizer<IdentityResource>(); |
||||
|
|
||||
|
var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o"); |
||||
|
administrationMenu.AddItem(identityMenuItem); |
||||
|
|
||||
|
if (hasRolePermission) |
||||
|
{ |
||||
|
identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "/identity/roles")); |
||||
|
} |
||||
|
|
||||
|
if (hasUserPermission) |
||||
|
{ |
||||
|
identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "/identity/users")); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue