Browse Source

Merge branch 'dev' into blazor-theming

pull/5607/head
Halil İbrahim Kalkan 6 years ago
parent
commit
74fecb72be
  1. 13
      docs/en/.vscode/settings.json
  2. 2
      docs/en/UI/Angular/Config-State.md
  3. 4
      docs/en/UI/Angular/Content-Projection-Service.md
  4. 4
      docs/en/UI/Angular/Custom-Setting-Page.md
  5. 4
      docs/en/UI/Angular/Dom-Insertion-Service.md
  6. 11
      docs/en/UI/Angular/Environment.md
  7. 98
      docs/en/UI/Angular/Feature-Libraries.md
  8. 4
      docs/en/UI/Angular/Lazy-Load-Service.md
  9. 7
      docs/en/UI/Angular/List-Service.md
  10. 29
      docs/en/UI/Angular/Multi-Tenancy.md
  11. 2
      docs/en/UI/Angular/Quick-Start.md
  12. 29
      docs/en/UI/Angular/Service-Proxies.md
  13. 4
      docs/en/UI/Angular/Subscription-Service.md
  14. 2
      docs/en/UI/Angular/Toaster-Service.md
  15. 4
      docs/en/UI/Angular/Track-By-Service.md
  16. 152
      docs/en/docs-nav.json
  17. 2
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/BloggingTestAppDbContext.cs
  18. 5
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/BloggingTestAppEntityFrameworkCoreModule.cs
  19. 1260
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20200922115311_Added_BlobStoing.Designer.cs
  20. 73
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20200922115311_Added_BlobStoing.cs
  21. 82
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/BloggingTestAppDbContextModelSnapshot.cs
  22. 1
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Volo.BloggingTestApp.EntityFrameworkCore.csproj
  23. 1
      modules/blogging/app/Volo.BloggingTestApp.MongoDB/Volo.BloggingTestApp.MongoDB.csproj
  24. 7
      modules/blogging/app/Volo.BloggingTestApp.MongoDB/Volo/BloggingTestApp/MongoDB/BloggingTestAppMongoDbModule.cs
  25. 11
      modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs
  26. 6
      modules/blogging/app/Volo.BloggingTestApp/Properties/launchSettings.json
  27. 2
      modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj
  28. 1
      modules/blogging/src/Volo.Blogging.Application/Volo.Blogging.Application.csproj
  29. 4
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationModule.cs
  30. 10
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingFileContainer.cs
  31. 5
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/BlogFileOptions.cs
  32. 49
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/FileAppService.cs
  33. 6
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/IRatingPublicAppService.cs
  34. 14
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs
  35. 7
      modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Ratings/RatingPublicController.cs
  36. 35
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Ratings/RatingPublicAppService_Tests.cs
  37. 6
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDtoBase.cs
  38. 4
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserDto.cs
  39. 1
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs
  40. 6
      modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor
  41. 5
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml
  42. 2
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs
  43. 7
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml
  44. 2
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml.cs
  45. 4
      modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs
  46. 1
      modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/ExternalLoginProvider_Tests.cs
  47. 7
      modules/tenant-management/Volo.Abp.TenantManagement.sln
  48. 14
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/AbpTenantManagementBlazorAutoMapperProfile.cs
  49. 37
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/AbpTenantManagementBlazorModule.cs
  50. 3
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/FodyWeavers.xml
  51. 30
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/FodyWeavers.xsd
  52. 23
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Menus/TenantManagementBlazorMenuContributor.cs
  53. 11
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Menus/TenantManagementBlazorMenus.cs
  54. 8
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/Tenants/Index.razor
  55. 20
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Volo.Abp.TenantManagement.Blazor.csproj
  56. 5
      modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/_Import.razor
  57. 3
      npm/ng-packs/.prettierrc
  58. 2
      npm/ng-packs/apps/dev-app/tsconfig.dev.json
  59. 2
      npm/ng-packs/apps/dev-app/tsconfig.spec.json
  60. 42
      npm/ng-packs/package.json
  61. 1
      npm/ng-packs/packages/account/src/lib/models/user.ts
  62. 6975
      npm/ng-packs/packages/feature-management/src/lib/proxy/generate-proxy.json
  63. 12
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  64. 3
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts
  65. 2
      npm/ng-packs/packages/identity/src/lib/proxy/identity/models.ts
  66. 41
      npm/ng-packs/tsconfig.base.json
  67. 78
      npm/ng-packs/tsconfig.json
  68. 1520
      npm/ng-packs/yarn.lock
  69. 3
      templates/app/angular/.prettierrc
  70. 2
      templates/app/angular/e2e/tsconfig.json
  71. 36
      templates/app/angular/package.json
  72. 2
      templates/app/angular/tsconfig.app.json
  73. 26
      templates/app/angular/tsconfig.base.json
  74. 39
      templates/app/angular/tsconfig.json
  75. 2
      templates/app/angular/tsconfig.spec.json
  76. 1207
      templates/app/angular/yarn.lock
  77. 5
      templates/module/angular/.prettierrc
  78. 36
      templates/module/angular/package.json
  79. 2
      templates/module/angular/projects/dev-app/e2e/tsconfig.json
  80. 2
      templates/module/angular/projects/dev-app/tsconfig.app.json
  81. 2
      templates/module/angular/projects/dev-app/tsconfig.spec.json
  82. 2
      templates/module/angular/projects/my-project-name/tsconfig.spec.json
  83. 15
      templates/module/angular/tsconfig.base.json
  84. 34
      templates/module/angular/tsconfig.json
  85. 2
      templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj

13
docs/en/.vscode/settings.json

@ -0,0 +1,13 @@
{
"grammarly.userWords": [
"api",
"apiName",
"cli",
"defaultProject",
"formatter",
"md",
"monorepo",
"npx",
"rootNamespace"
]
}

2
docs/en/UI/Angular/Config-State.md

@ -233,4 +233,4 @@ Please refer to `Config.Environment` type for all the properties you can pass to
## What's Next?
- [Modifying the Menu](./Modifying-the-Menu.md)
- [HTTP Requests](./Http-Requests)

4
docs/en/UI/Angular/Content-Projection-Service.md

