Browse Source

Merge branch 'dev' into feature/table-sort-pipe

pull/1866/head
Yasin Aydın 7 years ago
committed by GitHub
parent
commit
9f002787f0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 240
      docs/en/Authorization.md
  2. BIN
      docs/en/images/authorization-new-permission-ui-hierarcy.png
  3. BIN
      docs/en/images/authorization-new-permission-ui-localized.png
  4. BIN
      docs/en/images/authorization-new-permission-ui.png
  5. 9
      framework/Volo.Abp.sln
  6. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Pages/Error/Index.cshtml.cs
  7. 1
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
  8. 1
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
  9. 2
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
  10. 3
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs
  11. 2
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
  12. 3
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs
  13. 2
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/ExceptionHttpStatusCodeOptions.cs
  14. 2
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/IExceptionToErrorInfoConverter.cs
  15. 2
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/IHttpExceptionStatusCodeFinder.cs
  16. 7
      framework/src/Volo.Abp.Authorization/Microsoft/Extensions/DependencyInjection/AbpAuthorizationServiceCollectionExtensions.cs
  17. 20
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj
  18. 12
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/AbpDddApplicationContractsModule.cs
  19. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityDto.cs
  20. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs
  21. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityDto.cs
  22. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs
  23. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs
  24. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityDto.cs
  25. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs
  26. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IEntityDto.cs
  27. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IHasTotalCount.cs
  28. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ILimitedResultRequest.cs
  29. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IListResult.cs
  30. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IPagedAndSortedResultRequest.cs
  31. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IPagedResult.cs
  32. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IPagedResultRequest.cs
  33. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ISortedResultRequest.cs
  34. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs
  35. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ListResultDto.cs
  36. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs
  37. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedResultDto.cs
  38. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedResultRequestDto.cs
  39. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IApplicationService.cs
  40. 0
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs
  41. 4
      framework/src/Volo.Abp.Ddd.Application/Volo.Abp.Ddd.Application.csproj
  42. 2
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs
  43. 10
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  44. 8
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpClientTestModule.cs
  45. 11
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
  46. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs
  47. 7
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
  48. 2
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  49. 2
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs
  50. 1
      npm/ng-packs/.gitignore
  51. 25
      npm/ng-packs/angular.json
  52. 18
      npm/ng-packs/apps/dev-app/src/app/app.component.ts
  53. 14
      npm/ng-packs/packages/core/src/lib/models/application-configuration.ts
  54. 86
      npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts
  55. 35
      npm/ng-packs/packages/core/src/lib/states/config.state.ts
  56. 2
      npm/ng-packs/packages/theme-basic/src/lib/components/layout/layout.component.html
  57. 9
      npm/ng-packs/packages/theme-shared/src/lib/animations/slide.animations.ts
  58. 9
      npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts
  59. 2
      npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts
  60. 2
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  61. 1
      nupkg/common.ps1
  62. 52
      templates/app/angular/angular.json
  63. 18
      templates/app/angular/src/app/app.component.ts

240
docs/en/Authorization.md

