47 changed files with 912 additions and 108 deletions
@ -1,2 +1,13 @@ |
|||
# Lsw.Abp.AntDesignUI |
|||
|
|||
|
|||
## Still in progress! |
|||
|
|||
An Abp Blazor Theme based [Ant-Design-Blazor](https://github.com/ant-design-blazor/ant-design-blazor) |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
@ -1,50 +1,50 @@ |
|||
@using Microsoft.Extensions.Options |
|||
@inject IOptions<PageHeaderOptions> Options |
|||
|
|||
<Row Style="margin-left: 15px"> |
|||
<Breadcrumb> |
|||
@if (Options.Value.RenderPageTitle) |
|||
{ |
|||
<b>@PageLayout.Title</b> |
|||
} |
|||
|
|||
@if (Options.Value.RenderBreadcrumbs && PageLayout.BreadcrumbItems.Any()) |
|||
{ |
|||
@if (BreadcrumbShowHome) |
|||
<Row Class="ant-design-row-breadcrumb"> |
|||
<Col Span="12"> |
|||
<Breadcrumb Class="ant-design-breadcrumb"> |
|||
@if (Options.Value.RenderBreadcrumbs && PageLayout.BreadcrumbItems.Any()) |
|||
{ |
|||
<BreadcrumbItem Href=""> |
|||
<Icon Type="home"/> |
|||
</BreadcrumbItem> |
|||
} |
|||
@foreach (var item in PageLayout.BreadcrumbItems) |
|||
{ |
|||
<BreadcrumbItem Href="@item.Url"> |
|||
@if (!item.Icon.IsNullOrWhiteSpace()) |
|||
{ |
|||
<Icon Type="@item.Icon"/> |
|||
} |
|||
@item.Text |
|||
</BreadcrumbItem> |
|||
@if (BreadcrumbShowHome) |
|||
{ |
|||
<BreadcrumbItem Href=""> |
|||
<Icon Type="home"/> |
|||
</BreadcrumbItem> |
|||
} |
|||
@foreach (var item in PageLayout.BreadcrumbItems) |
|||
{ |
|||
<BreadcrumbItem Href="@item.Url"> |
|||
@if (!item.Icon.IsNullOrWhiteSpace()) |
|||
{ |
|||
<Icon Type="@item.Icon"/> |
|||
} |
|||
@item.Text |
|||
</BreadcrumbItem> |
|||
} |
|||
} |
|||
} |
|||
</Breadcrumb> |
|||
|
|||
@if (Options.Value.RenderToolbar) |
|||
{ |
|||
<div> |
|||
</Breadcrumb> |
|||
</Col> |
|||
|
|||
<Col Span="12"> |
|||
@if (Options.Value.RenderToolbar) |
|||
{ |
|||
<Row justify="end"> |
|||
@if (Toolbar == null) |
|||
{ |
|||
@ChildContent |
|||
} |
|||
|
|||
@foreach (var toolbarItemRender in ToolbarItemRenders) |
|||
{ |
|||
<div class="px-1 pt-2"> |
|||
<div style="margin: 0 5px"> |
|||
@toolbarItemRender |
|||
</div> |
|||
} |
|||
</Row> |
|||
</div> |
|||
} |
|||
} |
|||
</Col> |
|||
</Row> |
|||
@if (Options.Value.RenderPageTitle) |
|||
{ |
|||
<div class="ant-design-page-title">@PageLayout.Title</div> |
|||
} |
|||
|
|||
@ -0,0 +1,9 @@ |
|||
using Microsoft.AspNetCore.Components; |
|||
|
|||
namespace Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Themes.AntDesignTheme; |
|||
|
|||
public partial class Branding |
|||
{ |
|||
[Parameter] |
|||
public bool Collapsed { get; set; } |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
@foreach (var render in ToolbarItemRenders) |
|||
{ |
|||
@render |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Toolbars; |
|||
using Microsoft.AspNetCore.Components; |
|||
using Microsoft.AspNetCore.Components.Authorization; |
|||
|
|||
namespace Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Themes.AntDesignTheme; |
|||
|
|||
public partial class NavToolbar: IDisposable |
|||
{ |
|||
[Inject] |
|||
private IToolbarManager ToolbarManager { get; set; } |
|||
|
|||
[Inject] |
|||
private AuthenticationStateProvider AuthenticationStateProvider { get; set; } |
|||
|
|||
private List<RenderFragment> ToolbarItemRenders { get; set; } = new(); |
|||
|
|||
protected override async Task OnInitializedAsync() |
|||
{ |
|||
await GetToolbarItemRendersAsync(); |
|||
AuthenticationStateProvider.AuthenticationStateChanged += AuthenticationStateProviderOnAuthenticationStateChanged; |
|||
} |
|||
|
|||
private async Task GetToolbarItemRendersAsync() |
|||
{ |
|||
var toolbar = await ToolbarManager.GetAsync(StandardToolbars.Main); |
|||
|
|||
ToolbarItemRenders.Clear(); |
|||
|
|||
var sequence = 0; |
|||
foreach (var item in toolbar.Items) |
|||
{ |
|||
ToolbarItemRenders.Add(builder => |
|||
{ |
|||
builder.OpenComponent(sequence++, item.ComponentType); |
|||
builder.CloseComponent(); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
private async void AuthenticationStateProviderOnAuthenticationStateChanged(Task<AuthenticationState> task) |
|||
{ |
|||
await GetToolbarItemRendersAsync(); |
|||
await InvokeAsync(StateHasChanged); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
AuthenticationStateProvider.AuthenticationStateChanged -= AuthenticationStateProviderOnAuthenticationStateChanged; |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using System.Threading.Tasks; |
|||
using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Toolbars; |
|||
using Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme.Themes.AntDesignTheme; |
|||
using Microsoft.AspNetCore.Components.Authorization; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme; |
|||
|
|||
public class AntDesignThemeToolbarContributor: IToolbarContributor |
|||
{ |
|||
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) |
|||
{ |
|||
if (context.Toolbar.Name == StandardToolbars.Main) |
|||
{ |
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitch))); |
|||
|
|||
var authenticationStateProvider = context.ServiceProvider |
|||
.GetRequiredService<AuthenticationStateProvider>(); |
|||
|
|||
if (authenticationStateProvider != null) |
|||
{ |
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay))); |
|||
} |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -1,20 +1,21 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
|||
|
|||
<Import Project="..\..\configureawait.props"/> |
|||
<Import Project="..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme\Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.csproj"/> |
|||
<ProjectReference Include="..\Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme\Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Components.WebAssembly" Version="5.1.3"/> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.1"/> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.1"/> |
|||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0"/> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.0" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Components.WebAssembly" Version="5.1.3" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.1" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.1" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
|
|||
@ -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,79 @@ |
|||
@using Volo.Abp.Localization |
|||
@using System.Collections.Immutable |
|||
@using System.Globalization |
|||
@using Microsoft.JSInterop |
|||
@inject ILanguageProvider LanguageProvider |
|||
@inject IJSRuntime JsRuntime |
|||
|
|||
@if (_otherLanguages != null && _otherLanguages.Any()) |
|||
{ |
|||
<Dropdown> |
|||
<Overlay> |
|||
<Menu> |
|||
@foreach (var language in _otherLanguages) |
|||
{ |
|||
<MenuItem OnClick="() => ChangeLanguageAsync(language)"> |
|||
@language.DisplayName |
|||
</MenuItem> |
|||
} |
|||
</Menu> |
|||
</Overlay> |
|||
<ChildContent> |
|||
<a class="ant-dropdown-link" @onclick:preventDefault> |
|||
@_currentLanguage.DisplayName <Icon Type="down" /> |
|||
</a> |
|||
</ChildContent> |
|||
</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(); |
|||
} |
|||
|
|||
protected virtual async Task ChangeLanguageAsync(LanguageInfo language) |
|||
{ |
|||
await JsRuntime.InvokeVoidAsync( |
|||
"localStorage.setItem", |
|||
"Abp.SelectedLanguage", language.UiCultureName |
|||
); |
|||
|
|||
await JsRuntime.InvokeVoidAsync( |
|||
"localStorage.setItem", |
|||
"Abp.IsRtl", CultureInfo.GetCultureInfo(language.UiCultureName).TextInfo.IsRightToLeft |
|||
); |
|||
|
|||
await JsRuntime.InvokeVoidAsync("location.reload"); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
@using global::Localization.Resources.AbpUi |
|||
@using Microsoft.Extensions.Localization |
|||
@* @using Microsoft.AspNetCore.Components.Authorization *@ |
|||
@using Microsoft.JSInterop |
|||
@inherits Volo.Abp.AspNetCore.Components.AbpComponentBase |
|||
@inject IJSRuntime JsRuntime |
|||
@inject NavigationManager Navigation |
|||
@inject IStringLocalizer<AbpUiResource> UiLocalizer |
|||
|
|||
<AuthorizeView> |
|||
<Authorized> |
|||
<Dropdown> |
|||
<Overlay> |
|||
<Menu> |
|||
@if (Menu != null) |
|||
{ |
|||
@foreach (var menuItem in Menu.Items) |
|||
{ |
|||
<MenuItem OnClick="@(() => NavigateToAsync(menuItem.Url, menuItem.Target))"> |
|||
@menuItem.DisplayName |
|||
</MenuItem> |
|||
} |
|||
} |
|||
<MenuDivider/> |
|||
<MenuItem OnClick="BeginSignOut"> |
|||
@UiLocalizer["Logout"] |
|||
</MenuItem> |
|||
</Menu> |
|||
</Overlay> |
|||
<ChildContent> |
|||
@* @if (CurrentTenant.Name != null) *@ |
|||
@* { *@ |
|||
@* <span><i>@CurrentTenant.Name</i>\@CurrentUser.UserName</span> *@ |
|||
@* } *@ |
|||
@* else *@ |
|||
@* { *@ |
|||
@* <span>@CurrentUser.UserName</span> *@ |
|||
@* } *@ |
|||
@* <Icon Type="down" /> *@ |
|||
</ChildContent> |
|||
</Dropdown> |
|||
</Authorized> |
|||
<NotAuthorized> |
|||
<a class="nav-link" href="authentication/login">@UiLocalizer["Login"]</a> |
|||
</NotAuthorized> |
|||
</AuthorizeView> |
|||
@ -0,0 +1,76 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Components; |
|||
using Microsoft.AspNetCore.Components.Authorization; |
|||
using Microsoft.AspNetCore.Components.Routing; |
|||
using Microsoft.AspNetCore.Components.WebAssembly.Authentication; |
|||
using Microsoft.JSInterop; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace Lsw.Abp.AspnetCore.Components.WebAssembly.AntDesignTheme.Themes.AntDesignTheme; |
|||
|
|||
public partial class LoginDisplay : IDisposable |
|||
{ |
|||
[Inject] |
|||
protected IMenuManager MenuManager { get; set; } |
|||
|
|||
[Inject] |
|||
public AuthenticationStateProvider AuthenticationStateProvider { get; set; } |
|||
|
|||
[CanBeNull] |
|||
protected SignOutSessionStateManager SignOutManager; |
|||
|
|||
protected ApplicationMenu Menu { get; set; } |
|||
|
|||
protected override async Task OnInitializedAsync() |
|||
{ |
|||
Menu = await MenuManager.GetAsync(StandardMenus.User); |
|||
|
|||
Navigation.LocationChanged += OnLocationChanged; |
|||
|
|||
LazyGetService(ref SignOutManager); |
|||
|
|||
AuthenticationStateProvider.AuthenticationStateChanged += |
|||
AuthenticationStateProviderOnAuthenticationStateChanged; |
|||
} |
|||
|
|||
protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e) |
|||
{ |
|||
InvokeAsync(StateHasChanged); |
|||
} |
|||
|
|||
private async void AuthenticationStateProviderOnAuthenticationStateChanged(Task<AuthenticationState> task) |
|||
{ |
|||
Menu = await MenuManager.GetAsync(StandardMenus.User); |
|||
await InvokeAsync(StateHasChanged); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
Navigation.LocationChanged -= OnLocationChanged; |
|||
AuthenticationStateProvider.AuthenticationStateChanged -= |
|||
AuthenticationStateProviderOnAuthenticationStateChanged; |
|||
} |
|||
|
|||
private async Task NavigateToAsync(string uri, string target = null) |
|||
{ |
|||
if (target == "_blank") |
|||
{ |
|||
await JsRuntime.InvokeVoidAsync("open", uri, target); |
|||
} |
|||
else |
|||
{ |
|||
Navigation.NavigateTo(uri); |
|||
} |
|||
} |
|||
|
|||
private async Task BeginSignOut() |
|||
{ |
|||
if (SignOutManager != null) |
|||
{ |
|||
await SignOutManager.SetSignOutState(); |
|||
await NavigateToAsync("authentication/logout"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
@using Microsoft.AspNetCore.Components.Web |
|||
@using AntDesign |
|||
@ -1,2 +1,9 @@ |
|||
@using Microsoft.AspNetCore.Components.Web |
|||
@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.JSInterop |
|||
@using AntDesign |
|||
@using Lsw.Abp.AntDesignUI |
|||
@using Lsw.Abp.AntDesignUI.Components |
|||
|
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Ui.Branding; |
|||
|
|||
namespace AntDesignUIApp; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
public class AntDesignAppBrandBrandingProvider : DefaultBrandingProvider |
|||
{ |
|||
public override string AppName => "AntDesignApp"; |
|||
|
|||
public override string LogoUrl => "logo.svg"; |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace AntDesignUIApp; |
|||
|
|||
public class AntDesignUiAppMenuContributor : IMenuContributor |
|||
{ |
|||
public Task ConfigureMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
if (context.Menu.Name == StandardMenus.Main) |
|||
{ |
|||
context.Menu.Items.Insert( |
|||
0, |
|||
new ApplicationMenuItem( |
|||
"Home", |
|||
"Home", |
|||
"/", |
|||
icon: "home" |
|||
) |
|||
); |
|||
|
|||
var admin = new ApplicationMenuItem("Admin", "Admin"); |
|||
|
|||
admin.AddItem(new ApplicationMenuItem("Users", |
|||
"Users", |
|||
"/Users")); |
|||
|
|||
admin.AddItem(new ApplicationMenuItem("Roles", |
|||
"Roles", |
|||
"/Roles")); |
|||
|
|||
context.Menu.AddItem(admin); |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -1,5 +1,6 @@ |
|||
@page "/" |
|||
|
|||
<AbpPageHeader Title="Index" BreadcrumbItems="@BreadcrumbItems"/> |
|||
|
|||
<p>hello world</p> |
|||
<AbpPageHeader Title="Index" BreadcrumbItems="@BreadcrumbItems" Toolbar="@Toolbar"/> |
|||
<div class="page-content"> |
|||
<p>hello world</p> |
|||
</div> |
|||
|
|||
@ -0,0 +1,6 @@ |
|||
@page "/roles" |
|||
|
|||
<AbpPageHeader Title="Roles" BreadcrumbItems="@BreadcrumbItems"/> |
|||
<div class="page-content"> |
|||
<p>Role page</p> |
|||
</div> |
|||
@ -0,0 +1,18 @@ |
|||
using Lsw.Abp.AntDesignUI; |
|||
using Microsoft.AspNetCore.Components; |
|||
|
|||
namespace AntDesignUIApp.Pages; |
|||
|
|||
public partial class Roles : ComponentBase |
|||
{ |
|||
public List<BreadcrumbItem> BreadcrumbItems { get; set; } = new(); |
|||
|
|||
protected override void OnInitialized() |
|||
{ |
|||
BreadcrumbItems = new List<BreadcrumbItem>() |
|||
{ |
|||
new("Admin"), |
|||
new("Roles") |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
@page "/users" |
|||
|
|||
<AbpPageHeader Title="Users" BreadcrumbItems="@BreadcrumbItems"/> |
|||
<div class="page-content"> |
|||
<p>Users page</p> |
|||
</div> |
|||
@ -0,0 +1,18 @@ |
|||
using Lsw.Abp.AntDesignUI; |
|||
using Microsoft.AspNetCore.Components; |
|||
|
|||
namespace AntDesignUIApp.Pages; |
|||
|
|||
public partial class Users : ComponentBase |
|||
{ |
|||
public List<BreadcrumbItem> BreadcrumbItems { get; set; } = new(); |
|||
|
|||
protected override void OnInitialized() |
|||
{ |
|||
BreadcrumbItems = new List<BreadcrumbItem>() |
|||
{ |
|||
new("Admin"), |
|||
new("Users") |
|||
}; |
|||
} |
|||
} |
|||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 4.6 KiB |
Loading…
Reference in new issue