@ -1,4 +1,4 @@
# Content Projection
# Projecting Angular Content
You can use the `ContentProjectionService` in @abp/ng.core package in order to project content in an easy and explicit way.
@ -75,4 +75,4 @@ projectContent<T extends Type<any> | TemplateRef<any>>(
## What's Next?
- [TrackByService](./Track-By-Service.md)
- [Confirmation Popup](./Confirmation-Service.md)

4
docs/en/UI/Angular/Custom-Setting-Page.md

@ -35,7 +35,3 @@ export class AppComponent {
Navigate to `/setting-management` route to see the changes:
![Custom Settings Tab](./images/custom-settings.png)
## What's Next?
- [Lazy Loading Scripts & Styles](./Lazy-Load-Service.md)

4
docs/en/UI/Angular/Dom-Insertion-Service.md

@ -1,4 +1,4 @@
# Dom Insertion (of Scripts and Styles)
# Inserting Scripts & Styles to DOM
You can use the `DomInsertionService` in @abp/ng.core package in order to insert scripts and styles in an easy and explicit way.
@ -137,4 +137,4 @@ The `has` method returns a boolean value that indicates the given content has al
## What's Next?
- [ContentProjectionService](./Content-Projection-Service.md)
- [Lazy Loading Scripts & Styles](./Lazy-Load-Service.md)

11
docs/en/UI/Angular/Environment.md

@ -4,7 +4,7 @@ Every application needs some **environment** variables. In Angular world, this i
Current `Environment` configuration holds sub config classes as follows:
```typescript
```js
export interface Environment {
apis: Apis;
application: Application;
@ -16,7 +16,7 @@ export interface Environment {
## Apis
```typescript
```js
export interface Apis {
[key: string]: ApiConfig;
default: ApiConfig;
@ -56,7 +56,7 @@ Everything else will be sent to `"https://localhost:8080"`
## Application
```typescript
```js
export interface Application {
name: string;
baseUrl?: string;
@ -80,7 +80,7 @@ Abp Framework supports this out of box.
To integrate an existing config json into the `environment`, you need to set `remoteEnv`
```typescript
```js
export type customMergeFn = (
localEnv: Partial<Config.Environment>,
remoteEnv: any,
@ -105,5 +105,4 @@ export interface RemoteEnv {
## What's Next?
* [Service Proxies](./Service-Proxies.md)
- [About Feature Libraries](./Feature-Libraries.md)

98
docs/en/UI/Angular/Feature-Libraries.md

@ -0,0 +1,98 @@
# About Feature Libraries
ABP has an ever-growing number of feature modules and [introducing a new one](../../Module-Development-Basics.md) is always possible. When the UI is Angular, these features have modular Angular libraries accompanying them.
## Feature Library Content
Each library has at least two modules:
1. The main module contains all components, services, types, enums, etc. to deliver the required UI when the feature is loaded. From here on, we will refer to these modules as **"feature module"**.
2. There is also a **"config module"** per library which helps us configure applications to run these modules or make them accessible.
## How to Add a Feature Library to Your Project
<!-- TODO: Insert info on CLI `add-module` command here when the schematic is ready. -->
The manual setup of a feature library has three steps:
### 1. Install the Library
Feature libraries are usually published as an npm package. If a library you want to use does not exist in your project, you may install it via the following command:
```shell
yarn add @my-company-name/my-project-name
```
...or...
```shell
npm install @my-company-name/my-project-name
```
The `my-company-name` and `my-project-name` parts are going to change according to the package you want to use. For example, if we want to install the ABP Identity module, the package installation will be as seen below:
```shell
yarn add @abp/ng.identity
```
> Identity is used just as an example. If you have initiated your project with ABP CLI or ABP Suite, the identity library will already be installed and configured in your project.
### 2. Import the Config Module
As of ABP v3.0, every lazy-loaded module has a config module available via a secondary entry point on the same package. Importing them in your root module looks like this:
```js
import { IdentityConfigModule } from "@abp/ng.identity/config";
@NgModule({
imports: [
// other imports
IdentityConfigModule.forRoot(),
],
// providers, declarations, and bootstrap
})
export class AppModule {}
```
We need the config modules for actions required before feature modules are loaded (lazily). For example, the above import configures the menu to display links to identity pages.
Furthermore, depending on the library, the `.forRoot` static method may receive some options that configure how the feature works.
### 3. Import the Feature Module
Finally, the feature module should be [loaded lazily via Angular router](https://angular.io/guide/lazy-loading-ngmodules). If you open the `/src/app/app-routing.module.ts` file, you should see `IdentityModule` is loaded exactly as follows:
```js
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
const routes: Routes = [
// other routes
{
path: "identity",
loadChildren: () =>
import("@abp/ng.identity").then((m) => m.IdentityModule.forLazy()),
},
// other routes
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
```
When you load the identity feature like this, the "Users" page, for example, will have a route path of `/identity/users`. <sup id="a-modify-route">[1](#f-modify-route)</sup>
Depending on the library, the `.forLazy` static method may also receive some options that configure how the feature works.
---
<sup id="f-modify-route"><b>1</b></sup> _Libraries expect to work at a predefined path. Please check [how to patch a navigation element](./Modifying-the-Menu.md#how-to-patch-or-remove-a-navigation-element), if you want to use a different path from the default one (e.g. '/identity')._ <sup>[↩](#a-modify-route)</sup>
---
## What's Next?
- [Service Proxies](./Service-Proxies.md)

4
docs/en/UI/Angular/Lazy-Load-Service.md

@ -1,4 +1,4 @@
# How to Lazy Load Scripts and Styles
# Lazy Loading Scripts & Styles
You can use the `LazyLoadService` in @abp/ng.core package in order to lazy load scripts and styles in an easy and explicit way.
@ -210,4 +210,4 @@ load(strategy: LoadingStrategy, retryTimes?: number, retryDelay?: number): Obser
## What's Next?
- [DomInsertionService](./Dom-Insertion-Service.md)
- [Projecting Angular Content](./Content-Projection-Service.md)

7
docs/en/UI/Angular/List-Service.md

@ -1,4 +1,4 @@
# Querying Lists Easily with ListService
# Working with Lists
`ListService` is a utility service to provide an easy pagination, sorting, and search implementation.
@ -177,3 +177,8 @@ As of v3.0, with ngx-datatable, the `page` property has to be set as `0` for ini
```
**Important Note:** The `abp-table` is not removed, but is deprecated and will be removed in the future. Please consider switching to ngx-datatable.
## What's Next?
- [Easy *ngFor trackBy](./Track-By-Service.md)

29
docs/en/UI/Angular/Multi-Tenancy.md

@ -2,8 +2,8 @@
ABP Angular UI supports the multi-tenancy. The following features related to multi-tenancy are available in the startup templates.
![Tenants Page](./images/tenants-page.png)
<p style="font-size:small;text-align:center;">Tenants page</p>
On the page above, you can;
@ -13,13 +13,12 @@ On the page above, you can;
- Edit an existing tenant.
- Delete a tenant.
![Tenant Switching Component](./images/tenant-switching-box.png)
<p style="font-size:small;text-align:center;">Tenant Switching Component</p>
You can switch between existing tenants by using the tenant switching component in the child pages of the `AccountLayoutComponent` (like Login page). Angular UI sends the selected tenant id to the backend as `__tenant` header on each request.
## Domain Tenant Resolver
Angular UI can get the tenant name from the app running URL. You can determine the current tenant by subdomain (like mytenant1.mydomain.com) or by the whole domain (like mytenant.com). To do this, you need to set the `application.baseUrl` property in the environment:
@ -32,10 +31,10 @@ Subdomain resolver:
export const environment = {
//...
application: {
baseUrl: 'https://{0}.mydomain.com/'
baseUrl: "https://{0}.mydomain.com/",
},
//...
}
};
```
**{0}** is the placeholder to determine current tenant's unique name.
@ -44,7 +43,6 @@ After the configuration above, if your app runs on the `mytenant1.mydomain.com`,
> **Important Note:** If you define the `baseUrl` with the placeholder (**{0}**), the tenant switching component in the child pages of the `AccountLayoutComponent` (like Login page) will be hidden.
Domain resolver:
```js
@ -53,10 +51,10 @@ Domain resolver:
export const environment = {
//...
application: {
baseUrl: 'https://{0}.com/'
baseUrl: "https://{0}.com/",
},
//...
}
};
```
After the configuration above, if your app runs on the `mytenant.com`, the app will get the tenant name as **mytenant**.
@ -71,29 +69,28 @@ The **{0}** placeholder can be put to the API URLs in the environment to determi
export const environment = {
//...
application: {
baseUrl: 'https://{0}.mydomain.com/',
baseUrl: "https://{0}.mydomain.com/",
//...
},
oAuthConfig: {
issuer: 'https://{0}.ids.mydomain.com',
issuer: "https://{0}.ids.mydomain.com",
//...
},
apis: {
default: {
url: 'https://{0}.api.mydomain.com',
url: "https://{0}.api.mydomain.com",
},
AbpIdentity: {
url: 'https://{0}.identity.mydomain.com',
url: "https://{0}.identity.mydomain.com",
},
},
}
};
```
> **Important Note:** The `application.baseUrl` and the `{0}` placeholder in the value of the `baseUrl` property are required to be able to get tenant from running URL. Other placeholders in API URLs are optional.
After the configuration above, if your app runs on the `mytenant1.mydomain.com`, the app will get tenant name as **mytenant1** and replace the environment object in `ConfigState` on app initialization as follows:
```js
// environment object in ConfigState
@ -128,8 +125,8 @@ The app sends the `__tenant` header that contains the current tenant id on each
## See Also
* [Multi Tenancy in ABP](../../Multi-Tenancy.md)
- [Multi Tenancy in ABP](../../Multi-Tenancy.md)
## What's Next?
- [Confirmation Popup](./Confirmation-Service.md)
- [Managing RxJS Subscriptions](./Subscription-Service.md)

2
docs/en/UI/Angular/Quick-Start.md

@ -209,4 +209,4 @@ In addition, you can [deploy your application to certain targets using the Angul
## What's Next?
- [Environment](./Environment.md)
- [Environment Variables](./Environment.md)

29
docs/en/UI/Angular/Service-Proxies.md

@ -1,16 +1,15 @@
## Service Proxies
It is common to call a REST endpoint in the server from our Angular applications. In this case, we generally create **services** (those have methods for each service method on the server side) and **model objects** (matches to [DTOs](../../Data-Transfer-Objects) in the server side).
Calling a REST endpoint from Angular applications is common. We usually create **services** matching server-side controllers and **interfaces** matching [DTOs](../../Data-Transfer-Objects) to interact with the server. This often results in manually transforming C# code into TypeScript equivalents and that is unfortunate, if not intolerable.
In addition to manually creating such server-interacting services, we could use tools like [NSWAG](https://github.com/RicoSuter/NSwag) to generate service proxies for us. But NSWAG has the following problems we've experienced:
To avoid manual effort, we might use a tool like [NSWAG](https://github.com/RicoSuter/NSwag) that generates service proxies. However, NSWAG has some disadvantages:
- It generates a **big, single** .ts file which has some problems;
- It get **too large** when your application grows.
- It doesn't fit into the **[modular](../../Module-Development-Basics) approach** of the ABP framework.
- It creates a bit **ugly code**. We want to have a clean code (just like if we write manually).
- It can not generate the same **method signature** declared in the server side (because swagger.json doesn't exactly reflect the method signature of the backend service). We've created an endpoint that exposes server side method contacts to allow clients generate a better aligned client proxies.
- It generates **a single .ts file** which gets **too large** as your application grows. Also, this single file does not fit the **[modular](../../Module-Development-Basics) approach** of ABP.
- To be honest, the generated code is a bit **ugly**. We would like to produce code that looks as if someone wrote it.
- Since swagger.json **does not reflect the exact method signature** of backend services, NSWAG cannot reflect them on the client-side as well.
ABP introduces an endpoint that exposes server-side method contracts. When the `generate-proxy` command is run, ABP CLI makes an HTTP request to this endpoint and generates better-aligned client proxies in TypeScript. It organizes folders according to namespaces, adds barrel exports, and reflects method signatures in Angular services.
ABP CLI changes that via the `generate-proxy` command. It automatically generates the client proxies in TypeScript. by creating folders which separated by module names in the `src/app` folder.
Run the following command in the **root folder** of the angular application:
```bash
@ -19,13 +18,13 @@ abp generate-proxy
The command without any parameters creates proxies only for your own application's services and places them in your default Angular application. There are several parameters you may use to modify this behavior. See the [CLI documentation](../../CLI) for details.
The generated files will be placed in a folder called `proxy` at the root of target project.
The generated files will be placed in a folder called `proxy` at the root of the target project.
![generated-files-via-generate-proxy](./images/generated-files-via-generate-proxy.png)
Each folder will have models, enums, and services defined at related namespace accompanied by a barrel export, i.e. an `index.ts` file for easier imports.
> The cammand is able to find application/library roots by reading `angular.json` file. Make sure you have either defined your target project as the `defaultProject` or pass the `--target` parameter to the command. This also means that you may have a monorepo workspace.
> The command can find application/library roots by reading the `angular.json` file. Make sure you have either defined your target project as the `defaultProject` or pass the `--target` parameter to the command. This also means that you may have a monorepo workspace.
### Angular Project Configuration
@ -74,9 +73,9 @@ export const environment: Config.Environment = {
The `generate-proxy` command generates one service per back-end controller and a method (property with a function value actually) for each action in the controller. These methods call backend APIs via [RestService](./Http-Requests#restservice).
A variable named `apiName` (available as of v2.4) is defined in each service. `apiName` matches the module's RemoteServiceName. This variable passes to the `RestService` as a parameter at each request. If there is no microservice API defined in the environment, `RestService` uses the default. See [getting a specific API endpoint from application config](./Http-Requests#how-to-get-a-specific-api-endpoint-from-application-config)
A variable named `apiName` (available as of v2.4) is defined in each service. `apiName` matches the module's `RemoteServiceName`. This variable passes to the `RestService` as a parameter at each request. If there is no microservice API defined in the environment, `RestService` uses the default. See [getting a specific API endpoint from application config](./Http-Requests#how-to-get-a-specific-api-endpoint-from-application-config)
The `providedIn` property of the services is defined as `'root'`. Therefore there is no need to provide them in a module. You can use them directly by injecting them into constructor as shown below:
The `providedIn` property of the services is defined as `'root'`. Therefore there is no need to provide them in a module. You can use them directly by injecting them into the constructor as shown below:
```js
import { BookService } from '@proxy/books';
@ -114,7 +113,7 @@ export class BookComponent implements OnInit {
### Enums
Enums have always been difficult to populate in the frontend. The `generate-proxy` command genarates enums in a separate file and exports a ready-to-use options constant from the same file. So you can import them as follows:
Enums have always been difficult to populate in the frontend. The `generate-proxy` command generates enums in a separate file and exports a ready-to-use "options constant" from the same file. So you can import them as follows:
```js
import { bookGenreOptions } from "@proxy/books";
@ -132,7 +131,7 @@ export class BookComponent implements OnInit {
<select formControlName="genre">
<option [ngValue]="null">Select a genre</option>
<option *ngFor="let genre of genres" [ngValue]="genre.value">
{%{{{ genre.key }}}%}
{%{{{ genre.key }}}%}
</option>
</select>
```
@ -141,4 +140,4 @@ export class BookComponent implements OnInit {
## What's Next?
- [HTTP Requests](./Http-Requests)
- [Config State](./Config-State.md)

4
docs/en/UI/Angular/Subscription-Service.md

@ -1,4 +1,4 @@
# Easy Unsubscription for Your Observables
# Managing RxJS Subscriptions
`SubscriptionService` is a utility service to provide an easy unsubscription from RxJS observables in Angular components and directives. Please see [why you should unsubscribe from observables on instance destruction](https://angular.io/guide/lifecycle-hooks#cleaning-up-on-instance-destruction).
@ -200,4 +200,4 @@ class DemoComponent implements OnInit {
## What's Next?
- [ListService](./List-Service.md)
- [Working with Lists](./List-Service.md)

2
docs/en/UI/Angular/Toaster-Service.md

@ -156,4 +156,4 @@ Removes all open toasts.
## What's Next?
- [Config State](./Config-State.md)
- [Modifying the Menu](./Modifying-the-Menu.md)

4
docs/en/UI/Angular/Track-By-Service.md

@ -1,4 +1,4 @@
# Easy TrackByFunction Implementation
# Easy *ngFor trackBy
`TrackByService` is a utility service to provide an easy implementation for one of the most frequent needs in Angular templates: `TrackByFunction`. Please see [this page in Angular docs](https://angular.io/guide/template-syntax#ngfor-with-trackby) for its purpose.
@ -116,4 +116,4 @@ class DemoComponent {
## What's Next?
- [SubscriptionService](./Subscription-Service.md)
- [Inserting Scripts & Styles to DOM](./Dom-Insertion-Service.md)

152
docs/en/docs-nav.json

@ -436,76 +436,100 @@
"path": "UI/Angular/Quick-Start.md"
},
{
"text": "Environment",
"path": "UI/Angular/Environment.md"
},
{
"text": "Service Proxies",
"path": "UI/Angular/Service-Proxies.md"
},
{
"text": "HTTP Requests",
"path": "UI/Angular/HTTP-Requests.md"
},
{
"text": "Localization",
"path": "UI/Angular/Localization.md"
},
{
"text": "Permission Management",
"path": "UI/Angular/Permission-Management.md"
},
{
"text": "Multi Tenancy",
"path": "UI/Angular/Multi-Tenancy.md"
},
{
"text": "Confirmation Popup",
"path": "UI/Angular/Confirmation-Service.md"
},
{
"text": "Toast Overlay",
"path": "UI/Angular/Toaster-Service.md"
},
{
"text": "Config State",
"path": "UI/Angular/Config-State.md"
},
{
"text": "Modifying the Menu",
"path": "UI/Angular/Modifying-the-Menu.md"
},
{
"text": "Component Replacement",
"path": "UI/Angular/Component-Replacement.md"
},
{
"text": "Custom Setting Page",
"path": "UI/Angular/Custom-Setting-Page.md"
},
{
"text": "Lazy Loading Scripts & Styles",
"path": "UI/Angular/Lazy-Load-Service.md"
},
{
"text": "DomInsertionService",
"path": "UI/Angular/Dom-Insertion-Service.md"
},
{
"text": "ContentProjectionService",
"path": "UI/Angular/Content-Projection-Service.md"
"text": "Development",
"items": [
{
"text": "Environment Variables",
"path": "UI/Angular/Environment.md"
},
{
"text": "About Feature Libraries",
"path": "UI/Angular/Feature-Libraries.md"
},
{
"text": "Service Proxies",
"path": "UI/Angular/Service-Proxies.md"
}
]
},
{
"text": "TrackByService",
"path": "UI/Angular/Track-By-Service.md"
"text": "Core Functionality",
"items": [
{
"text": "Config State",
"path": "UI/Angular/Config-State.md"
},
{
"text": "HTTP Requests",
"path": "UI/Angular/HTTP-Requests.md"
},
{
"text": "Localization",
"path": "UI/Angular/Localization.md"
},
{
"text": "Permission Management",
"path": "UI/Angular/Permission-Management.md"
},
{
"text": "Multi Tenancy",
"path": "UI/Angular/Multi-Tenancy.md"
}
]
},
{
"text": "SubscriptionService",
"path": "UI/Angular/Subscription-Service.md"
"text": "Utilities",
"items": [
{
"text": "Managing RxJS Subscriptions",
"path": "UI/Angular/Subscription-Service.md"
},
{
"text": "Working with Lists",
"path": "UI/Angular/List-Service.md"
},
{
"text": "Easy *ngFor trackBy",
"path": "UI/Angular/Track-By-Service.md"
},
{
"text": "Inserting Scripts & Styles to DOM",
"path": "UI/Angular/Dom-Insertion-Service.md"
},
{
"text": "Lazy Loading Scripts & Styles",
"path": "UI/Angular/Lazy-Load-Service.md"
},
{
"text": "Projecting Angular Content",
"path": "UI/Angular/Content-Projection-Service.md"
},
{
"text": "Confirmation Popup",
"path": "UI/Angular/Confirmation-Service.md"
},
{
"text": "Toast Overlay",
"path": "UI/Angular/Toaster-Service.md"
}
]
},
{
"text": "ListService",
"path": "UI/Angular/List-Service.md"
"text": "Customization",
"items": [
{
"text": "Modifying the Menu",
"path": "UI/Angular/Modifying-the-Menu.md"
},
{
"text": "Component Replacement",
"path": "UI/Angular/Component-Replacement.md"
},
{
"text": "Custom Setting Page",
"path": "UI/Angular/Custom-Setting-Page.md"
}
]
}
]
},

2
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/BloggingTestAppDbContext.cs

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.BlobStoring.Database.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
@ -23,6 +24,7 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore
modelBuilder.ConfigureSettingManagement();
modelBuilder.ConfigureIdentity();
modelBuilder.ConfigureBlogging();
modelBuilder.ConfigureBlobStoring();
}
}
}

5
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/BloggingTestAppEntityFrameworkCoreModule.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.BlobStoring.Database.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Modularity;
@ -13,9 +14,9 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqlServerModule))]
typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(BlobStoringDatabaseEntityFrameworkCoreModule))]
public class BloggingTestAppEntityFrameworkCoreModule : AbpModule
{
}
}

1260
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20200922115311_Added_BlobStoing.Designer.cs

File diff suppressed because it is too large

73
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20200922115311_Added_BlobStoing.cs

@ -0,0 +1,73 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
{
public partial class Added_BlobStoing : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AbpBlobContainers",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
TenantId = table.Column<Guid>(nullable: true),
Name = table.Column<string>(maxLength: 128, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpBlobContainers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpBlobs",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
ContainerId = table.Column<Guid>(nullable: false),
TenantId = table.Column<Guid>(nullable: true),
Name = table.Column<string>(maxLength: 256, nullable: false),
Content = table.Column<byte[]>(maxLength: 2147483647, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpBlobs", x => x.Id);
table.ForeignKey(
name: "FK_AbpBlobs_AbpBlobContainers_ContainerId",
column: x => x.ContainerId,
principalTable: "AbpBlobContainers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AbpBlobContainers_TenantId_Name",
table: "AbpBlobContainers",
columns: new[] { "TenantId", "Name" });
migrationBuilder.CreateIndex(
name: "IX_AbpBlobs_ContainerId",
table: "AbpBlobs",
column: "ContainerId");
migrationBuilder.CreateIndex(
name: "IX_AbpBlobs_TenantId_ContainerId_Name",
table: "AbpBlobs",
columns: new[] { "TenantId", "ContainerId", "Name" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpBlobs");
migrationBuilder.DropTable(
name: "AbpBlobContainers");
}
}
}

82
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/BloggingTestAppDbContextModelSnapshot.cs

@ -21,6 +21,79 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<Guid>("ContainerId")
.HasColumnType("uniqueidentifier");
b.Property<byte[]>("Content")
.HasColumnType("varbinary(max)")
.HasMaxLength(2147483647);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("ContainerId");
b.HasIndex("TenantId", "ContainerId", "Name");
b.ToTable("AbpBlobs");
});
modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AbpBlobContainers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
@ -1046,6 +1119,15 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
b.ToTable("BlgUsers");
});
modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b =>
{
b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null)
.WithMany()
.HasForeignKey("ContainerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole", null)

1
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Volo.BloggingTestApp.EntityFrameworkCore.csproj

@ -12,6 +12,7 @@
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.EntityFrameworkCore\Volo.Abp.SettingManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.Identity.EntityFrameworkCore\Volo.Abp.Identity.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\modules\blob-storing-database\src\Volo.Abp.BlobStoring.Database.EntityFrameworkCore\Volo.Abp.BlobStoring.Database.EntityFrameworkCore.csproj" />
</ItemGroup>
<ItemGroup>

1
modules/blogging/app/Volo.BloggingTestApp.MongoDB/Volo.BloggingTestApp.MongoDB.csproj

@ -12,6 +12,7 @@
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.MongoDB\Volo.Abp.PermissionManagement.MongoDB.csproj" />
<ProjectReference Include="..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.MongoDB\Volo.Abp.SettingManagement.MongoDB.csproj" />
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.Identity.MongoDB\Volo.Abp.Identity.MongoDB.csproj" />
<ProjectReference Include="..\..\..\..\modules\blob-storing-database\src\Volo.Abp.BlobStoring.Database.MongoDB\Volo.Abp.BlobStoring.Database.MongoDB.csproj" />
</ItemGroup>
</Project>

7
modules/blogging/app/Volo.BloggingTestApp.MongoDB/Volo/BloggingTestApp/MongoDB/BloggingTestAppMongoDbModule.cs

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.BlobStoring.Database.MongoDB;
using Volo.Abp.Identity.MongoDB;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.MongoDB;
@ -13,7 +11,8 @@ namespace Volo.BloggingTestApp.MongoDB
typeof(AbpIdentityMongoDbModule),
typeof(BloggingMongoDbModule),
typeof(AbpSettingManagementMongoDbModule),
typeof(AbpPermissionManagementMongoDbModule)
typeof(AbpPermissionManagementMongoDbModule),
typeof(BlobStoringDatabaseMongoDbModule)
)]
public class BloggingTestAppMongoDbModule : AbpModule
{

11
modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs

@ -23,6 +23,8 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Mvc.UI.Theming;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.Database;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity;
@ -37,7 +39,6 @@ using Volo.Blogging;
using Volo.Blogging.Admin;
using Volo.Blogging.Files;
using Volo.BloggingTestApp.EntityFrameworkCore;
using Volo.BloggingTestApp.MongoDB;
namespace Volo.BloggingTestApp
{
@ -57,6 +58,7 @@ namespace Volo.BloggingTestApp
typeof(AbpIdentityApplicationModule),
typeof(AbpPermissionManagementDomainIdentityModule),
typeof(AbpPermissionManagementApplicationModule),
typeof(BlobStoringDatabaseDomainModule),
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule)
)]
@ -130,9 +132,12 @@ namespace Volo.BloggingTestApp
options.DefaultThemeName = BasicTheme.Name;
});
Configure<BlogFileOptions>(options =>
Configure<AbpBlobStoringOptions>(options =>
{
options.FileUploadLocalFolder = Path.Combine(hostingEnvironment.WebRootPath, "files");
options.Containers.ConfigureDefault(container =>
{
container.UseDatabase();
});
});
}

6
modules/blogging/app/Volo.BloggingTestApp/Properties/launchSettings.json

@ -3,7 +3,7 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50013/",
"applicationUrl": "https://localhost:40013/",
"sslPort": 0
}
},
@ -21,7 +21,7 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:50017/"
"applicationUrl": "https://localhost:40017/"
}
}
}
}