@ -1,3 +1,239 @@
## Authorization
# Authorization
TODO
Authorization is used to check if a user is allowed to perform some specific operation in the application.
ABP extends [ASP.NET Core's Authorization system](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction) by adding **permissions** as auto [policies](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies) and allowing authorization system to be usable in the **[application services](Application-Services.md)** too.
So, all the ASP.NET Core authorization features and the documentation are valid in an ABP based application. This document focuses on the features added on top of them.
## Authorize Attribute
ASP.NET Core defines the [**Authorize**](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/simple) attribute that can be used for an action, a controller or a page. ABP allows you to use the same attribute for an [application service](Application-Services.md) too.
Example:
````csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Services;
namespace Acme.BookStore
{
[Authorize]
public class AuthorAppService : ApplicationService, IAuthorAppService
{
public Task<List<AuthorDto>> GetListAsync()
{
...
}
[AllowAnonymous]
public Task<AuthorDto> GetAsync(Guid id)
{
...
}
[Authorize("BookStore_Author_Create")]
public Task CreateAsync(CreateAuthorDto input)
{
...
}
}
}
````
* `Authorize` attribute forces user to login to the application in order to use the `AuthorAppService` methods. So, `GetListAsync` method is only available to authenticated users.
* `AllowAnonymous` suppress the authentication. So, `GetAsync` method is available to everyone including unauthorized users.
* `[Authorize("BookStore_Author_Create")]` defines a policy (see [policy based authorization](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies)) that is checked to authorize the current user.
"BookStore_Author_Create" is an arbitrary policy name. If you declare an attribute like that, ASP.NET Core authorization system expects a policy defined before.
You can of course implement your policies as stated in the ASP.NET Core documentation. But for simple true/false cases (that means a policy was granted a user or not), ABP defines the permission system explained in the next section.
## Permission System
A permission is a simple policy where it is granted or prohibited for a particular user, role or client.
### Defining Permissions
To define permissions, create a class inheriting from the `PermissionDefinitionProvider` as shown below:
````csharp
using Volo.Abp.Authorization.Permissions;
namespace Acme.BookStore.Permissions
{
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var myGroup = context.AddGroup("BookStore");
myGroup.AddPermission("BookStore_Author_Create");
}
}
}
````
> ABP will automatically discover this class. No additional configuration required.
In the `Define` method, you first need to add a **permission group** (or get an existing group) then add **permissions** to this group.
When you define a permission, it becomes usable in the ASP.NET Core authorization system as a **policy** name. It also becomes visible in the UI. See permissions dialog for a role:
![authorization-new-permission-ui](images/authorization-new-permission-ui.png)
* The "BookStore" group is shown as a new tab on the left side.
* "BookStore_Author_Create" on the right side is the permission name. You can grant or prohibit it for the role.
When you save the dialog, it is saved to the database and used in the authorization system.
> The screen above is available when you have installed the identity module, which is basically used for user and role management. Startup templates come with the identity module pre-installed.
#### Localizing the Permission Name
"BookStore_Author_Create" is not a good permission name on the UI. Fortunately, `AddPermission` and `AddGroup` methods can take `LocalizableString` as second parameters:
````csharp
var myGroup = context.AddGroup(
"BookStore",
LocalizableString.Create<BookStoreResource>("BookStore")
);
myGroup.AddPermission(
"BookStore_Author_Create",
LocalizableString.Create<BookStoreResource>("Permission:BookStore_Author_Create")
);
````
Then you can define texts for "BookStore" and "Permission:BookStore_Author_Create" keys in the localization file:
````json
"BookStore": "Book Store",
"Permission:BookStore_Author_Create": "Creating a new author"
````
> See the [localization document](Localization.md) for more details on the localization system.
The localized UI will be like that:
![authorization-new-permission-ui-localized](images/authorization-new-permission-ui-localized.png)
#### Multi-Tenancy
ABP supports [multi-tenancy](Multi-Tenancy.md) as a first class citizen. You can define multi-tenancy side option while defining a new permission. It gets one of the three values defined below:
* **Host**: The permission is available only for the host side.
* **Tenant**: The permission is available only for the tenant side.
* **Both** (default): The permission is available both for tenant and host sides.
> If your application is not multi-tenant, you can ignore this option.
To set the multi-tenancy side option, pass to the third parameter of the `AddPermission` method:
````csharp
myGroup.AddPermission(
"BookStore_Author_Create",
LocalizableString.Create<BookStoreResource>("Permission:BookStore_Author_Create"),
multiTenancySide: MultiTenancySides.Tenant //set multi-tenancy side!
);
````
#### Child Permissions
A permission may have child permissions. It is especially useful when you want to create a hierarchical permission tree where a permission may have additional sub permissions which are available only if the parent permission has been granted.
Example definition:
````csharp
var authorManagement = myGroup.AddPermission("Author_Management");
authorManagement.AddChild("Author_Management_Create_Books");
authorManagement.AddChild("Author_Management_Edit_Books");
authorManagement.AddChild("Author_Management_Delete_Books");
````
The result on the UI is shown below (you probably want to localize permissions for your application):
![authorization-new-permission-ui-hierarcy](images/authorization-new-permission-ui-hierarcy.png)
For the example code, it is assumed that a role/user with "Author_Management" permission granted may have additional permissions. Then a typical application service that checks permissions can be defined as shown below:
````csharp
[Authorize("Author_Management")]
public class AuthorAppService : ApplicationService, IAuthorAppService
{
public Task<List<AuthorDto>> GetListAsync()
{
...
}
public Task<AuthorDto> GetAsync(Guid id)
{
...
}
[Authorize("Author_Management_Create_Books")]
public Task CreateAsync(CreateAuthorDto input)
{
...
}
[Authorize("Author_Management_Edit_Books")]
public Task UpdateAsync(CreateAuthorDto input)
{
...
}
[Authorize("Author_Management_Delete_Books")]
public Task DeleteAsync(CreateAuthorDto input)
{
...
}
}
````
* `GetListAsync` and `GetAsync` will be available to users if they have `Author_Management` permission granted.
* Other methods require additional permissions.
## IAuthorizationService
ASP.NET Core provides the `IAuthorizationService` that can be used to check for authorization. Once you inject, you can use it in your code to conditionally control the authorization.
Example:
````csharp
public async Task CreateAsync(CreateAuthorDto input)
{
var result = await AuthorizationService
.AuthorizeAsync("Author_Management_Create_Books");
if (result.Succeeded == false)
{
//throw exception
throw new AbpAuthorizationException("...");
}
//continue to the normal flow...
}
````
> `AuthorizationService` is available as a property when you derive from ABP's `ApplicationService` base class. Since it is widely used in application services, `ApplicationService` pre-injects it for you. Otherwise, you can directly [inject](Dependency-Injection.md) it into your class.
Since this is a typical code block, ABP provides extension methods to simplify it.
Example:
````csharp
public async Task CreateAsync(CreateAuthorDto input)
{
await AuthorizationService.CheckAsync("Author_Management_Create_Books");
//continue to the normal flow...
}
````
`CheckAsync` extension method throws `AbpAuthorizationException` if current user/client has not granted for the given permission. There is also `IsGrantedAsync` extension method that returns `true` or `false`.
> Tip: Prefer to use the `Authorize` attribute wherever possible, since it is declarative & simple. Use `IAuthorizationService` if you need to conditionally check a permission and run a business code based on the permission check.

