Browse Source

Implemented initial basic theme for the Blazor UI

pull/5399/head
Halil İbrahim Kalkan 5 years ago
parent
commit
f0b11b786c
  1. 7
      framework/Volo.Abp.sln
  2. 6
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/AbpAspNetCoreComponentsWebAssemblyBasicTheme.cs
  3. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor
  4. 24
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor
  5. 19
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor
  6. 37
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor
  7. 38
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor
  8. 27
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs
  9. 52
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenuItem.razor
  10. 4
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj
  11. 105
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.css
  12. 16
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.js
  13. 17
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpAspNetCoreComponentsWebAssemblyThemingModule.cs
  14. 3
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xml
  15. 30
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xsd
  16. 17
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj
  17. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj
  18. 15
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
  19. 8
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpBlazorClientHttpMessageHandler.cs
  20. 31
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs
  21. 6
      modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorAutoMapperProfile.cs
  22. 8
      modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs
  23. 40
      modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs
  24. 10
      modules/identity/src/Volo.Abp.Identity.Blazor/IdentityMenuNames.cs
  25. 1
      modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.csproj
  26. 6
      modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/AbpPermissionManagementBlazorModule.cs
  27. 2
      modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.csproj
  28. 3
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/App.razor
  29. 24
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs
  30. 15
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameMenuContributor.cs
  31. 185
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/css/app.css
  32. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/index.html
  33. 18
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/main.css

7
framework/Volo.Abp.sln

@ -341,6 +341,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlazoriseUI", "src
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme", "src\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj", "{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Components.WebAssembly.Theming", "src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj", "{29CA7471-4E3E-4E75-8B33-001DDF682F01}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1015,6 +1017,10 @@ Global
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Release|Any CPU.Build.0 = Release|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29CA7471-4E3E-4E75-8B33-001DDF682F01}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1187,6 +1193,7 @@ Global
{E1A62D10-F2FB-4040-BD60-11A3934058DF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{29CA7471-4E3E-4E75-8B33-001DDF682F01} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

6
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/AbpAspNetCoreComponentsWebAssemblyBasicTheme.cs

@ -1,12 +1,10 @@
using Volo.Abp.BlazoriseUI;
using Volo.Abp.Http.Client.IdentityModel.WebAssembly;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme
{
[DependsOn(
typeof(AbpBlazoriseUIModule),
typeof(AbpHttpClientIdentityModelWebAssemblyModule)
typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule)
)]
public class AbpAspNetCoreComponentsWebAssemblyBasicThemeModule : AbpModule
{

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/Pages/Authentication.razor → framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor

@ -1,4 +1,4 @@
@page "/authentication/{action}"
@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action" />

24
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor

@ -1,28 +1,24 @@
@using Volo.Abp.Localization
@using System.Globalization
@using System.Collections.Immutable
@inject ILanguageProvider LanguageProvider
@inject IJSRuntime JsRuntime
@if (_languages != null && _languages.Count > 1)
@if (_otherLanguages != null && _otherLanguages.Any())
{
<Dropdown>
<DropdownToggle Color="Color.None">
@_currentLanguage.DisplayName
</DropdownToggle>
<DropdownMenu>
@foreach (var language in _languages)
@foreach (var language in _otherLanguages)
{
if (language == _currentLanguage)
{
continue;
}
<DropdownItem Clicked="() => ChangeLanguageAsync(language)">@language.DisplayName</DropdownItem>
}
</DropdownMenu>
</Dropdown>
}
@code {
private IReadOnlyList<LanguageInfo> _languages;
private IReadOnlyList<LanguageInfo> _otherLanguages;
private LanguageInfo _currentLanguage;
protected override async Task OnInitializedAsync()
@ -32,27 +28,29 @@
"Abp.SelectedLanguage"
);
_languages = await LanguageProvider.GetLanguagesAsync();
_otherLanguages = await LanguageProvider.GetLanguagesAsync();
if (!_languages.Any())
if (!_otherLanguages.Any())
{
return;
}
if (!selectedLanguageName.IsNullOrWhiteSpace())
{
_currentLanguage = _languages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName);
_currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName);
}
if (_currentLanguage == null)
{
_currentLanguage = _languages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name);
_currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name);
}
if (_currentLanguage == null)
{
_currentLanguage = _languages.FirstOrDefault();
_currentLanguage = _otherLanguages.FirstOrDefault();
}
_otherLanguages = _otherLanguages.Where(l => l != _currentLanguage).ToImmutableList();
}
private async Task ChangeLanguageAsync(LanguageInfo language)

19
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor

@ -1,20 +1,25 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Volo.Abp.Users
@inject ICurrentUser CurrentUser
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
<AuthorizeView>
<Authorized>
Hello, @context.User.Identity.Name!
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
<Dropdown>
<DropdownToggle Color="Color.None">
@CurrentUser.UserName
</DropdownToggle>
<DropdownMenu>
<DropdownItem Clicked="BeginSignOut">Logout</DropdownItem>
</DropdownMenu>
</Dropdown>
</Authorized>
<NotAuthorized>
<a href="authentication/login">Log in</a>
<a class="nav-link" href="authentication/login">Log in</a>
</NotAuthorized>
</AuthorizeView>
@code{
private async Task BeginSignOut(MouseEventArgs args)
private async Task BeginSignOut()
{
await SignOutManager.SetSignOutState();
Navigation.NavigateTo("authentication/logout");

37
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor

@ -1,18 +1,29 @@
@inherits LayoutComponentBase
@using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4 auth">
<LanguageSwitch/>
<LoginDisplay/>
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<div class="content px-4">
@Body
<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="~/">My Application (TODO)</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>

38
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor

@ -1,37 +1,7 @@
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">MyProjectName</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<i class="fas fa-home" aria-hidden="true"></i> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="identity/users">
<i class="fas fa-users" aria-hidden="true"></i> Users
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="identity/roles">
<i class="fas fa-user-tag" aria-hidden="true"></i> Roles
</NavLink>
</li>
</ul>
</div>
@code {
private bool collapseNavMenu = true;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
@if (Menu != null)
{
foreach (var menuItem in Menu.Items)
{
collapseNavMenu = !collapseNavMenu;
<NavMenuItem MenuItem="@menuItem" />
}
}

27
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs

@ -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;
}
}
}

52
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenuItem.razor

@ -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; }
}

4
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj

@ -6,11 +6,11 @@
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme</PackageId>
</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.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" />
</ItemGroup>
</Project>

105
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.css

@ -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;
}

16
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.js

@ -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;
});
});

17
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpAspNetCoreComponentsWebAssemblyThemingModule.cs

@ -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
{
}
}

3
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

30
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xsd

@ -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>

17
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj

@ -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>

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj

@ -18,7 +18,7 @@
<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" />
</ItemGroup>

15
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs

@ -1,4 +1,6 @@
using Volo.Abp.AspNetCore.Mvc.Client;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Client;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.UI;
@ -10,6 +12,15 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly
)]
public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientBuildActions.Add((_, builder) =>
{
builder.AddHttpMessageHandler<AbpBlazorClientHttpMessageHandler>();
});
});
}
}
}

8
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/BlazorClientHttpMessageHandler.cs → framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpBlazorClientHttpMessageHandler.cs

@ -6,13 +6,13 @@ using System.Threading.Tasks;
using Microsoft.JSInterop;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName.Blazor
namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
public class BlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency
public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency
{
private readonly IJSRuntime _jsRuntime;
public BlazorClientHttpMessageHandler(IJSRuntime jsRuntime)
public AbpBlazorClientHttpMessageHandler(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
@ -39,4 +39,4 @@ namespace MyCompanyName.MyProjectName.Blazor
}
}
}
}
}

31
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using Volo.Abp.AspNetCore.Mvc.Client;
using Volo.Abp.DependencyInjection;
@ -10,23 +11,37 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
protected ICachedApplicationConfigurationClient ConfigurationClient { get; }
public WebAssemblyCurrentPrincipalAccessor(ICachedApplicationConfigurationClient configurationClient)
public WebAssemblyCurrentPrincipalAccessor(
ICachedApplicationConfigurationClient configurationClient)
{
ConfigurationClient = configurationClient;
}
protected override ClaimsPrincipal GetClaimsPrincipal()
{
//TODO: Should be optimized! Or should be replaced?
var configuration = ConfigurationClient.Get();
var claims = new List<Claim>();
claims.Add(new Claim(AbpClaimTypes.UserName,configuration.CurrentUser.UserName));
claims.Add(new Claim(AbpClaimTypes.Email,configuration.CurrentUser.Email));
claims.Add(new Claim(AbpClaimTypes.UserId,configuration.CurrentUser.Id.ToString()));
claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentUser.TenantId.ToString()));
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()));
}
foreach (var role in configuration.CurrentUser.Roles)
{

6
modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorAutoMapperProfile.cs

@ -1,4 +1,5 @@
using AutoMapper;
using Volo.Abp.AutoMapper;
namespace Volo.Abp.Identity.Blazor
{
@ -8,6 +9,11 @@ namespace Volo.Abp.Identity.Blazor
{
CreateMap<IdentityRoleDto, IdentityRoleUpdateDto>()
.MapExtraProperties();
CreateMap<IdentityUserDto, IdentityUserUpdateDto>()
.Ignore(x => x.Password)
.Ignore(x => x.RoleNames)
.MapExtraProperties();
}
}
}

8
modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs

@ -1,14 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.BlazoriseUI;
using Volo.Abp.PermissionManagement.Blazor;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Identity.Blazor
{
[DependsOn(
typeof(AbpIdentityHttpApiClientModule),
typeof(AbpBlazoriseUIModule),
typeof(AbpAutoMapperModule),
typeof(AbpPermissionManagementBlazorModule)
)]
@ -22,6 +21,11 @@ namespace Volo.Abp.Identity.Blazor
{
options.AddProfile<AbpIdentityBlazorAutoMapperProfile>(validate: true);
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new AbpIdentityWebMainMenuContributor());
});
}
}
}