2
modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj

@ -34,7 +34,7 @@
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Application\Volo.Abp.PermissionManagement.Application.csproj" />
<ProjectReference Include="..\..\..\..\modules\account\src\Volo.Abp.Account.Web\Volo.Abp.Account.Web.csproj" />
<ProjectReference Include="..\..\..\..\modules\account\src\Volo.Abp.Account.Application\Volo.Abp.Account.Application.csproj" />
<ProjectReference Include="..\Volo.BloggingTestApp.MongoDB\Volo.BloggingTestApp.MongoDB.csproj" />
<ProjectReference Include="..\..\..\..\modules\blob-storing-database\src\Volo.Abp.BlobStoring.Database.Domain\Volo.Abp.BlobStoring.Database.Domain.csproj" />
</ItemGroup>
</Project>

1
modules/blogging/src/Volo.Blogging.Application/Volo.Blogging.Application.csproj

@ -16,6 +16,7 @@
<ProjectReference Include="..\Volo.Blogging.Domain\Volo.Blogging.Domain.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Caching\Volo.Abp.Caching.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.BlobStoring\Volo.Abp.BlobStoring.csproj" />
</ItemGroup>
</Project>

4
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationModule.cs

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.BlobStoring;
using Volo.Abp.Caching;
using Volo.Abp.Modularity;
using Volo.Blogging.Comments;
@ -12,7 +13,8 @@ namespace Volo.Blogging
typeof(BloggingDomainModule),
typeof(BloggingApplicationContractsModule),
typeof(AbpCachingModule),
typeof(AbpAutoMapperModule))]
typeof(AbpAutoMapperModule),
typeof(AbpBlobStoringModule))]
public class BloggingApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)