BIN
docs/en/images/authorization-new-permission-ui-hierarcy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
docs/en/images/authorization-new-permission-ui-localized.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/en/images/authorization-new-permission-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

9
framework/Volo.Abp.sln

@ -248,7 +248,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MailKit", "src\Vol
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MailKit.Tests", "test\Volo.Abp.MailKit.Tests\Volo.Abp.MailKit.Tests.csproj", "{70DD6E17-B98B-4B00-8F38-C489E291BB53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.ObjectMapping.Tests", "test\Volo.Abp.ObjectMapping.Tests\Volo.Abp.ObjectMapping.Tests.csproj", "{667F5544-C1EB-447C-96FD-9B757F04DE2B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectMapping.Tests", "test\Volo.Abp.ObjectMapping.Tests\Volo.Abp.ObjectMapping.Tests.csproj", "{667F5544-C1EB-447C-96FD-9B757F04DE2B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ddd.Application.Contracts", "src\Volo.Abp.Ddd.Application.Contracts\Volo.Abp.Ddd.Application.Contracts.csproj", "{73559227-EBF0-475F-835B-1FF0CD9132AA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -744,6 +746,10 @@ Global
{667F5544-C1EB-447C-96FD-9B757F04DE2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{667F5544-C1EB-447C-96FD-9B757F04DE2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{667F5544-C1EB-447C-96FD-9B757F04DE2B}.Release|Any CPU.Build.0 = Release|Any CPU
{73559227-EBF0-475F-835B-1FF0CD9132AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73559227-EBF0-475F-835B-1FF0CD9132AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73559227-EBF0-475F-835B-1FF0CD9132AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73559227-EBF0-475F-835B-1FF0CD9132AA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -871,6 +877,7 @@ Global
{0CAED4CC-1CFD-4092-A326-AFE4DB3A9AB4} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{70DD6E17-B98B-4B00-8F38-C489E291BB53} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{667F5544-C1EB-447C-96FD-9B757F04DE2B} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{73559227-EBF0-475F-835B-1FF0CD9132AA} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Pages/Error/Index.cshtml.cs

@ -2,7 +2,7 @@ using System;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.Http;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Error

1
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs

@ -111,6 +111,7 @@ namespace Volo.Abp.AspNetCore.Mvc
var application = context.Services.GetSingletonInstance<IAbpApplication>();
partManager.FeatureProviders.Add(new AbpConventionalControllerFeatureProvider(application));
partManager.ApplicationParts.Add(new AssemblyPart(typeof(AbpAspNetCoreMvcModule).Assembly));
Configure<MvcOptions>(mvcOptions =>
{

1
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.Json;

2
framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs

@ -4,7 +4,7 @@ using Microsoft.AspNetCore.RequestLocalization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Tracing;
using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.DependencyInjection;

3
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs

@ -4,12 +4,13 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.Json;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
namespace Volo.Abp.AspNetCore.ExceptionHandling
{
public class AbpExceptionHandlingMiddleware : IMiddleware, ITransientDependency
{

2
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs

@ -15,7 +15,7 @@ using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Validation;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
namespace Volo.Abp.AspNetCore.ExceptionHandling
{
public class DefaultExceptionToErrorInfoConverter : IExceptionToErrorInfoConverter, ITransientDependency
{

3
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
@ -9,7 +8,7 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.Validation;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
namespace Volo.Abp.AspNetCore.ExceptionHandling
{
public class DefaultHttpExceptionStatusCodeFinder : IHttpExceptionStatusCodeFinder, ITransientDependency
{

2
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/ExceptionHttpStatusCodeOptions.cs

@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Net;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
namespace Volo.Abp.AspNetCore.ExceptionHandling
{
public class ExceptionHttpStatusCodeOptions
{

2
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/IExceptionToErrorInfoConverter.cs

@ -1,7 +1,7 @@
using System;
using Volo.Abp.Http;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
namespace Volo.Abp.AspNetCore.ExceptionHandling
{
/// <summary>
/// This interface can be implemented to convert an <see cref="Exception"/> object to an <see cref="RemoteServiceErrorInfo"/> object.

2
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/IHttpExceptionStatusCodeFinder.cs

@ -2,7 +2,7 @@
using System.Net;
using Microsoft.AspNetCore.Http;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
namespace Volo.Abp.AspNetCore.ExceptionHandling
{
public interface IHttpExceptionStatusCodeFinder
{

7
framework/src/Volo.Abp.Authorization/Microsoft/Extensions/DependencyInjection/AbpAuthorizationServiceCollectionExtensions.cs

@ -8,13 +8,6 @@ namespace Microsoft.Extensions.DependencyInjection
{
public static class AbpAuthorizationServiceCollectionExtensions
{
//TODO: Remove this and use AddAlwaysAllowAuthorization
[Obsolete("Use AddAlwaysAllowAuthorization instead")]
public static IServiceCollection AddAlwaysAllowPermissionChecker(this IServiceCollection services)
{
return services.Replace(ServiceDescriptor.Singleton<IPermissionChecker, AlwaysAllowPermissionChecker>());
}
public static IServiceCollection AddAlwaysAllowAuthorization(this IServiceCollection services)
{
services.Replace(ServiceDescriptor.Singleton<IAuthorizationService, AlwaysAllowAuthorizationService>());

20
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Volo.Abp.Ddd.Application.Contracts</AssemblyName>
<PackageId>Volo.Abp.Ddd.Application.Contracts</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.Auditing\Volo.Abp.Auditing.csproj" />
</ItemGroup>
</Project>

12
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/AbpDddApplicationContractsModule.cs

@ -0,0 +1,12 @@
using Volo.Abp.Auditing;
using Volo.Abp.Modularity;
namespace Volo.Abp.Application
{
[DependsOn(
typeof(AbpAuditingModule)
)]
public class AbpDddApplicationContractsModule : AbpModule
{
}
}

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/AuditedEntityDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/AuditedEntityWithUserDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/CreationAuditedEntityDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/CreationAuditedEntityWithUserDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/EntityDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/EntityDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/FullAuditedEntityDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/FullAuditedEntityWithUserDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/IEntityDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IEntityDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/IHasTotalCount.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IHasTotalCount.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/ILimitedResultRequest.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ILimitedResultRequest.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/IListResult.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IListResult.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/IPagedAndSortedResultRequest.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IPagedAndSortedResultRequest.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/IPagedResult.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IPagedResult.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/IPagedResultRequest.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/IPagedResultRequest.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/ISortedResultRequest.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ISortedResultRequest.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/ListResultDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ListResultDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedAndSortedResultRequestDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/PagedResultDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedResultDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Dtos/PagedResultRequestDto.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/PagedResultRequestDto.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IApplicationService.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IApplicationService.cs

0
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs → framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs

4
framework/src/Volo.Abp.Ddd.Application/Volo.Abp.Ddd.Application.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -15,7 +15,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" />
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Ddd.Application.Contracts\Volo.Abp.Ddd.Application.Contracts.csproj" />
<ProjectReference Include="..\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" />
<ProjectReference Include="..\Volo.Abp.Features\Volo.Abp.Features.csproj" />
<ProjectReference Include="..\Volo.Abp.Http.Abstractions\Volo.Abp.Http.Abstractions.csproj" />

2
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs

@ -16,6 +16,7 @@ namespace Volo.Abp.Application
{
[DependsOn(
typeof(AbpDddDomainModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpSecurityModule),
typeof(AbpObjectMappingModule),
typeof(AbpValidationModule),
@ -30,6 +31,7 @@ namespace Volo.Abp.Application
{
Configure<ApiDescriptionModelOptions>(options =>
{
//TODO: Should we move related items to their own projects?
options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService));
options.IgnoredInterfaces.AddIfNotContains(typeof(IApplicationService));
options.IgnoredInterfaces.AddIfNotContains(typeof(IUnitOfWorkEnabled));

10
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -30,9 +30,9 @@ namespace Volo.Abp.EntityFrameworkCore
{
protected virtual Guid? CurrentTenantId => CurrentTenant?.Id;
protected virtual bool IsMultiTenantFilterEnabled => DataFilter.IsEnabled<IMultiTenant>();
protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false;
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter.IsEnabled<ISoftDelete>();
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
public ICurrentTenant CurrentTenant { get; set; }
@ -316,17 +316,17 @@ namespace Volo.Abp.EntityFrameworkCore
protected virtual void SetCreationAuditProperties(EntityEntry entry)
{
AuditPropertySetter.SetCreationProperties(entry.Entity);
AuditPropertySetter?.SetCreationProperties(entry.Entity);
}
protected virtual void SetModificationAuditProperties(EntityEntry entry)
{
AuditPropertySetter.SetModificationProperties(entry.Entity);
AuditPropertySetter?.SetModificationProperties(entry.Entity);
}
protected virtual void SetDeletionAuditProperties(EntityEntry entry)
{
AuditPropertySetter.SetDeletionProperties(entry.Entity);
AuditPropertySetter?.SetDeletionProperties(entry.Entity);
}
protected virtual void ConfigureBaseProperties<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType)

8
framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpClientTestModule.cs

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.DynamicProxying;
@ -23,11 +22,6 @@ namespace Volo.Abp.Http
{
options.RemoteServices.Default = new RemoteServiceConfiguration("/");
});
//This is needed after ASP.NET Core 3.0 upgrade.
context.Services.AddMvc()
.PartManager.ApplicationParts
.Add(new AssemblyPart(typeof(AbpAspNetCoreMvcModule).Assembly));
}
}
}

11
framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs

@ -5,7 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Http.Client;
using Volo.Abp.TestApp.Application;
using Volo.Abp.TestApp.Application.Dto;
using Volo.Abp.TestApp.Domain;
@ -103,6 +103,15 @@ namespace Volo.Abp.Http.DynamicProxying
personInDb.Age.ShouldBe(person.Age);
}
[Fact]
public async Task GetWithAuthorized()
{
(await Assert.ThrowsAsync<AbpRemoteCallException>(async () =>
{
await _peopleAppService.GetWithAuthorized();
})).Error.Message.ShouldContain("Authorization");
}
[Fact]
public async Task GetWithComplexType()
{

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs

@ -14,6 +14,8 @@ namespace Volo.Abp.TestApp.Application
Task RemovePhone(Guid id, string number);
Task GetWithAuthorized();
Task<GetWithComplexTypeInput> GetWithComplexType(GetWithComplexTypeInput input);
}
}

7
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.Domain.Repositories;
@ -46,6 +47,12 @@ namespace Volo.Abp.TestApp.Application
Repository.Update(person);
}
[Authorize]
public virtual Task GetWithAuthorized()
{
return Task.CompletedTask;
}
public Task<GetWithComplexTypeInput> GetWithComplexType(GetWithComplexTypeInput input)
{
return Task.FromResult(input);

2
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

@ -87,7 +87,7 @@
</label>
</div>
<select asp-items="Model.ProjectSelectItems" class="form-control" onchange="window.location.replace(this.value)"></select>
<select asp-items="Model.ProjectSelectItems" class="form-control" onchange="window.location.pathname = this.value"></select>
</div>
</div>
</div>

2
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

@ -187,7 +187,7 @@ namespace Volo.Docs.Pages.Documents.Project
ProjectSelectItems = projects.Items.Select(p => new SelectListItem
{
Text = p.Name,
Value = p.Id != Project.Id ? "/" + DocumentsUrlPrefix + LanguageCode + "/" + p.ShortName + "/" + DocsAppConsts.Latest : null,
Value = p.Id != Project.Id ? DocumentsUrlPrefix + LanguageCode + "/" + p.ShortName + "/" + DocsAppConsts.Latest : null,
Selected = p.Id == Project.Id
}).ToList();
}

1
npm/ng-packs/.gitignore

@ -3,6 +3,7 @@
# compiled output
/tmp
/out-tsc
/dist/dev-app
# Only exists if Bazel was run
/bazel-out

25
npm/ng-packs/angular.json

@ -434,13 +434,30 @@
"tsConfig": "apps/dev-app/tsconfig.app.json",
"aot": false,
"assets": ["apps/dev-app/src/favicon.ico", "apps/dev-app/src/assets"],
"extractCss": true,
"styles": [
"apps/dev-app/src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/font-awesome/css/font-awesome.min.css",
"node_modules/primeng/resources/themes/nova-light/theme.css",
"node_modules/primeicons/primeicons.css",
"node_modules/primeng/resources/primeng.min.css"
{
"input": "node_modules/font-awesome/css/font-awesome.min.css",
"lazy": true,
"bundleName": "font-awesome.min"
},
{
"input": "node_modules/primeng/resources/themes/nova-light/theme.css",
"lazy": true,
"bundleName": "primeng-nova-light-theme"
},
{
"input": "node_modules/primeicons/primeicons.css",
"lazy": true,
"bundleName": "primeicons"
},
{
"input": "node_modules/primeng/resources/primeng.min.css",
"lazy": true,
"bundleName": "primeng.min"
}
],
"scripts": []
},

18
npm/ng-packs/apps/dev-app/src/app/app.component.ts

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { LazyLoadService } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
@ -7,4 +8,17 @@ import { Component } from '@angular/core';
<router-outlet></router-outlet>
`,
})
export class AppComponent {}
export class AppComponent implements OnInit {
constructor(private lazyLoadService: LazyLoadService) {}
ngOnInit() {
this.lazyLoadService
.load(
['primeng.min.css', 'primeicons.css', 'primeng-nova-light-theme.css', 'font-awesome.min.css'],
'style',
null,
'head',
)
.subscribe();
}
}

14
npm/ng-packs/packages/core/src/lib/models/application-configuration.ts

@ -1,10 +1,12 @@
import { ABP } from './common';
export namespace ApplicationConfiguration {
export interface Response {
localization: Localization;
auth: Auth;
setting: Setting;
setting: Value;
currentUser: CurrentUser;
features: Features;
features: Value;
}
export interface Localization {
@ -32,8 +34,8 @@ export namespace ApplicationConfiguration {
[key: string]: boolean;
}
export interface Setting {
values: { [key: string]: 'Abp.Localization.DefaultLanguage' };
export interface Value {
values: ABP.Dictionary<string>;
}
export interface CurrentUser {
@ -42,8 +44,4 @@ export namespace ApplicationConfiguration {
tenantId: string;
userName: string;
}
export interface Features {
values: Setting;
}
}

86
npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts

@ -9,50 +9,68 @@ export class LazyLoadService {
loadedLibraries: { [url: string]: ReplaySubject<void> } = {};
load(
url: string,
urlOrUrls: string | string[],
type: 'script' | 'style',
content: string = '',
targetQuery: string = 'body',
position: InsertPosition = 'afterend',
): Observable<void> {
if (!url && !content) return;
const key = url ? url.slice(url.lastIndexOf('/') + 1) : uuid();
if (this.loadedLibraries[key]) {
return this.loadedLibraries[key].asObservable();
if (!urlOrUrls && !content) {
return;
} else if (!urlOrUrls && content) {
urlOrUrls = [null];
}
this.loadedLibraries[key] = new ReplaySubject();
let library;
if (type === 'script') {
library = document.createElement('script');
library.type = 'text/javascript';
if (url) {
(library as HTMLScriptElement).src = url;
}
(library as HTMLScriptElement).text = content;
} else if (url) {
library = document.createElement('link');
library.type = 'text/css';
(library as HTMLLinkElement).rel = 'stylesheet';
if (url) {
(library as HTMLLinkElement).href = url;
}
} else {
library = document.createElement('style');
(library as HTMLStyleElement).textContent = content;
if (!Array.isArray(urlOrUrls)) {
urlOrUrls = [urlOrUrls];
}
library.onload = () => {
this.loadedLibraries[key].next();
this.loadedLibraries[key].complete();
};
return new Observable(subscriber => {
(urlOrUrls as string[]).forEach((url, index) => {
const key = url ? url.slice(url.lastIndexOf('/') + 1) : uuid();
if (this.loadedLibraries[key]) {
subscriber.next();
subscriber.complete();
return;
}
this.loadedLibraries[key] = new ReplaySubject();
let library;
if (type === 'script') {
library = document.createElement('script');
library.type = 'text/javascript';
if (url) {
(library as HTMLScriptElement).src = url;
}
(library as HTMLScriptElement).text = content;
} else if (url) {
library = document.createElement('link');
library.type = 'text/css';
(library as HTMLLinkElement).rel = 'stylesheet';
if (url) {
(library as HTMLLinkElement).href = url;
}
} else {
library = document.createElement('style');
(library as HTMLStyleElement).textContent = content;
}
library.onload = () => {
this.loadedLibraries[key].next();
this.loadedLibraries[key].complete();
document.querySelector(targetQuery).insertAdjacentElement(position, library);
if (index === urlOrUrls.length - 1) {
subscriber.next();
subscriber.complete();
}
};
return this.loadedLibraries[key].asObservable();
document.querySelector(targetQuery).insertAdjacentElement(position, library);
});
});
}
}

35
npm/ng-packs/packages/core/src/lib/states/config.state.ts

@ -1,14 +1,14 @@
import { State, Selector, createSelector, Action, StateContext, Store } from '@ngxs/store';
import { Config } from '../models/config';
import { ABP } from '../models/common';
import { GetAppConfiguration, PatchRouteByName } from '../actions/config.actions';
import { ApplicationConfigurationService } from '../services/application-configuration.service';
import { tap, switchMap } from 'rxjs/operators';
import { Action, createSelector, Selector, State, StateContext, Store } from '@ngxs/store';
import { of } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
import snq from 'snq';
import { GetAppConfiguration, PatchRouteByName } from '../actions/config.actions';
import { SetLanguage } from '../actions/session.actions';
import { ABP } from '../models/common';
import { Config } from '../models/config';
import { ApplicationConfigurationService } from '../services/application-configuration.service';
import { organizeRoutes } from '../utils/route-utils';
import { SessionState } from './session.state';
import { of } from 'rxjs';
import { setChildRoute, sortRoutes, organizeRoutes } from '../utils/route-utils';
@State<Config.State>({
name: 'ConfigState',
@ -90,14 +90,31 @@ export class ConfigState {
return selector;
}
static getSetting(key: string) {
static getSetting(key: string, findContain?: boolean) {
const selector = createSelector(
[ConfigState],
(state: Config.State) => {
return snq(() => state.setting.values[key]);
},
);
return selector;
}
static getSettings(keyword?: string) {
const selector = createSelector(
[ConfigState],
(state: Config.State) => {
if (keyword) {
const keys = snq(() => Object.keys(state.setting.values).filter(key => key.indexOf(keyword) > -1), []);
if (keys.length) {
return keys.reduce((acc, key) => ({ ...acc, [key]: state.setting.values[key] }), {});
}
}
return snq(() => state.setting.values, {});
},
);
return selector;
}

2
npm/ng-packs/packages/theme-basic/src/lib/components/layout/layout.component.html

@ -11,7 +11,7 @@
</nav>
<div
[@routeAnimations]="outlet && outlet.activatedRoute && outlet.activatedRoute.routeConfig.path"
[@slideFromBottom]="outlet && outlet.activatedRoute && outlet.activatedRoute.routeConfig.path"
style="padding-top: 5rem;"
class="container"
>

9
npm/ng-packs/packages/theme-shared/src/lib/animations/slide.animations.ts

@ -1,6 +1,7 @@
import { animate, state, style, transition, trigger, query } from '@angular/animations';
export const slideFromBottom = trigger('routeAnimations', [
state('void', style({ 'margin-top': '20px', opacity: '0' })),
state('*', style({ 'margin-top': '0px', opacity: '1' })),
transition(':enter', [animate('0.2s ease-out', style({ opacity: '1', 'margin-top': '0px' }))]),
export const slideFromBottom = trigger('slideFromBottom', [
transition('* <=> *', [
style({ 'margin-top': '20px', opacity: '0' }),
animate('0.2s ease-out', style({ opacity: '1', 'margin-top': '0px' })),
]),
]);

9
npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts

@ -6,14 +6,14 @@ import { Component, Input } from '@angular/core';
<button [attr.type]="type" [ngClass]="buttonClass" [disabled]="loading || disabled">
<i [ngClass]="icon" class="mr-1"></i><ng-content></ng-content>
</button>
`
`,
})
export class ButtonComponent {
@Input()
buttonClass = 'btn btn-primary';
@Input()
type = 'button';
buttonType; // TODO: Add initial value.
@Input()
iconClass: string;
@ -24,6 +24,11 @@ export class ButtonComponent {
@Input()
disabled = false;
/**
* @deprecated Use buttonType instead. To be deleted in v1
*/
@Input() type = 'button';
get icon(): string {
return `${this.loading ? 'fa fa-pulse fa-spinner' : this.iconClass || 'd-none'}`;
}

2
npm/ng-packs/packages/theme-shared/src/lib/contants/styles.ts

@ -38,7 +38,7 @@ export default `
left: 0 !important;
width: 100% !important;
height: 100% !important;
background-color: rgba(0, 0, 0, .6) !important;
background-color: rgba(0, 0, 0, 0.6) !important;
z-index: 1040 !important;
}

2
npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

@ -35,7 +35,7 @@ export function appendScript(injector: Injector) {
'head',
'afterbegin',
) /* lazyLoadService.load(null, 'script', scripts) */,
).pipe(take(1));
).toPromise();
};
return fn;

1
nupkg/common.ps1

@ -59,6 +59,7 @@ $projects = (
"framework/src/Volo.Abp.Dapper",
"framework/src/Volo.Abp.Data",
"framework/src/Volo.Abp.Ddd.Application",
"framework/src/Volo.Abp.Ddd.Application.Contracts",
"framework/src/Volo.Abp.Ddd.Domain",
"framework/src/Volo.Abp.Emailing",
"framework/src/Volo.Abp.EntityFrameworkCore",

52
templates/app/angular/angular.json

@ -23,17 +23,31 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"extractCss": true,
"assets": ["src/favicon.ico", "src/assets"],
"styles": [
"src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/font-awesome/css/font-awesome.min.css",
"node_modules/primeng/resources/themes/nova-light/theme.css",
"node_modules/primeicons/primeicons.css",
"node_modules/primeng/resources/primeng.min.css"
{
"input": "node_modules/font-awesome/css/font-awesome.min.css",
"lazy": true,
"bundleName": "font-awesome.min"
},
{
"input": "node_modules/primeng/resources/themes/nova-light/theme.css",
"lazy": true,
"bundleName": "primeng-nova-light-theme"
},
{
"input": "node_modules/primeicons/primeicons.css",
"lazy": true,
"bundleName": "primeicons"
},
{
"input": "node_modules/primeng/resources/primeng.min.css",
"lazy": true,
"bundleName": "primeng.min"
}
],
"scripts": []
},
@ -100,10 +114,7 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"assets": ["src/favicon.ico", "src/assets"],
"styles": [
"src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
@ -118,14 +129,8 @@
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json"],
"exclude": ["**/node_modules/**"]
}
},
"e2e": {
@ -143,8 +148,5 @@
}
}
},
"defaultProject": "myProjectName",
"cli": {
"analytics": "07ef29be-2b85-4919-9f78-44994f63b8b7"
}
}
"defaultProject": "myProjectName"
}

18
templates/app/angular/src/app/app.component.ts

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { LazyLoadService } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
@ -7,4 +8,17 @@ import { Component } from '@angular/core';
<router-outlet></router-outlet>
`,
})
export class AppComponent {}
export class AppComponent implements OnInit {
constructor(private lazyLoadService: LazyLoadService) {}
ngOnInit() {
this.lazyLoadService
.load(
['primeng.min.css', 'primeicons.css', 'primeng-nova-light-theme.css', 'font-awesome.min.css'],
'style',
null,
'head',
)
.subscribe();
}
}

Loading…
Cancel
Save