40
modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs

@ -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"));
}
}
}
}
}

10
modules/identity/src/Volo.Abp.Identity.Blazor/IdentityMenuNames.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.Identity.Blazor
{
public class IdentityMenuNames
{
public const string GroupName = "AbpIdentity";
public const string Roles = GroupName + ".Roles";
public const string Users = GroupName + ".Users";
}
}

1
modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.csproj

@ -9,7 +9,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\..\..\permission-management\src\Volo.Abp.PermissionManagement.Blazor\Volo.Abp.PermissionManagement.Blazor.csproj" />
</ItemGroup>

6
modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/AbpPermissionManagementBlazorModule.cs

@ -1,11 +1,11 @@
using Volo.Abp.AutoMapper;
using Volo.Abp.BlazoriseUI;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace Volo.Abp.PermissionManagement.Blazor
{
[DependsOn(
typeof(AbpBlazoriseUIModule),
typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule),
typeof(AbpAutoMapperModule),
typeof(AbpPermissionManagementHttpApiClientModule)
)]

2
modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.csproj

@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj" />
<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>

3
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/App.razor

@ -1,8 +1,9 @@
@using Volo.Abp.Identity.Blazor
@using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme
@using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly"
AdditionalAssemblies="new []{ typeof(AbpIdentityBlazorModule).Assembly }">
AdditionalAssemblies="new []{ typeof(AbpIdentityBlazorModule).Assembly, typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeModule).Assembly }">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>

24
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs

@ -8,30 +8,21 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Autofac;
using Volo.Abp.Http.Client;
using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
using Volo.Abp.Identity.Blazor;
namespace MyCompanyName.MyProjectName.Blazor
{
[DependsOn(
typeof(AbpAutofacModule),
typeof(MyProjectNameHttpApiClientModule),
typeof(AbpIdentityBlazorModule),
typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeModule)
)]
public class MyProjectNameBlazorModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientBuildActions.Add((_, builder) =>
{
builder.AddHttpMessageHandler<BlazorClientHttpMessageHandler>();
});
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var environment = context.Services.GetSingletonInstance<IWebAssemblyHostEnvironment>();
@ -41,6 +32,15 @@ namespace MyCompanyName.MyProjectName.Blazor
ConfigureHttpClient(context, environment);
ConfigureBlazorise(context);
ConfigureUI(builder);
ConfigureMenu(context);
}
private void ConfigureMenu(ServiceConfigurationContext context)
{
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new MyProjectNameMenuContributor());
});
}
private void ConfigureBlazorise(ServiceConfigurationContext context)

15
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameMenuContributor.cs

@ -0,0 +1,15 @@
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
namespace MyCompanyName.MyProjectName.Blazor
{
public class MyProjectNameMenuContributor : IMenuContributor
{
public Task ConfigureMenuAsync(MenuConfigurationContext context)
{
context.Menu.AddItem(new ApplicationMenuItem("Test", "Test", "/test"));
return Task.CompletedTask;
}
}
}

185
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/css/app.css

@ -1,185 +0,0 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a, .btn-link {
color: #0366d6;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
app {
position: relative;
display: flex;
flex-direction: column;
}
.top-row {
height: 3.5rem;
display: flex;
align-items: center;
}
.main {
flex: 1;
}
.main .top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
}
.main .top-row > a, .main .top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.main .top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.sidebar .top-row {
background-color: rgba(0,0,0,0.4);
}
.sidebar .navbar-brand {
font-size: 1.1rem;
}
.sidebar .oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.sidebar .nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.sidebar .nav-item:first-of-type {
padding-top: 1rem;
}
.sidebar .nav-item:last-of-type {
padding-bottom: 1rem;
}
.sidebar .nav-item a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.sidebar .nav-item a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.sidebar .nav-item a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.content {
padding-top: 1.1rem;
}
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid red;
}
.validation-message {
color: red;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
.nav .nav-item .nav-link i {
margin: 5px;
}
@media (max-width: 767.98px) {
.main .top-row:not(.auth) {
display: none;
}
.main .top-row.auth {
justify-content: space-between;
}
.main .top-row a, .main .top-row .btn-link {
margin-left: 0;
}
}
@media (min-width: 768px) {
app {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.main .top-row {
position: sticky;
top: 0;
}
.main > div {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
.navbar-toggler {
display: none;
}
.sidebar .collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}

5
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/index.html

@ -12,8 +12,8 @@
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
<link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/theme.css" rel="stylesheet" />
<link href="main.css" rel="stylesheet" />
</head>
<body>
@ -33,6 +33,7 @@
<script src="_content/Blazorise/blazorise.js"></script>
<script src="_content/Blazorise.Bootstrap/blazorise.bootstrap.js"></script>
<script src="_content/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/theme.js"></script>
</body>
</html>

18
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/main.css

@ -0,0 +1,18 @@
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
Loading…
Cancel
Save