10
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingFileContainer.cs

@ -0,0 +1,10 @@
using Volo.Abp.BlobStoring;
namespace Volo.Blogging
{
[BlobContainerName("blogging-files")]
public class BloggingFileContainer
{
}
}

5
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/BlogFileOptions.cs

@ -1,4 +1,6 @@
namespace Volo.Blogging.Files
using System;
namespace Volo.Blogging.Files
{
/* TODO:
* - It is not to have different options for all different modules. We should find a more generic way.
@ -6,6 +8,7 @@
*/
public class BlogFileOptions
{
[Obsolete("Now store using blob storing system, will be deleted in a next version")]
public string FileUploadLocalFolder { get; set; }
}
}

49
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/FileAppService.cs

@ -2,9 +2,9 @@
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.BlobStoring;
using Volo.Abp.Validation;
using Volo.Blogging.Areas.Blog.Helpers;
@ -12,42 +12,25 @@ namespace Volo.Blogging.Files
{
public class FileAppService : BloggingAppServiceBase, IFileAppService
{
public BlogFileOptions Options { get; }
private readonly ILogger<FileAppService> _logger;
protected IBlobContainer<BloggingFileContainer> BlobContainer { get; }
public FileAppService(IOptions<BlogFileOptions> options, ILogger<FileAppService> logger)
public FileAppService(
IBlobContainer<BloggingFileContainer> blobContainer)
{
_logger = logger;
Options = options.Value;
BlobContainer = blobContainer;
}
public virtual Task<RawFileDto> GetAsync(string name)
public virtual async Task<RawFileDto> GetAsync(string name)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
if (!Directory.Exists(Options.FileUploadLocalFolder))
return new RawFileDto
{
Directory.CreateDirectory(Options.FileUploadLocalFolder);
return Task.FromResult(
new RawFileDto
{
Bytes = new byte[0]
}
);
}
var filePath = Path.Combine(Options.FileUploadLocalFolder, name);
if (File.Exists(filePath))
{
return Task.FromResult(new RawFileDto {Bytes = File.ReadAllBytes(filePath)});
}
_logger.LogError($"Cannot find the file {filePath}");
return Task.FromResult(RawFileDto.EmptyResult());
Bytes = await BlobContainer.GetAllBytesAsync(name)
};
}
public virtual Task<FileUploadOutputDto> CreateAsync(FileUploadInputDto input)
public virtual async Task<FileUploadOutputDto> CreateAsync(FileUploadInputDto input)
{
if (input.Bytes.IsNullOrEmpty())
{
@ -65,20 +48,14 @@ namespace Volo.Blogging.Files
}
var uniqueFileName = GenerateUniqueFileName(Path.GetExtension(input.Name));
var filePath = Path.Combine(Options.FileUploadLocalFolder, uniqueFileName);
if (!Directory.Exists(Options.FileUploadLocalFolder))
{
Directory.CreateDirectory(Options.FileUploadLocalFolder);
}
File.WriteAllBytes(filePath, input.Bytes); //TODO: Previously was using WriteAllBytesAsync, but it's only in .netcore.
await BlobContainer.SaveAsync(uniqueFileName, input.Bytes);
return Task.FromResult(new FileUploadOutputDto
return new FileUploadOutputDto
{
Name = uniqueFileName,
WebUrl = "/api/blogging/files/www/" + uniqueFileName
});
};
}
private static void ThrowValidationException(string message, string memberName)

6
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/IRatingPublicAppService.cs

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Volo.CmsKit.Public.Ratings
@ -11,8 +9,6 @@ namespace Volo.CmsKit.Public.Ratings
Task<RatingDto> CreateAsync(string entityType, string entityId, CreateUpdateRatingInput input);
Task DeleteAsync(string entityType, string entityId);
Task<RatingDto> GetCurrentUserRatingAsync(string entityType, string entityId);
Task<List<RatingWithStarCountDto>> GetGroupedStarCountsAsync(string entityType, string entityId);
}

14
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization;
using Volo.Abp.Users;
@ -66,16 +64,6 @@ namespace Volo.CmsKit.Public.Ratings
await RatingRepository.DeleteAsync(rating.Id);
}
[Authorize]
public virtual async Task<RatingDto> GetCurrentUserRatingAsync(string entityType, string entityId)
{
var currentUserId = CurrentUser.GetId();
var rating = await RatingRepository.GetCurrentUserRatingAsync(entityType, entityId, currentUserId);
return ObjectMapper.Map<Rating, RatingDto>(rating);
}
public virtual async Task<List<RatingWithStarCountDto>> GetGroupedStarCountsAsync(string entityType,
string entityId)
{

7
modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Ratings/RatingPublicController.cs

@ -34,13 +34,6 @@ namespace Volo.CmsKit.Public.Ratings
return RatingPublicAppService.DeleteAsync(entityType, entityId);
}
[HttpGet]
[Route("{entityType}/{entityId}")]
public virtual Task<RatingDto> GetCurrentUserRatingAsync(string entityType, string entityId)
{
return RatingPublicAppService.GetCurrentUserRatingAsync(entityType, entityId);
}
[HttpGet]
[Route("{entityType}/{entityId}")]
public virtual Task<List<RatingWithStarCountDto>> GetGroupedStarCountsAsync(string entityType, string entityId)

35
modules/cms-kit/test/Volo.CmsKit.Application.Tests/Ratings/RatingPublicAppService_Tests.cs

@ -1,6 +1,5 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
@ -52,16 +51,16 @@ namespace Volo.CmsKit.Ratings
.ShouldBeTrue();
});
}
[Fact]
public async Task CreateAsync_Should_Update_If_Rating_Is_Exist()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
var entity =
await _ratingAppService.GetCurrentUserRatingAsync(_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1);
(await _ratingAppService.GetGroupedStarCountsAsync(_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1)).FirstOrDefault();
var updatedEntity = await _ratingAppService.CreateAsync(
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
@ -69,34 +68,10 @@ namespace Volo.CmsKit.Ratings
{
StarCount = 5
});
entity.Id.ShouldBe(updatedEntity.Id);
entity.EntityId.ShouldBe(updatedEntity.EntityId);
entity.EntityType.ShouldBe(updatedEntity.EntityType);
entity.StarCount.ShouldBe(updatedEntity.StarCount);
}
[Fact]
public async Task GetCurrentUserRatingAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
var rating = await _ratingAppService.GetCurrentUserRatingAsync(
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1
);
UsingDbContext(context =>
{
var ratings = context.Set<Rating>().Where(x =>
x.EntityId == _cmsKitTestData.EntityId1 && x.EntityType == _cmsKitTestData.EntityType1).ToList();
ratings
.Any(c => c.Id == rating.Id && c.EntityId == rating.EntityId && c.EntityType == rating.EntityType)
.ShouldBeTrue();
});
}
[Fact]
public async Task GetGroupedStarCountsAsync()
{

6
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDtoBase.cs

@ -26,8 +26,6 @@ namespace Volo.Abp.Identity
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
public string PhoneNumber { get; set; }
public bool TwoFactorEnabled { get; set; }
public bool LockoutEnabled { get; set; }
[CanBeNull]
@ -35,7 +33,7 @@ namespace Volo.Abp.Identity
protected IdentityUserCreateOrUpdateDtoBase() : base(false)
{
}
}
}
}

4
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserDto.cs

@ -23,12 +23,10 @@ namespace Volo.Abp.Identity
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public bool LockoutEnabled { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public string ConcurrencyStamp { get; set; }
}
}
}

1
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs

@ -162,7 +162,6 @@ namespace Volo.Abp.Identity
(await UserManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
}
(await UserManager.SetTwoFactorEnabledAsync(user, input.TwoFactorEnabled)).CheckErrors();
(await UserManager.SetLockoutEnabledAsync(user, input.LockoutEnabled)).CheckErrors();
user.Name = input.Name;

6
modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor

@ -121,9 +121,6 @@
<Field>
<Check TValue="bool" @bind-checked="@NewEntity.LockoutEnabled">@L["DisplayName:LockoutEnabled"]</Check>
</Field>
<Field>
<Check TValue="bool" @bind-checked="@NewEntity.TwoFactorEnabled">@L["DisplayName:TwoFactorEnabled"]</Check>
</Field>
</TabPanel>
<TabPanel Name="Roles">
@if (NewUserRoles != null)
@ -197,9 +194,6 @@
<Field>
<Check TValue="bool" @bind-checked="EditingEntity.LockoutEnabled">@L["DisplayName:LockoutEnabled"]</Check>
</Field>
<Field>
<Check TValue="bool" @bind-checked="EditingEntity.TwoFactorEnabled">@L["DisplayName:TwoFactorEnabled"]</Check>
</Field>
</TabPanel>
<TabPanel Name="Roles">
@if (EditUserRoles != null)

5
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml

@ -26,8 +26,7 @@
<abp-input asp-for="UserInfo.Email" />
<abp-input asp-for="UserInfo.PhoneNumber" />
<abp-input asp-for="UserInfo.LockoutEnabled" />
<abp-input asp-for="UserInfo.TwoFactorEnabled" />
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModalModel.UserInfoViewModel>())
{
if (propertyInfo.Type.IsEnum)
@ -56,4 +55,4 @@
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</form>
</form>

2
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs

@ -79,8 +79,6 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Users
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
public string PhoneNumber { get; set; }
public bool TwoFactorEnabled { get; set; } = true;
public bool LockoutEnabled { get; set; } = true;
}

7
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml

@ -28,8 +28,7 @@
<abp-input asp-for="UserInfo.Email" />
<abp-input asp-for="UserInfo.PhoneNumber" />
<abp-input asp-for="UserInfo.LockoutEnabled" />
<abp-input asp-for="UserInfo.TwoFactorEnabled" />
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<EditModalModel.UserInfoViewModel>())
{
if (propertyInfo.Type.IsEnum)
@ -46,7 +45,7 @@
value="@propertyInfo.GetInputValueOrNull(Model.UserInfo.ExtraProperties[propertyInfo.Name])" />
}
}
</abp-tab>
<abp-tab title="@L["Roles"].Value">
@for (var i = 0; i < Model.Roles.Length; i++)
@ -59,4 +58,4 @@
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</form>
</form>

2
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml.cs

@ -87,8 +87,6 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Users
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
public string PhoneNumber { get; set; }
public bool TwoFactorEnabled { get; set; }
public bool LockoutEnabled { get; set; }
}

4
modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs

@ -98,7 +98,6 @@ namespace Volo.Abp.Identity
{
UserName = johnNash.UserName,
LockoutEnabled = true,
TwoFactorEnabled = true,
PhoneNumber = CreateRandomPhoneNumber(),
Password = "123qwe4R*",
Email = CreateRandomEmail(),
@ -135,7 +134,7 @@ namespace Volo.Abp.Identity
{
//Get user
var johnNash = await _userAppService.GetAsync(_testData.UserJohnId);
//Act
var input = new IdentityUserUpdateDto
@ -144,7 +143,6 @@ namespace Volo.Abp.Identity
Surname = "Nash-updated",
UserName = johnNash.UserName,
LockoutEnabled = true,
TwoFactorEnabled = true,
PhoneNumber = CreateRandomPhoneNumber(),
Email = CreateRandomEmail(),
RoleNames = new[] { "admin", "moderator" },

1
modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/ExternalLoginProvider_Tests.cs

@ -44,7 +44,6 @@ namespace Volo.Abp.Identity.AspNetCore
user.Name.ShouldBe("Test Name");
user.Surname.ShouldBe("Test Surname");
user.EmailConfirmed.ShouldBeTrue();
user.TwoFactorEnabled.ShouldBeFalse();
user.PhoneNumber.ShouldBe("123");
user.PhoneNumberConfirmed.ShouldBeFalse();
user.IsExternal.ShouldBeTrue();

7
modules/tenant-management/Volo.Abp.TenantManagement.sln

@ -35,6 +35,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.TenantManagement.T
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TenantManagement.Domain.Tests", "test\Volo.Abp.TenantManagement.Domain.Tests\Volo.Abp.TenantManagement.Domain.Tests.csproj", "{F7219BE2-4588-489C-9D31-647C59694C03}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TenantManagement.Blazor", "src\Volo.Abp.TenantManagement.Blazor\Volo.Abp.TenantManagement.Blazor.csproj", "{05040C16-B531-446A-B406-277E44D147C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -97,6 +99,10 @@ Global
{F7219BE2-4588-489C-9D31-647C59694C03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7219BE2-4588-489C-9D31-647C59694C03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7219BE2-4588-489C-9D31-647C59694C03}.Release|Any CPU.Build.0 = Release|Any CPU
{05040C16-B531-446A-B406-277E44D147C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05040C16-B531-446A-B406-277E44D147C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{05040C16-B531-446A-B406-277E44D147C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05040C16-B531-446A-B406-277E44D147C0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -116,6 +122,7 @@ Global
{F75B4C54-A5F1-4101-99F5-A5B868A5146B} = {C6941869-A9FC-4BEA-AD3F-C1E104826ECA}
{C3BAD6E8-00CD-4283-9416-64287BB5B265} = {C6941869-A9FC-4BEA-AD3F-C1E104826ECA}
{F7219BE2-4588-489C-9D31-647C59694C03} = {C6941869-A9FC-4BEA-AD3F-C1E104826ECA}
{05040C16-B531-446A-B406-277E44D147C0} = {799CA525-4748-421A-9892-05C68BB2FA13}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7C258726-2CE0-44D3-A2D7-71812E8F505C}

14
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/AbpTenantManagementBlazorAutoMapperProfile.cs

@ -0,0 +1,14 @@
using AutoMapper;
namespace Volo.Abp.TenantManagement.Blazor
{
public class AbpTenantManagementBlazorAutoMapperProfile : Profile
{
public AbpTenantManagementBlazorAutoMapperProfile()
{
/* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
}
}
}

37
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/AbpTenantManagementBlazorModule.cs

@ -0,0 +1,37 @@
using Microsoft.Extensions.DependencyInjection;
using MyCompanyName.MyProjectName.Blazor;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.TenantManagement.Blazor.Menus;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.TenantManagement.Blazor
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpTenantManagementHttpApiClientModule)
)]
public class AbpTenantManagementBlazorModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpTenantManagementBlazorModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpTenantManagementBlazorAutoMapperProfile>(validate: true);
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new TenantManagementBlazorMenuContributor());
});
Configure<AbpRouterOptions>(options =>
{
options.AdditionalAssemblies.Add(typeof(AbpTenantManagementBlazorModule).Assembly);
});
}
}
}

3
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/FodyWeavers.xml

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

30
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/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>

23
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Menus/TenantManagementBlazorMenuContributor.cs

@ -0,0 +1,23 @@
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.TenantManagement.Blazor.Menus
{
public class TenantManagementBlazorMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenu(context);
}
}
private Task ConfigureMainMenu(MenuConfigurationContext context)
{
//Add main menu items.
return Task.CompletedTask;
}
}
}

11
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Menus/TenantManagementBlazorMenus.cs

@ -0,0 +1,11 @@
namespace Volo.Abp.TenantManagement.Blazor.Menus
{
public class TenantManagementBlazorMenus
{
private const string Prefix = "MyProjectName";
//Add your menu items here...
//public const string Home = Prefix + ".MyNewMenuItem";
}
}

8
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/Tenants/Index.razor

@ -0,0 +1,8 @@
@page "/TenantManagement/Tenants"
@using Microsoft.Extensions.Localization
@using Volo.Abp.TenantManagement.Localization
@inject IStringLocalizer<AbpTenantManagementResource> L
@{
}
<h1>MyProjectName</h1>
<p>@L["SamplePageMessage"]</p>

20
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Volo.Abp.TenantManagement.Blazor.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<RootNamespace>Volo.Abp.TenantManagement.Blazor</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.TenantManagement.HttpApi.Client\Volo.Abp.TenantManagement.HttpApi.Client.csproj" />
</ItemGroup>
</Project>

5
modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/_Import.razor

@ -0,0 +1,5 @@
@using Microsoft.AspNetCore.Components.Web
@using Volo.Abp.AspNetCore.Components.WebAssembly
@using Volo.Abp.BlazoriseUI
@using Blazorise
@using Blazorise.DataGrid

3
npm/ng-packs/.prettierrc

@ -1,5 +1,6 @@
{
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all"
"trailingComma": "all",
"arrowParens": "avoid"
}

2
npm/ng-packs/apps/dev-app/tsconfig.dev.json

@ -1,5 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/app",
"types": []

2
npm/ng-packs/apps/dev-app/tsconfig.spec.json

@ -1,5 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": ["node", "jest"]

42
npm/ng-packs/package.json

@ -21,7 +21,7 @@
"ci:test": "ng test --coverage=false --silent",
"ci:build": "cd scripts && yarn install && yarn build:prod",
"lerna": "lerna",
"compile:ivy": "yarn ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points --tsconfig './tsconfig.prod.json' --source node_modules --async false",
"compile:ivy": "yarn ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points --tsconfig './tsconfig.prod.json' --source node_modules",
"postinstall": "npm run compile:ivy"
},
"devDependencies": {
@ -37,21 +37,21 @@
"@abp/ng.theme.shared": "~3.2.0-rc.2",
"@abp/utils": "^3.2.0-rc.2",
"@angular-builders/jest": "^10.0.0",
"@angular-devkit/build-angular": "~0.1000.6",
"@angular-devkit/build-ng-packagr": "~0.1000.6",
"@angular-devkit/build-angular": "~0.1001.2",
"@angular-devkit/build-ng-packagr": "~0.1001.2",
"@angular-devkit/schematics-cli": "^0.1001.1",
"@angular/animations": "~10.0.10",
"@angular/cli": "~10.0.6",
"@angular/common": "~10.0.10",
"@angular/compiler": "10.0.0",
"@angular/compiler-cli": "10.0.0",
"@angular/core": "~10.0.10",
"@angular/forms": "~10.0.10",
"@angular/language-service": "~10.0.10",
"@angular/localize": "~10.0.10",
"@angular/platform-browser": "~10.0.10",
"@angular/platform-browser-dynamic": "~10.0.10",
"@angular/router": "~10.0.10",
"@angular/animations": "~10.1.2",
"@angular/cli": "~10.1.2",
"@angular/common": "~10.1.2",
"@angular/compiler": "10.1.2",
"@angular/compiler-cli": "10.1.2",
"@angular/core": "~10.1.2",
"@angular/forms": "~10.1.2",
"@angular/language-service": "~10.1.2",
"@angular/localize": "~10.1.2",
"@angular/platform-browser": "~10.1.2",
"@angular/platform-browser-dynamic": "~10.1.2",
"@angular/router": "~10.1.2",
"@fortawesome/fontawesome-free": "^5.14.0",
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
"@ngneat/spectator": "^5.13.0",
@ -68,7 +68,7 @@
"angular-oauth2-oidc": "^10.0.3",
"bootstrap": "^4.5.0",
"chart.js": "^2.9.3",
"codelyzer": "^5.1.2",
"codelyzer": "^6.0.0",
"conventional-changelog-cli": "^2.0.31",
"cz-conventional-changelog": "3.0.2",
"font-awesome": "^4.7.0",
@ -84,25 +84,21 @@
"ng-zorro-antd": "^9.3.0",
"ngxs-reset-plugin": "^1.3.0",
"ngxs-schematic": "^1.1.9",
"prettier": "^1.18.2",
"prettier": "^2.1.2",
"protractor": "~7.0.0",
"rxjs": "~6.5.4",
"snq": "^1.0.3",
"symlink-manager": "^1.5.0",
"ts-node": "~7.0.0",
"ts-toolbelt": "6.15.4",
"tsickle": "^0.38.1",
"tsickle": "^0.39.1",
"tslint": "~6.1.0",
"typescript": "~3.9.5",
"typescript": "~4.0.3",
"zone.js": "~0.10.2"
},
"dependencies": {
"tslib": "^2.0.0"
},
"resolutions": {
"@angular/compiler": "10.0.0",
"@angular/compiler-cli": "10.0.0"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"

1
npm/ng-packs/packages/account/src/lib/models/user.ts

@ -14,7 +14,6 @@ export interface RegisterResponse {
emailConfirmed: boolean;
phoneNumber: string;
phoneNumberConfirmed: boolean;
twoFactorEnabled: boolean;
lockoutEnabled: boolean;
lockoutEnd: string;
concurrencyStamp: string;

6975
npm/ng-packs/packages/feature-management/src/lib/proxy/generate-proxy.json

File diff suppressed because it is too large

12
npm/ng-packs/packages/identity/src/lib/components/users/users.component.html

@ -169,18 +169,6 @@
'AbpIdentity::DisplayName:LockoutEnabled' | abpLocalization
}}</label>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="two-factor-checkbox"
class="custom-control-input"
formControlName="twoFactorEnabled"
/>
<label class="custom-control-label" for="two-factor-checkbox">{{
'AbpIdentity::DisplayName:TwoFactorEnabled' | abpLocalization
}}</label>
</div>
</ng-template>
</li>

3
npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts

@ -101,8 +101,7 @@ export class UsersComponent implements OnInit {
name: [this.selected.name || '', [Validators.maxLength(64)]],
surname: [this.selected.surname || '', [Validators.maxLength(64)]],
phoneNumber: [this.selected.phoneNumber || '', [Validators.maxLength(16)]],
lockoutEnabled: [this.selected.lockoutEnabled || (this.selected.id ? false : true)],
twoFactorEnabled: [this.selected.twoFactorEnabled || (this.selected.id ? false : true)],
lockoutEnabled: [this.selected.id ? this.selected.lockoutEnabled : true],
roleNames: this.fb.array(
this.roles.map(role =>
this.fb.group({

2
npm/ng-packs/packages/identity/src/lib/proxy/identity/models.ts

@ -41,7 +41,6 @@ export interface IdentityUserCreateOrUpdateDtoBase extends ExtensibleObject {
surname: string;
email: string;
phoneNumber: string;
twoFactorEnabled: boolean;
lockoutEnabled: boolean;
roleNames: string[];
}
@ -55,7 +54,6 @@ export interface IdentityUserDto extends ExtensibleFullAuditedEntityDto<string>
emailConfirmed: boolean;
phoneNumber: string;
phoneNumberConfirmed: boolean;
twoFactorEnabled: boolean;
lockoutEnabled: boolean;
lockoutEnd?: string;
concurrencyStamp: string;

41
npm/ng-packs/tsconfig.base.json

@ -1,41 +0,0 @@
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"types": ["jest"],
"paths": {
"@abp/ng.core": ["packages/core/src/public-api.ts"],
"@abp/ng.theme.shared": ["packages/theme-shared/src/public-api.ts"],
"@abp/ng.theme.shared/extensions": ["packages/theme-shared/extensions/src/public-api.ts"],
"@abp/ng.components/tree": ["packages/components/tree/src/public-api.ts"],
"@abp/ng.theme.basic": ["packages/theme-basic/src/public-api.ts"],
"@abp/ng.account": ["packages/account/src/public-api.ts"],
"@abp/ng.account/config": ["packages/account/config/src/public-api.ts"],
"@abp/ng.identity": ["packages/identity/src/public-api.ts"],
"@abp/ng.identity/config": ["packages/identity/config/src/public-api.ts"],
"@abp/ng.tenant-management": ["packages/tenant-management/src/public-api.ts"],
"@abp/ng.tenant-management/config": ["packages/tenant-management/config/src/public-api.ts"],
"@abp/ng.setting-management": ["packages/setting-management/src/public-api.ts"],
"@abp/ng.setting-management/config": ["packages/setting-management/config/src/public-api.ts"],
"@abp/ng.permission-management": ["packages/permission-management/src/public-api.ts"],
"@abp/ng.feature-management": ["packages/feature-management/src/public-api.ts"],
"@proxy": ["apps/dev-app/src/app/proxy/index.ts"],
"@proxy/*": ["apps/dev-app/src/app/proxy/*"]
}
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true
}
}

78
npm/ng-packs/tsconfig.json

@ -1,41 +1,41 @@
/*
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScripts language server to improve development experience.
It is not intended to be used to perform a compilation.
To learn more about this file see: https://angular.io/config/solution-tsconfig.
*/
{
"files": [],
"references": [
{
"path": "./packages/core/tsconfig.lib.json"
},
{
"path": "./packages/theme-shared/tsconfig.lib.json"
},
{
"path": "./packages/theme-basic/tsconfig.lib.json"
},
{
"path": "./packages/account/tsconfig.lib.json"
},
{
"path": "./packages/permission-management/tsconfig.lib.json"
},
{
"path": "./packages/identity/tsconfig.lib.json"
},
{
"path": "./packages/feature-management/tsconfig.lib.json"
},
{
"path": "./packages/tenant-management/tsconfig.lib.json"
},
{
"path": "./packages/setting-management/tsconfig.lib.json"
},
{
"path": "./apps/dev-app/tsconfig.dev.json"
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"types": ["jest"],
"paths": {
"@abp/ng.core": ["packages/core/src/public-api.ts"],
"@abp/ng.theme.shared": ["packages/theme-shared/src/public-api.ts"],
"@abp/ng.theme.shared/extensions": ["packages/theme-shared/extensions/src/public-api.ts"],
"@abp/ng.components/tree": ["packages/components/tree/src/public-api.ts"],
"@abp/ng.theme.basic": ["packages/theme-basic/src/public-api.ts"],
"@abp/ng.account": ["packages/account/src/public-api.ts"],
"@abp/ng.account/config": ["packages/account/config/src/public-api.ts"],
"@abp/ng.identity": ["packages/identity/src/public-api.ts"],
"@abp/ng.identity/config": ["packages/identity/config/src/public-api.ts"],
"@abp/ng.tenant-management": ["packages/tenant-management/src/public-api.ts"],
"@abp/ng.tenant-management/config": ["packages/tenant-management/config/src/public-api.ts"],
"@abp/ng.setting-management": ["packages/setting-management/src/public-api.ts"],
"@abp/ng.setting-management/config": ["packages/setting-management/config/src/public-api.ts"],
"@abp/ng.permission-management": ["packages/permission-management/src/public-api.ts"],
"@abp/ng.feature-management": ["packages/feature-management/src/public-api.ts"],
"@proxy": ["apps/dev-app/src/app/proxy/index.ts"],
"@proxy/*": ["apps/dev-app/src/app/proxy/*"]
}
]
}
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true
}
}

1520
npm/ng-packs/yarn.lock

File diff suppressed because it is too large

3
templates/app/angular/.prettierrc

@ -1,4 +1,5 @@
{
"singleQuote": true,
"printWidth": 100
"printWidth": 100,
"arrowParens": "avoid"
}

2
templates/app/angular/e2e/tsconfig.json

@ -1,5 +1,5 @@
{
"extends": "../tsconfig.base.json",
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",

36
templates/app/angular/package.json

@ -17,40 +17,40 @@
"@abp/ng.setting-management": "~3.2.0-rc.2",
"@abp/ng.tenant-management": "~3.2.0-rc.2",
"@abp/ng.theme.basic": "~3.2.0-rc.2",
"@angular/animations": "~10.0.10",
"@angular/common": "~10.0.10",
"@angular/compiler": "~10.0.10",
"@angular/core": "~10.0.10",
"@angular/forms": "~10.0.10",
"@angular/platform-browser": "~10.0.10",
"@angular/platform-browser-dynamic": "~10.0.10",
"@angular/router": "~10.0.10",
"rxjs": "~6.5.4",
"@angular/animations": "~10.1.2",
"@angular/common": "~10.1.2",
"@angular/compiler": "~10.1.2",
"@angular/core": "~10.1.2",
"@angular/forms": "~10.1.2",
"@angular/platform-browser": "~10.1.2",
"@angular/platform-browser-dynamic": "~10.1.2",
"@angular/router": "~10.1.2",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@abp/ng.schematics": "~3.2.0-rc.2",
"@angular-devkit/build-angular": "~0.1000.6",
"@angular-devkit/build-ng-packagr": "~0.1000.6",
"@angular/cli": "~10.0.6",
"@angular/compiler-cli": "~10.0.10",
"@angular/language-service": "~10.0.10",
"@angular-devkit/build-angular": "~0.1001.2",
"@angular-devkit/build-ng-packagr": "~0.1001.2",
"@angular/cli": "~10.1.2",
"@angular/compiler-cli": "~10.1.2",
"@angular/language-service": "~10.1.2",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.5.0",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"ng-packagr": "^10.0.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.9.5"
"typescript": "~4.0.2"
}
}

2
templates/app/angular/tsconfig.app.json

@ -1,5 +1,5 @@
{
"extends": "./tsconfig.base.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []

26
templates/app/angular/tsconfig.base.json

@ -1,26 +0,0 @@
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"paths": {
"@proxy": ["src/app/proxy/index.ts"],
"@proxy/*": ["src/app/proxy/*"]
}
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"enableIvy": true
}
}

39
templates/app/angular/tsconfig.json

@ -1,17 +1,26 @@
/*
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScripts language server to improve development experience.
It is not intended to be used to perform a compilation.
To learn more about this file see: https://angular.io/config/solution-tsconfig.
*/
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"paths": {
"@proxy": ["src/app/proxy/index.ts"],
"@proxy/*": ["src/app/proxy/*"]
}
]
}
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"enableIvy": true
}
}

2
templates/app/angular/tsconfig.spec.json

@ -1,5 +1,5 @@
{
"extends": "./tsconfig.base.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [

1207
templates/app/angular/yarn.lock

File diff suppressed because it is too large

5
templates/module/angular/.prettierrc

@ -0,0 +1,5 @@
{
"singleQuote": true,
"printWidth": 100,
"arrowParens": "avoid"
}

36
templates/module/angular/package.json

@ -20,40 +20,40 @@
"@abp/ng.setting-management": "~3.2.0-rc.2",
"@abp/ng.tenant-management": "~3.2.0-rc.2",
"@abp/ng.theme.basic": "~3.2.0-rc.2",
"@angular/animations": "~10.0.0",
"@angular/common": "~10.0.0",
"@angular/compiler": "~10.0.0",
"@angular/core": "~10.0.0",
"@angular/forms": "~10.0.0",
"@angular/platform-browser": "~10.0.0",
"@angular/platform-browser-dynamic": "~10.0.0",
"@angular/router": "~10.0.0",
"rxjs": "~6.5.4",
"@angular/animations": "~10.1.2",
"@angular/common": "~10.1.2",
"@angular/compiler": "~10.1.2",
"@angular/core": "~10.1.2",
"@angular/forms": "~10.1.2",
"@angular/platform-browser": "~10.1.2",
"@angular/platform-browser-dynamic": "~10.1.2",
"@angular/router": "~10.1.2",
"rxjs": "~6.6.3",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@abp/ng.schematics": "~3.2.0-rc.2",
"@angular-devkit/build-angular": "~0.1000.0",
"@angular-devkit/build-ng-packagr": "~0.1000.0",
"@angular/cli": "~10.0.0",
"@angular/compiler-cli": "~10.0.0",
"@angular-devkit/build-angular": "~0.1001.2",
"@angular-devkit/build-ng-packagr": "~0.1001.2",
"@angular/cli": "~10.1.2",
"@angular/compiler-cli": "~10.1.2",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.5.0",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"ng-packagr": "^10.0.0",
"protractor": "~7.0.0",
"symlink-manager": "^1.5.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.9.5"
"typescript": "~4.0.3"
}
}
}

2
templates/module/angular/projects/dev-app/e2e/tsconfig.json

@ -1,5 +1,5 @@
{
"extends": "../../../tsconfig.base.json",
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/e2e",
"module": "commonjs",

2
templates/module/angular/projects/dev-app/tsconfig.app.json

@ -1,5 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/app",
"types": []

2
templates/module/angular/projects/dev-app/tsconfig.spec.json

@ -1,5 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [

2
templates/module/angular/projects/my-project-name/tsconfig.spec.json

@ -1,5 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [

15
templates/module/angular/tsconfig.base.json

@ -1,15 +0,0 @@
{
"extends": "./tsconfig.prod.json",
"compilerOptions": {
"paths": {
"@my-company-name/my-project-name": [
"projects/my-project-name/src/public-api.ts"
],
"@my-company-name/my-project-name/config": [
"projects/my-project-name/config/src/public-api.ts"
],
"@proxy": ["projects/my-project-name/src/lib/proxy/index.ts"],
"@proxy/*": ["projects/my-project-name/src/lib/proxy/*"]
}
}
}

34
templates/module/angular/tsconfig.json

@ -1,23 +1,15 @@
/*
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScripts language server to improve development experience.
It is not intended to be used to perform a compilation.
To learn more about this file see: https://angular.io/config/solution-tsconfig.
*/
{
"files": [],
"references": [
{
"path": "./projects/my-project-name/tsconfig.lib.json"
},
{
"path": "./projects/my-project-name/tsconfig.spec.json"
},
{
"path": "./projects/dev-app/tsconfig.app.json"
},
{
"path": "./projects/dev-app/tsconfig.spec.json"
"extends": "./tsconfig.prod.json",
"compilerOptions": {
"paths": {
"@my-company-name/my-project-name": [
"projects/my-project-name/src/public-api.ts"
],
"@my-company-name/my-project-name/config": [
"projects/my-project-name/config/src/public-api.ts"
],
"@proxy": ["projects/my-project-name/src/lib/proxy/index.ts"],
"@proxy/*": ["projects/my-project-name/src/lib/proxy/*"]
}
]
}
}
}

2
templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\common.props" />

Loading…
Cancel
Save