diff --git a/.github/workflows/angular.yml b/.github/workflows/angular.yml index 1b4d37bd39..dfca28338b 100644 --- a/.github/workflows/angular.yml +++ b/.github/workflows/angular.yml @@ -9,8 +9,41 @@ jobs: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + + - uses: actions/cache@v2 with: - node-version: '12.x' - - run: yarn && yarn ci + path: 'npm/ng-packs/node_modules' + key: ${{ runner.os }}-${{ hashFiles('npm/ng-packs/yarn.lock') }} + + - uses: actions/cache@v2 + with: + path: 'templates/app/angular/node_modules' + key: ${{ runner.os }}-${{ hashFiles('templates/app/angular/yarn.lock') }} + + - name: Install packages + run: yarn install + working-directory: npm/ng-packs + + - name: Run lint + run: yarn ng lint + working-directory: npm/ng-packs + + - name: Run prepare workspace + run: yarn prepare:workspace + working-directory: npm/ng-packs + + - name: Run test + run: yarn ci:test + working-directory: npm/ng-packs + + - name: Build dev-app + run: yarn build --prod working-directory: npm/ng-packs + + - name: Install packages of app template + run: yarn install + working-directory: templates/app/angular + + - name: Build app template + run: yarn build --prod + working-directory: templates/app/angular diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 395f88351a..366972c165 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@master with: - dotnet-version: 3.1.100 + dotnet-version: 3.1.102 - name: Build All run: .\build-all.ps1 diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 5b0a2a78cb..6e3c1df3ce 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -191,6 +191,9 @@ "Enum:Status:2": "Approved", "Summary": "Summary", "AuthorName": "Author name", - "CoverImage": "Cover Image" + "CoverImage": "Cover Image", + "RemoveCacheConfirmationMessage": "Are you sure you remove the cache for \"{0}\" article?", + "SuccessfullyRemoved": "Successfully cleared", + "RemoveCache": "Remove Cache" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index a6ee47e253..d6f334f7cd 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -26,6 +26,7 @@ "ContributionGuide": "Contribution Guide", "Blog": "Blog", "Commercial": "Commercial", + "MyAccount": "My account", "SeeDocuments": "See Documents" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json index 9451e616ff..286346a5b5 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json @@ -64,15 +64,12 @@ "CoverImage": "Cover Image", "ShareYourExperiencesWithTheABPFramework": "Share your experiences with the ABP Framework!", "Optional": "Optional", - "UpdateUserNameInfo": "Name", - "UpdateUserSurnameInfo": "Surname", - "UpdateUserWebSiteInfo": "Example: https://abp.io", - "UpdateUserTwitterInfo": "Example: abpframework", - "UpdateUserGithubInfo": "Example: volosoft", - "UpdateUserLinkedinInfo": "Example: https://www.linkedin.com/company/volosoft", - "UpdateUserCompanyInfo": "Example: Volosoft Computer & Technology", - "UpdateUserJobTitleInfo": "Example: Software Engineer Intern", - "UpdateUserBiographyInfo": "About you", + "UpdateUserWebSiteInfo": "Example: https://johndoe.com", + "UpdateUserTwitterInfo": "Example: johndoe", + "UpdateUserGithubInfo": "Example: johndoe", + "UpdateUserLinkedinInfo": "Example: https://www.linkedin.com/...", + "UpdateUserCompanyInfo": "Example: Volosoft", + "UpdateUserJobTitleInfo": "Example: Software Developer", "UserName": "UserName", "Company": "Company", "PersonalWebsite": "Personal Website", @@ -81,9 +78,10 @@ "Biography": "Biography", "HasNoPublishedArticlesYet": "has no published articles yet", "Author": "Author", - "MyAccount": "My account", - "LatestGithubAnnouncements": "Latest Github Announcements", + "LatestGithubAnnouncements": "Latest Github Announcements", "SeeAllAnnouncements": "See All Announcements", - "LatestBlogPost": "Latest Blog Post" + "LatestBlogPost": "Latest Blog Post", + "Edit": "Edit", + "ProfileImageChange": "Change the profile image" } } diff --git a/common.props b/common.props index 4855f1cd9c..a22af0116f 100644 --- a/common.props +++ b/common.props @@ -1,16 +1,16 @@ latest - 3.1.0 - $(NoWarn);CS1591 + 3.2.0 + $(NoWarn);CS1591;CS0436 https://abp.io/assets/abp_nupkg.png https://abp.io/ - LICENSE.md + LGPL-3.0-only git https://github.com/abpframework/abp/ + true - \ No newline at end of file diff --git a/common.test.props b/common.test.props index e90103e606..233afe8282 100644 --- a/common.test.props +++ b/common.test.props @@ -1,7 +1,7 @@ latest - $(NoWarn);CS1591 + $(NoWarn);CS1591;CS0436 true false false diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md index 4b7502f437..eef4237039 100644 --- a/docs/en/Authorization.md +++ b/docs/en/Authorization.md @@ -80,6 +80,8 @@ namespace Acme.BookStore.Permissions > ABP automatically discovers this class. No additional configuration required! +> You typically define this class inside the `Application.Contracts` project of your [application](Startup-Templates/Application.md). The startup template already comes with an empty class named *YourProjectNamePermissionDefinitionProvider* that you can start with. + 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: @@ -276,14 +278,24 @@ public async Task CreateAsync(CreateAuthorDto input) > 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. -### Check a Permission in JavaScript +## Check a Permission in JavaScript + +You may need to check a policy/permission on the client side. + +### MVC UI -You may need to check a policy/permission on the client side. For ASP.NET Core MVC / Razor Pages applications, you can use the `abp.auth` API. Example: +For ASP.NET Core MVC / Razor Pages applications, you can use the `abp.auth` API. + +**Example: Check if a given permission has been granted for the current user** ```js abp.auth.isGranted('MyPermissionName'); ``` +### Angular UI + +See the [permission management document](UI/Angular/Permission-Management.md) for the Angular UI. + ## Permission Management Permission management is normally done by an admin user using the permission management modal: @@ -374,7 +386,7 @@ Configure(options => ### Permission Store -`IPermissionStore` is the only interface that needs to be implemented to read the value of permissions from a persistence source, generally a database system. Permission management module implements it. See the [permission management module documentation](Modules/Permission-Management.md) for more information +`IPermissionStore` is the only interface that needs to be implemented to read the value of permissions from a persistence source, generally a database system. The Permission Management module implements it and pre-installed in the application startup template. See the [permission management module documentation](Modules/Permission-Management.md) for more information ### AlwaysAllowAuthorizationService diff --git a/docs/en/Blog-Posts/2020-09-03 v3_1_Release_Stable/POST.md b/docs/en/Blog-Posts/2020-09-03 v3_1_Release_Stable/POST.md new file mode 100644 index 0000000000..fdbeb08c0d --- /dev/null +++ b/docs/en/Blog-Posts/2020-09-03 v3_1_Release_Stable/POST.md @@ -0,0 +1,62 @@ +# ABP Framework 3.1 Final Has Been Released + +It is exciting for us to announce that we've released the ABP Framework & ABP Commercial 3.1 today. + +Since all the new features are already explained in details with the [3.1 RC Announcement Post](https://blog.abp.io/abp/ABP-Framework-v3.1-RC-Has-Been-Released), I will not repeat all the details here. Please read [the RC post](https://blog.abp.io/abp/ABP-Framework-v3.1-RC-Has-Been-Released) for **new feature and changes** you may need to do for your solution while upgrading to the version 3.1. + +## Creating New Solutions + +You can create a new solution with the ABP Framework version 3.1 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started). + +> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details. + +## How to Upgrade an Existing Solution + +### Install/Update the ABP CLI + +First of all, install the ABP CLI or upgrade to the latest version. + +If you haven't installed yet: + +````bash +dotnet tool install -g Volo.Abp.Cli +```` + +To update an existing installation: + +```bash +dotnet tool update -g Volo.Abp.Cli +``` + +### ABP UPDATE Command + +[ABP CLI](https://docs.abp.io/en/abp/latest/CLI) provides a handy command to update all the ABP related NuGet and NPM packages in your solution with a single command: + +````bash +abp update +```` + +After the update command, check [the RC blog post](https://blog.abp.io/abp/ABP-Framework-v3.1-RC-Has-Been-Released) to learn if you need to make any changes in your solution. + +> You may want to see the new [upgrading document](https://docs.abp.io/en/abp/latest/Upgrading). + +## About the version 3.2 + +The planned schedule for the version 3.2 is like that; + +* **September 17, 2020**: 3.2.0-rc.1 (release candidate) +* **October 1, 2020**: 3.2.0 final (stable) + +You can check [the GitHub milestone](https://github.com/abpframework/abp/milestone/39) to see the features/issues we are working on. + +## ABP Community & Articles + +We had lunched the [ABP Community web site](https://community.abp.io/) a few weeks before. The core ABP team and the ABP community have started to create content for the community. + +Here, the last three articles from the ABP Community: + +* [ABP Suite: How to Add the User Entity as a Navigation Property of Another Entity](https://community.abp.io/articles/abp-suite-how-to-add-the-user-entity-as-a-navigation-property-of-another-entity-furp75ex) by [@ebicoglu](https://github.com/ebicoglu) +* [Reuse ABP vNext Modules to Quickly Implement Application Features](https://community.abp.io/articles/reuse-abp-vnext-modules-to-quickly-implement-application-features-tdtmwd9w) by [@gdlcf88](https://github.com/gdlcf88) +* [Using DevExtreme Components With the ABP Framework](https://community.abp.io/articles/using-devextreme-components-with-the-abp-framework-zb8z7yqv) by [@cotur](https://github.com/cotur). + +We are looking for your contributions; You can [submit your article](https://community.abp.io/articles/submit)! We will promote your article to the community. \ No newline at end of file diff --git a/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/POST.md b/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/POST.md index d16540872f..09df3a2119 100644 --- a/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/POST.md +++ b/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/POST.md @@ -1,8 +1,8 @@ # Introducing the Angular Service Proxy Generation -Angular Service Proxy System **generates TypeScript services and models** to consume your backend HTTP APIs developed using the ABP Framework. So, you **don't manually create** models for your server side DTOs and perform raw HTTP calls to the server. +ABP Angular Service Proxy System **generates TypeScript services and models** to consume your backend HTTP APIs developed using the ABP Framework. So, you **don't manually create** models for your server side DTOs and perform raw HTTP calls to the server. -ABP Framework has introduced the **new** Angular Service Proxy Generation system with the version 3.1. While this feature was available since the [v2.3](https://blog.abp.io/abp/ABP-Framework-v2_3_0-Has-Been-Released), it was not well covering some scenarios, like inheritance and generic types and had some known problems. **With the v3.1, we've re-written** it using the [Angular Schematics](https://angular.io/guide/schematics) system. Now, it is much more stable and feature rich. +ABP Framework has introduced the **new** Angular Service Proxy Generation system with the **version 3.1**. While this feature was available since the [v2.3](https://blog.abp.io/abp/ABP-Framework-v2_3_0-Has-Been-Released), it was not well covering some scenarios, like inheritance and generic types and had some known problems. **With the v3.1, we've re-written** it using the [Angular Schematics](https://angular.io/guide/schematics) system. Now, it is much more stable and feature rich. This post introduces the service proxy generation system and highlights some important features. @@ -47,6 +47,15 @@ apis: { `Acme.BookStore` should be replaced by the root namespace of your .NET project. This ensures to not create unnecessary nested folders while creating the service proxy code. This value is `AngularProxyDemo` for the example solution explained below. +* Finally, add the following paths to the `tsconfig.base.json` to have a shortcut while importing proxies: + +```json +"paths": { + "@proxy": ["src/app/proxy/index.ts"], + "@proxy/*": ["src/app/proxy/*"] +} +``` + ## Basic Usage ### Project Creation @@ -139,21 +148,23 @@ abp generate-proxy It should produce an output like the following: ````bash -CREATE src/app/shared/models/books/index.ts (142 bytes) -CREATE src/app/shared/services/books/book.service.ts (437 bytes) ... +CREATE src/app/proxy/books/book.service.ts (446 bytes) +CREATE src/app/proxy/books/models.ts (148 bytes) +CREATE src/app/proxy/books/index.ts (57 bytes) +CREATE src/app/proxy/index.ts (33 bytes) ```` > `generate-proxy` command can take some some optional parameters for advanced scenarios (like [modular development](https://docs.abp.io/en/abp/latest/Module-Development-Basics)). You can take a look at the [documentation](https://docs.abp.io/en/abp/latest/UI/Angular/Service-Proxies). -It basically creates two files; +#### The Generated Code -src/app/shared/services/books/**book.service.ts**: This is the service that can be injected and used to get the list of books; +`src/app/proxy/books/book.service.ts`: This is the service that can be injected and used to get the list of books; -````typescript +````js +import type { BookDto } from './models'; import { RestService } from '@abp/ng.core'; import { Injectable } from '@angular/core'; -import type { BookDto } from '../../models/book'; @Injectable({ providedIn: 'root', @@ -170,12 +181,11 @@ export class BookService { constructor(private restService: RestService) {} } - ```` -src/app/shared/models/books/**index.ts**: This file contains the modal classes corresponding to the DTOs defined in the server side; +`src/app/proxy/books/models.ts`: This file contains the modal classes corresponding to the DTOs defined in the server side; -````typescript +````js import type { EntityDto } from '@abp/ng.core'; export interface BookDto extends EntityDto { @@ -184,7 +194,21 @@ export interface BookDto extends EntityDto { } ```` -You can now inject the `BookService` into any Angular component and use the `getList()` method to get the list of books. +> There are a few more files have been generated to help you import the types easier. + +#### How to Import + +You can now import the `BookService` into any Angular component and use the `getList()` method to get the list of books. + +````js +import { BookService, BookDto } from '../proxy/books'; +```` + +You can also use the `@proxy` as a shortcut of the proxy folder: + +````js +import { BookService, BookDto } from '@proxy/books'; +```` ### About the Generated Code @@ -235,27 +259,20 @@ namespace AngularProxyDemo.Books } ``` -Let's re-run the `generate-proxy` command to see the result: - -```` -abp generate-proxy -```` - -The output of this command will be like the following: +Let's re-run the `generate-proxy` command: ````bash -UPDATE src/app/shared/services/books/book.service.ts (660 bytes) -UPDATE src/app/shared/models/books/index.ts (217 bytes) +abp generate-proxy ```` -It tells us two files have been updated. Let's see the changes; +This command will re-generate the proxies by updating some files. Let's see some of the changes; **book.service.ts** -````typescript +````js +import type { BookDto, BookUpdateDto } from './models'; import { RestService } from '@abp/ng.core'; import { Injectable } from '@angular/core'; -import type { BookDto, BookUpdateDto } from '../../models/books'; @Injectable({ providedIn: 'root', @@ -284,7 +301,7 @@ export class BookService { `update` function has been added to the `BookService` that gets an `id` and a `BookUpdateDto` as the parameters. -**index.ts** +**models.ts** ````typescript import type { EntityDto } from '@abp/ng.core'; @@ -358,14 +375,14 @@ namespace AngularProxyDemo.Orders } ```` -When I run the `abp generate-proxy` command again, I see two new files have been created. +When I run the `abp generate-proxy` command again, I see there are some created and updated files. Let's see some important ones; -src/app/shared/services/orders/**order.service.ts** +`src/app/proxy/orders/order.service.ts` -````typescript +````js +import type { OrderCreateDto } from './models'; import { RestService } from '@abp/ng.core'; import { Injectable } from '@angular/core'; -import type { OrderCreateDto } from '../../models/orders'; @Injectable({ providedIn: 'root', @@ -385,16 +402,19 @@ export class OrderService { } ```` -src/app/shared/models/orders/**index.ts** +`src/app/proxy/orders/models.ts` ````typescript -import type { GenericDetailDto } from '../../models/orders'; +export interface GenericDetailDto { + productId: string; + count: TCount; +} export interface OrderCreateDto { customerId: string; creationTime: string; details: OrderDetailDto[]; - extraProperties: string | object; + extraProperties: Record; } export interface OrderDetailDto extends GenericDetailDto { @@ -402,4 +422,10 @@ export interface OrderDetailDto extends GenericDetailDto { } ```` -NOTE: 3.1.0-rc2 was generating the code above, which is wrong. It will be fixed in the next RC versions. \ No newline at end of file +## Conclusion + +`abp generate-proxy` is a very handy command that creates all the necessary code to consume your ABP based backend HTTP APIs. It generates a clean code that is well aligned to the backend services and benefits from the power of TypeScript (by using generics, inheritance...). + +## The Documentation + +See [the documentation](https://docs.abp.io/en/abp/latest/UI/Angular/Service-Proxies) for details of the Angular Service Proxy Generation. \ No newline at end of file diff --git a/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/abp-generate-proxy-output.png b/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/abp-generate-proxy-output.png deleted file mode 100644 index 0a77d8e40f..0000000000 Binary files a/docs/en/Blog-Posts/2020-09-07 Angular-Service-Proxies/abp-generate-proxy-output.png and /dev/null differ diff --git a/docs/en/CLI.md b/docs/en/CLI.md index e6e7fcccf8..8ea20ffd57 100644 --- a/docs/en/CLI.md +++ b/docs/en/CLI.md @@ -31,6 +31,7 @@ Here, the list of all available commands before explaining their details: * **`update`**: Automatically updates all ABP related NuGet and NPM packages in a solution. * **`add-package`**: Adds an ABP package to a project. * **`add-module`**: Adds a [multi-package application module](https://docs.abp.io/en/abp/latest/Modules/Index) to a solution. +* **`get-source`**: Downloads the source code of a module. * **`generate-proxy`**: Generates client side proxies to use HTTP API endpoints. * **`remove-proxy`**: Removes previously generated client side proxies. * **`switch-to-preview`**: Switches to the latest preview version of the ABP Framework. @@ -85,6 +86,8 @@ abp new Acme.BookStore * `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios. * `angular`: Angular. There are some additional options for this template: * `--separate-identity-server`: Separates the identity server application from the API host application. If not specified, you will have a single endpoint in the server side. + * `blazor`: Blazor. There are some additional options for this template: + * `--separate-identity-server`: Separates the identity server application from the API host application. If not specified, you will have a single endpoint in the server side. * `none`: Without UI. There are some additional options for this template: * `--separate-identity-server`: Separates the identity server application from the API host application. If not specified, you will have a single endpoint in the server side. * `--mobile` or `-m`: Specifies the mobile application framework. If not specified, no mobile application will be created. Available options: @@ -178,6 +181,31 @@ abp add-module Volo.Blogging * `-sp` or `--startup-project`: Relative path to the project folder of the startup project. Default value is the current folder. * `--with-source-code`: Add source code of the module instead of NuGet/NPM packages. +### get-source + +Downloads the source code of a module to your computer. + +Usage + +````bash +abp get-source [options] +```` + +Example: + +```bash +abp get-source Volo.Blogging + +abp get-source Volo.Blogging --local-framework-ref --abp-path D:\GitHub\abp +``` + +#### Options + +* `--output-folder` or `-o`: Specifies the directory that source code will be downloaded in. If not specified, current directory is used. +* `--version` or `-v`: Specifies the version of the source code that will be downloaded. If not specified, latest version is used. +* `--preview`: If no version option is specified, this option specifies if latest [preview version](Previews.md) will be used instead of latest stable version. +* `-- local-framework-ref --abp-path`: Path of [ABP Framework GitHub repository](https://github.com/abpframework/abp) in your computer. This will be used for converting project references to your local system. If this is not specified, project references will be converted to NuGet references. + ### generate-proxy Generates Angular service proxies for your HTTP APIs to make easy to consume your services from the client side. Your host (server) application must be up and running before running this command. @@ -191,6 +219,7 @@ abp generate-proxy #### Options * `--module` or `-m`: Specifies the name of the backend module you wish to generate proxies for. Default value: `app`. +* `--api-name` or `-a`: The name of the API endpoint defined in the `/src/environments/environment.ts`. Default value: `default`. * `--source` or `-s`: Specifies the Angular project name to resolve the root namespace & API definition URL from. Default value: `defaultProject`. * `--target` or `-t`: Specifies the Angular project name to place generated code in. Default value: `defaultProject`. * `--prompt` or `-p`: Asks the options from the command line prompt (for the unspecified options). @@ -212,6 +241,7 @@ abp remove-proxy #### Options * `--module` or `-m`: Specifies the name of the backend module you wish to remove proxies for. Default value: `app`. +* `--api-name` or `-a`: The name of the API endpoint defined in the `/src/environments/environment.ts`. Default value: `default`. * `--source` or `-s`: Specifies the Angular project name to resolve the root namespace & API definition URL from. Default value: `defaultProject`. * `--target` or `-t`: Specifies the Angular project name to place generated code in. Default value: `defaultProject`. * `--prompt` or `-p`: Asks the options from the command line prompt (for the unspecified options). diff --git a/docs/en/Community-Articles/2020-08-07-Passwordless-Authentication/POST.md b/docs/en/Community-Articles/2020-08-07-Passwordless-Authentication/POST.md index 1b7cef0867..b31ea023f2 100644 --- a/docs/en/Community-Articles/2020-08-07-Passwordless-Authentication/POST.md +++ b/docs/en/Community-Articles/2020-08-07-Passwordless-Authentication/POST.md @@ -2,15 +2,17 @@ ## Introduction -To allow a user login with a magic URL, you need to implement a custom token provider. In this tutorial, we will show you how to add a custom token provider to authenticate a user with a link, instead of entering a password. +In this tutorial, we will show you how to add a custom token provider to authenticate a user with a link, instead of entering the password. + +This can be useful especially if you want to make someone login to the application with your user, without sharing your secret password. The generated link will be for a single use. ### Source Code -The completed sample is available on [the GitHub repository](https://github.com/abpframework/abp-samples/tree/master/PasswordlessAuthentication). +The completed sample is available on [GitHub repository](https://github.com/abpframework/abp-samples/tree/master/PasswordlessAuthentication). ## Creating the Solution -Before starting to the development, create a new solution named `PasswordlessAuthentication` and run it by following the [getting started tutorial](https://docs.abp.io/en/abp/latest/Getting-Started?UI=MVC&DB=EF&Tiered=No). +Before starting the development, create a new solution named `PasswordlessAuthentication` and run it by following the [getting started tutorial](https://docs.abp.io/en/abp/latest/Getting-Started?UI=MVC&DB=EF&Tiered=No). ## Step-1 @@ -155,36 +157,33 @@ Open your **Index.cshtml** and set the content as below. We added a form that po ```html @page -@inject IHtmlLocalizer L -@using Microsoft.AspNetCore.Mvc.Localization -@using PasswordlessAuthentication.Localization -@using PasswordlessAuthentication.Web.Menus +@using MyBookStore.Web.Menus @using Volo.Abp.AspNetCore.Mvc.UI.Layout -@model PasswordlessAuthentication.Web.Pages.IndexModel - +@model MyBookStore.Web.Pages.IndexModel +@using Microsoft.AspNetCore.Mvc.Localization +@using MyBookStore.Localization +@inject IHtmlLocalizer L @{ ViewBag.PageTitle = "Home"; } -@inject IPageLayout PageLayout; +@inject IPageLayout PageLayout @{ PageLayout.Content.Title = L["Home"].Value; PageLayout.Content.BreadCrumb.Add(L["Menu:Home"].Value); - PageLayout.Content.MenuItemName = PasswordlessAuthenticationMenus.Home; + PageLayout.Content.MenuItemName = MyBookStoreMenus.Home; } -
- + Generate passwordless token link @if (Model.PasswordlessLoginUrl != null) { - [@Model.PasswordlessLoginUrl](/en/commercial/latest/how-to/@Model.PasswordlessLoginUrl) + @Model.PasswordlessLoginUrl } -
@@ -273,4 +272,4 @@ That's all! We created a passwordless login with 7 steps. ## Source Code -The completed sample is available on [the GitHub repository](https://github.com/abpframework/abp-samples/tree/master/PasswordlessAuthentication). \ No newline at end of file +The completed sample is available on [GitHub repository](https://github.com/abpframework/abp-samples/tree/master/PasswordlessAuthentication). \ No newline at end of file diff --git a/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/POST.md b/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/POST.md index 039491e10f..7bfd20637f 100644 --- a/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/POST.md +++ b/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/POST.md @@ -1,20 +1,34 @@ -# How to add the user entity as a navigation property? +# ABP Suite: How to Add the User Entity as a Navigation Property of Another Entity -In this post, I'll show you how to add the user as a navigation property in your new entity. +## Introduction -To do this, open the ABP Suite. Create a new entity called `Note`. +[ABP Suite](https://commercial.abp.io/tools/suite), a part of the [ABP Commercial](https://commercial.abp.io/), is a productivity tool developed by the team behind the ABP Framework. The main functionality of the ABP Suite is to generate code for you. + +In this post, I'll show you how to add the user entity as a navigation property in your new entity, by the help of the ABP Suite. + +> In the sample project MVC UI is used, but the same steps are applicable to the Angular UI as well. + +## Code Generation + +### Create a New Entity + +Open the ABP Suite ([see how](https://docs.abp.io/en/commercial/latest/abp-suite/index)). Create a new entity called `Note`, as an example entity. ![create-note-entity](create-note-entity.jpg) -Then add a string property called `Title`. +Then add a string property called `Title`, as an example property. ![add-simple-property](add-simple-property.jpg) -To be able to add a user navigation, we need to create a user DTO to map from entity. To do this, create a new folder called "Users" in `*.Application.Contracts` then add a new class called `AppUserDto` inherited from `IdentityUserDto`. +### Create AppUserDto + +ABP Suite needs a DTO for the target entity (user, in this case) in order to define a navigation property. + +To do this, create a new folder called "Users" in `*.Application.Contracts` then add a new class called `AppUserDto` inherited from `IdentityUserDto`. ![create-appuserdto](create-appuserdto.jpg) -Create the mapping for `AppUserDto`. To do this, open `YourProjectApplicationAutoMapperProfile.cs` and add the below line: +We should define the [object mapping](https://docs.abp.io/en/abp/latest/Object-To-Object-Mapping) to be able to convert the `AppUser` objects to `AppUserDto` objects. To do this, open `YourProjectApplicationAutoMapperProfile.cs` and add the below line: ```csharp CreateMap().Ignore(x => x.ExtraProperties); @@ -22,28 +36,46 @@ CreateMap().Ignore(x => x.ExtraProperties); ![create-mapping](create-mapping.jpg) -Get back to ABP Suite, go to **Navigation Properties** tab. Click **Add Navigation Property** button. Browse `AppUser.cs` in `*.Domain\Users` folder. Then choose the `Name` item as display property. Browse `AppUserDto.cs` in `*.Contracts\Users` folder. Choose `Users` from Collection Names dropdown. +> Creating such a DTO class may not be needed for another entity than the `AppUser`, since it will probably be already available, especially if you had created the other entity using the ABP Suite. + +### Define the Navigation Property + +Get back to ABP Suite, open the **Navigation Properties** tab of the ABP Suite, click the **Add Navigation Property** button. Browse `AppUser.cs` in `*.Domain\Users` folder. Then choose the `Name` item as display property. Browse `AppUserDto.cs` in `*.Contracts\Users` folder. Choose `Users` from Collection Names dropdown. ![add-user-navigation](add-user-navigation.jpg) -That's it! Click **Save and generate** button to create your page. You'll see the following page if there's everything goes well. +### Generate the Code! + +That's it! Click **Save and generate** button to create your page. You'll see the following page if everything goes well. ![final-page](final-page.jpg) +This is the new page that has been created by the ABP Suite. It can perform the fundamental CRUD operations. Also, it has the "App user" column that shows the related user name (you can easily change the automatically created "App user" title from the **Entity Name** field of the navigation property creation screen). + +**Picking Users from Look Up Table** + +We used dropdown element to select a user from the user list. If you have a lot of users, then it's good to pick a user from a look up table. A look up table is a modal window that lets you filter data and pick one. To do this, get back to Suite and click **Edit** button of user navigation which is set as `AppUserId` name. Choose "Modal" from the "UI Pick Type" field. Then click **Save and generate** button to recreate your page. + +![ui-pick-type-modal](ui-pick-type-modal.jpg) + +After successful code generation, you'll see the the user can be picked from user table. + +![ui-pick-type-modal2](ui-pick-type-modal2.jpg) +## About the ABP Commercial RC -Note this example is implemented with ABP Commercial 3.1.0-rc.3. This is a RC version. If you want to install the CLI and Suite RC version follow the next steps: +This example has been implemented with **ABP Commercial 3.1.0**. If you have not installed the ABP CLI and ABP Suite, follow the next steps: -1- Uninstall the current version of the CLI and install the specific RC version: +1- Uninstall the current version of the CLI and install: ```bash -dotnet tool uninstall --global Volo.Abp.Cli && dotnet tool install --global Volo.Abp.Cli --version 3.1.0-rc.3 +dotnet tool install --global Volo.Abp.Cli --version 3.1.0 ``` -2- Uninstall the current version of the Suite and install the specific RC version: +2- Uninstall the current version of the Suite and install: ```bash -dotnet tool uninstall --global Volo.Abp.Suite && dotnet tool install -g Volo.Abp.Suite --version 3.1.0-rc.3 --add-source https://nuget.abp.io//v3/index.json +dotnet tool uninstall --global Volo.Abp.Suite && dotnet tool install -g Volo.Abp.Suite --version 3.1.0 --add-source https://nuget.abp.io//v3/index.json ``` -Don't forget to replace the `` with your own key! \ No newline at end of file +Don't forget to replace the `` with your own key! diff --git a/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/ui-pick-type-modal.jpg b/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/ui-pick-type-modal.jpg new file mode 100644 index 0000000000..dcff62e742 Binary files /dev/null and b/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/ui-pick-type-modal.jpg differ diff --git a/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/ui-pick-type-modal2.jpg b/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/ui-pick-type-modal2.jpg new file mode 100644 index 0000000000..d04aec570b Binary files /dev/null and b/docs/en/Community-Articles/2020-08-31-Adding-User-Navigation-In-Suite/ui-pick-type-modal2.jpg differ diff --git a/docs/en/Data-Filtering.md b/docs/en/Data-Filtering.md index 85f094b614..62021452bd 100644 --- a/docs/en/Data-Filtering.md +++ b/docs/en/Data-Filtering.md @@ -151,11 +151,21 @@ public class Book : AggregateRoot, IIsActive ABP uses [EF Core's Global Query Filters](https://docs.microsoft.com/en-us/ef/core/querying/filters) system for the [EF Core Integration](Entity-Framework-Core.md). So, it is well integrated to EF Core and works as expected even if you directly work with `DbContext`. -Best way to implement a custom filter is to override `CreateFilterExpression` method for your `DbContext`. Example: +Best way to implement a custom filter is to override `ShouldFilterEntity` and `CreateFilterExpression` method for your `DbContext`. Example: ````csharp protected bool IsActiveFilterEnabled => DataFilter?.IsEnabled() ?? false; +protected override bool ShouldFilterEntity(IMutableEntityType entityType) +{ + if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity))) + { + return true; + } + + return base.ShouldFilterEntity(entityType); +} + protected override Expression> CreateFilterExpression() { var expression = base.CreateFilterExpression(); @@ -174,7 +184,7 @@ protected override Expression> CreateFilterExpression The feature system is implemented with the [Volo.Abp.Features](https://www.nuget.org/packages/Volo.Abp.Features) NuGet package. Most of the times you don't need to manually [install it](https://abp.io/package-detail/Volo.Abp.Features) since it comes pre-installed with the [application startup template](Startup-Templates/Application.md). + +## Checking for the Features + +Before explaining to define features, let's see how to check a feature value in your application code. + +### RequiresFeature Attribute + +`[RequiresFeature]` attribute (defined in the `Volo.Abp.Features` namespace) is used to declaratively check if a feature is `true` (enabled) or not. It is a useful shortcut for the `boolean` features. + +**Example: Check if the "PDF Reporting" feature enabled** + +```csharp +public class ReportingAppService : ApplicationService, IReportingAppService +{ + [RequiresFeature("MyApp.PdfReporting")] + public async Task GetPdfReportAsync() + { + //TODO... + } +} +``` + +* `RequiresFeature(...)` simply gets a feature name to check if it is enabled or not. If not enabled, an authorization [exception](Exception-Handling.md) is thrown and a proper response is returned to the client side. +* `[RequiresFeature]` can be used for a **method** or a **class**. When you use it for a class, all the methods of that class require the given feature. +* `RequiresFeature` may get multiple feature names, like `[RequiresFeature("Feature1", "Feature2")]`. In this case ABP checks if any of the features enabled. Use `RequiresAll` option, like `[RequiresFeature("Feature1", "Feature2", RequiresAll = true)]` to force to check all of the features to be enabled. +* Multiple usage of `[RequiresFeature]` attribute is supported for a method or class. ABP check checks all of them in that case. + +> Feature name can be any arbitrary string. It should be unique for a feature. + +#### About the Interception + +ABP Framework uses the interception system to make the `[RequiresFeature]` attribute working. So, it can work with any class (application services, controllers...) that is injected from the [dependency injection](Dependency-Injection.md). + +However, there are **some rules should be followed** in order to make it working; + +* If you are **not injecting** the service over an interface (like `IMyService`), then the methods of the service must be `virtual`. Otherwise, [dynamic proxy / interception](Dynamic-Proxying-Interceptors.md) system can not work. +* Only `async` methods (methods returning a `Task` or `Task`) are intercepted. + +> There is an exception for the **controller and razor page methods**. They **don't require** the following the rules above, since ABP Framework uses the action/page filters to implement the feature checking in this case. + +### IFeatureChecker Service + +`IFeatureChecker` allows to check a feature in your application code. + +#### IsEnabledAsync + +Returns `true` if the given feature is enabled. So, you can conditionally execute your business flow. + +**Example: Check if the "PDF Reporting" feature enabled** + +```csharp +public class ReportingAppService : ApplicationService, IReportingAppService +{ + private readonly IFeatureChecker _featureChecker; + + public ReportingAppService(IFeatureChecker featureChecker) + { + _featureChecker = featureChecker; + } + + public async Task GetPdfReportAsync() + { + if (await _featureChecker.IsEnabledAsync("MyApp.PdfReporting")) + { + //TODO... + } + else + { + //TODO... + } + } +} +``` + +`IsEnabledAsync` has overloads to check multiple features in one method call. + +#### GetOrNullAsync + +Gets the current value for a feature. This method returns a `string`, so you store any kind of value inside it, by converting to or from `string`. + +**Example: Check the maximum product count allowed** + +```csharp +public class ProductController : AbpController +{ + private readonly IFeatureChecker _featureChecker; + + public ProductController(IFeatureChecker featureChecker) + { + _featureChecker = featureChecker; + } + + public async Task Create(CreateProductModel model) + { + var currentProductCount = await GetCurrentProductCountFromDatabase(); + + //GET THE FEATURE VALUE + var maxProductCountLimit = + await _featureChecker.GetOrNullAsync("MyApp.MaxProductCount"); + + if (currentProductCount >= Convert.ToInt32(maxProductCountLimit)) + { + throw new BusinessException( + "MyApp:ReachToMaxProductCountLimit", + $"You can not create more than {maxProductCountLimit} products!" + ); + } + + //TODO: Create the product in the database... + } + + private async Task GetCurrentProductCountFromDatabase() + { + throw new System.NotImplementedException(); + } +} +``` + +This example uses a numeric value as a feature limit product counts for a user/tenant in a SaaS application. + +Instead of manually converting the value to `int`, you can use the generic overload of the `GetAsync` method: + +```csharp +var maxProductCountLimit = await _featureChecker.GetAsync("MyApp.MaxProductCount"); +``` + +#### Extension Methods + +There are some useful extension methods for the `IFeatureChecker` interface; + +* `Task GetAsync(string name, T defaultValue = default)`: Used to get a value of a feature with the given type `T`. Allows to specify a `defaultValue` that is returned when the feature value is `null`. +* `CheckEnabledAsync(string name)`: Checks if given feature is enabled. Throws an `AbpAuthorizationException` if the feature was not `true` (enabled). + +## Defining the Features + +A feature should be defined to be able to check it. + +### FeatureDefinitionProvider + +Create a class inheriting the `FeatureDefinitionProvider` to define permissions. + +**Example: Defining permissions** + +```csharp +using Volo.Abp.Features; + +namespace FeaturesDemo +{ + public class MyFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var myGroup = context.AddGroup("MyApp"); + + myGroup.AddFeature("MyApp.PdfReporting", defaultValue: "false"); + myGroup.AddFeature("MyApp.MaxProductCount", defaultValue: "10"); + } + } +} +``` + +> ABP automatically discovers this class and registers the features. No additional configuration required. + +> This class is generally created in the `Application.Contracts` project of your solution. + +* In the `Define` method, you first need to add a **feature group** for your application/module or get an existing group then add **features** to this group. +* First feature, named `MyApp.PdfReporting`, is a `boolean` feature with `false` as the default value. +* Second feature, named `MyApp.MaxProductCount`, is a numeric feature with `10` as the default value. + +Default value is used if there is no other value set for the current user/tenant. + +### Other Feature Properties + +While these minimal definitions are enough to make the feature system working, you can specify the **optional properties** for the features; + +* `DisplayName`: A localizable string that will be used to show the feature name on the user interface. +* `Description`: A longer localizable text to describe the feature. +* `ValueType`: Type of the feature value. Can be a class implementing the `IStringValueType`. Built-in types: + * `ToggleStringValueType`: Used to define `true`/`false`, `on`/`off`, `enabled`/`disabled` style features. A checkbox is shown on the UI. + * `FreeTextStringValueType`: Used to define free text values. A textbox is shown on the UI. + * `SelectionStringValueType`: Used to force the value to be selected from a list. A dropdown list is shown on the UI. +* `IsVisibleToClients` (default: `true`): Set false to hide the value of this feature from clients (browsers). Sharing the value with the clients helps them to conditionally show/hide/change the UI parts based on the feature value. +* `Properties`: A dictionary to set/get arbitrary key-value pairs related to this feature. This can be a point for customization. + +So, based on these descriptions, it would be better to define these features as shown below: + +```csharp +using FeaturesDemo.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; +using Volo.Abp.Validation.StringValues; + +namespace FeaturesDemo +{ + public class MyFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var myGroup = context.AddGroup("MyApp"); + + myGroup.AddFeature( + "MyApp.PdfReporting", + defaultValue: "false", + displayName: LocalizableString + .Create("PdfReporting"), + valueType: new ToggleStringValueType() + ); + + myGroup.AddFeature( + "MyApp.MaxProductCount", + defaultValue: "10", + displayName: LocalizableString + .Create("MaxProductCount"), + valueType: new FreeTextStringValueType( + new NumericValueValidator(0, 1000000)) + ); + } + } +} +``` + +* `FeaturesDemoResource` is the project name in this example code. See the [localization document](Localization.md) for details about the localization system. +* First feature is set to `ToggleStringValueType`, while the second one is set to `FreeTextStringValueType` with a numeric validator that allows to the values from `0` to `1,000,000`. + +Remember to define the localization the keys in your localization file: + +````json +"PdfReporting": "PDF Reporting", +"MaxProductCount": "Maximum number of products" +```` + +See the [localization document](Localization.md) for details about the localization system. + +### Feature Management Modal + +The [application startup template](Startup-Templates/Application.md) comes with the [tenant management](Modules/Tenant-Management.md) and the [feature management](Modules/Feature-Management.md) modules pre-installed. + +Whenever you define a new feature, it will be available on the **feature management modal**. To open this modal, navigate to the **tenant management page** and select the `Features` action for a tenant (create a new tenant if there is no tenant yet): + +![features-action](images/features-action.png) + +This action opens a modal to manage the feature values for the selected tenant: + +![features-modal](images/features-modal.png) + +So, you can enable, disable and set values for a tenant. These values will be used whenever a user of this tenant uses the application. + +See the *Feature Management* section below to learn more about managing the features. + +### Child Features + +A feature may have child features. This is especially useful if you want to create a feature that is selectable only if another feature was enabled. + +**Example: Defining child features** + +```csharp +using FeaturesDemo.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; +using Volo.Abp.Validation.StringValues; + +namespace FeaturesDemo +{ + public class MyFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var myGroup = context.AddGroup("MyApp"); + + var reportingFeature = myGroup.AddFeature( + "MyApp.Reporting", + defaultValue: "false", + displayName: LocalizableString + .Create("Reporting"), + valueType: new ToggleStringValueType() + ); + + reportingFeature.CreateChild( + "MyApp.PdfReporting", + defaultValue: "false", + displayName: LocalizableString + .Create("PdfReporting"), + valueType: new ToggleStringValueType() + ); + + reportingFeature.CreateChild( + "MyApp.ExcelReporting", + defaultValue: "false", + displayName: LocalizableString + .Create("ExcelReporting"), + valueType: new ToggleStringValueType() + ); + } + } +} +``` + +The example above defines a *Reporting* feature with two children: *PDF Reporting* and *Excel Reporting*. + +### Changing Features Definitions of a Depended Module + +A class deriving from the `FeatureDefinitionProvider` (just like the example above) can also get the existing permission definitions (defined by the depended [modules](Module-Development-Basics.md)) and change their definitions. + +**Example: Manipulate an existing feature definition** + +```csharp +var someGroup = context.GetGroupOrNull("SomeModule"); +var feature = someGroup.Features.FirstOrDefault(f => f.Name == "SomeFeature"); +if (feature != null) +{ + feature.Description = ... + feature.CreateChild(...); +} +``` + +## Check a Feature in the Client Side + +A feature value is available at the client side too, unless you set `IsVisibleToClients` to `false` on the feature definition. The feature values are exposed from the [Application Configuration API](API/Application-Configuration.md) and usable via some services on the UI. + +### ASP.NET Core MVC / Razor Pages UI + +Use `abp.features` API to get the feature values. + +**Example: Get feature values in the JavaScript code** + +````js +var isEnabled = abp.features.values["MyApp.ExcelReporting"] === "true"; +var count = abp.features.values["MyApp.MaxProductCount"]; +```` + +### Angular UI + +See the [features](Features.md) document for the Angular UI. + +## Feature Management + +Feature management is normally done by an admin user using the feature management modal: + +![features-modal](images/features-modal.png) + +This modal is available on the related entities, like tenants in a multi-tenant application. To open it, navigate to the **Tenant Management** page (for a multi-tenant application), click to the **Actions** button left to the Tenant and select the **Features** action. + +If you need to manage features by code, inject the `IFeatureManager` service. + +**Example: Enable PDF reporting for a tenant** + +```csharp +public class MyService : ITransientDependency +{ + private readonly IFeatureManager _featureManager; + + public MyService(IFeatureManager featureManager) + { + _featureManager = featureManager; + } + + public async Task EnablePdfReporting(Guid tenantId) + { + await _featureManager.SetForTenantAsync( + tenantId, + "MyApp.PdfReporting", + true.ToString() + ); + } +} +``` + +`IFeatureManager` is defined by the Feature Management module. It comes pre-installed with the application startup template. See the [feature management module documentation](Modules/Feature-Management.md) for more information. + +## Advanced Topics + +### Feature Value Providers + +Feature system is extensible. Any class derived from `FeatureValueProvider` (or implements `IFeatureValueProvider`) can contribute to the feature system. A value provider is responsible to **obtain the current value** of a given feature. + +Feature value providers are **executed one by one**. If one of them return a non-null value, then this feature value is used and the other providers are not executed. + +There are three pre-defined value providers, executed by the given order: + +* `TenantFeatureValueProvider` tries to get if the feature value is explicitly set for the **current tenant**. +* `EditionFeatureValueProvider` tries to get the feature value for the current edition. Edition Id is obtained from the current principal identity (`ICurrentPrincipalAccessor`) with the claim name `editionid` (a constant defined as`AbpClaimTypes.EditionId`). Editions are not implemented for the [tenant management](Modules/Tenant-Management.md) module. You can implement it yourself or consider to use the [SaaS module](https://commercial.abp.io/modules/Volo.Saas) of the ABP Commercial. +* `DefaultValueFeatureValueProvider` gets the default value of the feature. + +You can write your own provider by inheriting the `FeatureValueProvider`. + +**Example: Enable all features for a user with "SystemAdmin" as a "User_Type" claim value** + +```csharp +using System.Threading.Tasks; +using Volo.Abp.Features; +using Volo.Abp.Security.Claims; +using Volo.Abp.Validation.StringValues; + +namespace FeaturesDemo +{ + public class SystemAdminFeatureValueProvider : FeatureValueProvider + { + public override string Name => "SA"; + + private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor; + + public SystemAdminFeatureValueProvider( + IFeatureStore featureStore, + ICurrentPrincipalAccessor currentPrincipalAccessor) + : base(featureStore) + { + _currentPrincipalAccessor = currentPrincipalAccessor; + } + + public override Task GetOrNullAsync(FeatureDefinition feature) + { + if (feature.ValueType is ToggleStringValueType && + _currentPrincipalAccessor.Principal?.FindFirst("User_Type")?.Value == "SystemAdmin") + { + return Task.FromResult("true"); + } + + return null; + } + } +} +``` + +If a provider returns `null`, then the next provider is executed. + +Once a provider is defined, it should be added to the `AbpFeatureOptions` as shown below: + +```csharp +Configure(options => +{ + options.ValueProviders.Add(); +}); +``` + +Use this code inside the `ConfigureServices` of your [module](Module-Development-Basics.md) class. + +### Feature Store + +`IFeatureStore` is the only interface that needs to be implemented to read the value of features from a persistence source, generally a database system. The Feature Management module implements it and pre-installed in the application startup template. See the [feature management module documentation](https://docs.abp.io/en/abp/latest/Modules/Feature-Management) for more information \ No newline at end of file diff --git a/docs/en/Index.md b/docs/en/Index.md index 5fe44625ad..949c04eb24 100644 --- a/docs/en/Index.md +++ b/docs/en/Index.md @@ -6,9 +6,21 @@ Explore the navigation menu to deep dive in the documentation. ## Getting Started -The easiest way to start a new web application with the ABP Framework is to use the [getting started](Getting-Started.md) tutorial. +The easiest way to start a new web application with the ABP Framework is to use the [getting started](Getting-Started.md) guide. -Then you can continue with the [web application development tutorial](Tutorials/Part-1.md). +## Tutorials / Articles + +### Web Application Development + +[Web application development tutorial](Tutorials/Part-1.md) is a complete tutorial to develop a full stack application using the ABP Framework. + +### ABP Community Articles + +See also the [ABP Community](https://community.abp.io/) articles. + +## Samples + +See the [sample projects](Samples/Index.md) built with the ABP Framework. ## Source Code diff --git a/docs/en/Modules/Feature-Management.md b/docs/en/Modules/Feature-Management.md index 5c41277dd8..968b742092 100644 --- a/docs/en/Modules/Feature-Management.md +++ b/docs/en/Modules/Feature-Management.md @@ -1,3 +1,5 @@ # Feature Management Module +> This module implements the `IFeatureStore` to store and manage feature values in a database. See the [Features System document](../Features.md) to understand the features first. + TODO \ No newline at end of file diff --git a/docs/en/Modules/Identity.md b/docs/en/Modules/Identity.md index b950658505..ac86b13564 100644 --- a/docs/en/Modules/Identity.md +++ b/docs/en/Modules/Identity.md @@ -4,3 +4,26 @@ Identity module is used to manage [organization units](Organization-Units.md), r See [the source code](https://github.com/abpframework/abp/tree/dev/modules/identity). Documentation will come soon... + +## Identity Security Log + +The security log can record some important operations or changes about your account. You can save the security log if needed. + +You can inject and use `IdentitySecurityLogManager` or `ISecurityLogManager` to write security logs. It will create a log object by default and fill in some common values, such as `CreationTime`, `ClientIpAddress`, `BrowserInfo`, `current user/tenant`, etc. Of course, you can override them. + +```cs +await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext() +{ + Identity = "IdentityServer"; + Action = "ChangePassword"; +}); +``` + +Configure `AbpSecurityLogOptions` to provide the application name for the log or disable this feature. **Enabled** by default. + +```cs +Configure(options => +{ + options.ApplicationName = "AbpSecurityTest"; +}); +``` diff --git a/docs/en/Modules/Permission-Management.md b/docs/en/Modules/Permission-Management.md index faa03eecc9..ad48b60171 100644 --- a/docs/en/Modules/Permission-Management.md +++ b/docs/en/Modules/Permission-Management.md @@ -1,3 +1,5 @@ # Permission Management Module +This module implements the `IPermissionStore` to store and manage feature values in a database. See the [Authorization document](../Authorization.md) to understand the authorization and permission systems first. + TODO \ No newline at end of file diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 901a5c5cff..5138c9de04 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -369,3 +369,6 @@ options.AddDomainTenantResolver("{0}.mydomain.com"); options.AddDomainTenantResolver("{0}.com"); ```` +## See Also + +* [Features](Features.md) \ No newline at end of file diff --git a/docs/en/Tutorials/Part-10.md b/docs/en/Tutorials/Part-10.md index 0fa4892298..05ed6e343e 100644 --- a/docs/en/Tutorials/Part-10.md +++ b/docs/en/Tutorials/Part-10.md @@ -376,6 +376,8 @@ namespace Acme.BookStore.Books public override async Task GetAsync(Guid id) { + await CheckGetPolicyAsync(); + //Prepare a query to join books and authors var query = from book in Repository join author in _authorRepository on book.AuthorId equals author.Id @@ -397,6 +399,8 @@ namespace Acme.BookStore.Books public override async Task> GetListAsync(PagedAndSortedResultRequestDto input) { + await CheckGetListPolicyAsync(); + //Prepare a query to join books and authors var query = from book in Repository join author in _authorRepository on book.AuthorId equals author.Id @@ -495,6 +499,8 @@ namespace Acme.BookStore.Books public override async Task GetAsync(Guid id) { + await CheckGetPolicyAsync(); + var book = await Repository.GetAsync(id); var bookDto = ObjectMapper.Map(book); @@ -507,6 +513,8 @@ namespace Acme.BookStore.Books public override async Task> GetListAsync(PagedAndSortedResultRequestDto input) { + await CheckGetListPolicyAsync(); + //Set a default sorting, if not provided if (input.Sorting.IsNullOrWhiteSpace()) { @@ -915,6 +923,149 @@ You can run the application and try to create a new book or update an existing b {{else if UI=="NG"}} -***Angular UI is being prepared...*** +### The Book List + +Book list page change is trivial. Open the `/src/app/book/book.component.html` and add the following column definition between the `Name` and `Type` columns: + +````js + +```` + +When you run the application, you can see the *Author* column on the table: + +![bookstore-books-with-authorname-angular](images/bookstore-books-with-authorname-angular.png) + +### Create/Edit Forms + +The next step is to add an Author selection (dropdown) to the create/edit forms. The final UI will look like the one shown below: + +![bookstore-angular-author-selection](images/bookstore-angular-author-selection.png) + +Added the Author dropdown as the first element in the form. + +Open the `/src/app/book/book.component.ts` and and change the content as shown below: + +````js +import { ListService, PagedResultDto } from '@abp/ng.core'; +import { Component, OnInit } from '@angular/core'; +import { BookService, BookDto, bookTypeOptions, AuthorLookupDto } from '@proxy/books'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'app-book', + templateUrl: './book.component.html', + styleUrls: ['./book.component.scss'], + providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], +}) +export class BookComponent implements OnInit { + book = { items: [], totalCount: 0 } as PagedResultDto; + + form: FormGroup; + + selectedBook = {} as BookDto; + + authors$: Observable; + + bookTypes = bookTypeOptions; + + isModalOpen = false; + + constructor( + public readonly list: ListService, + private bookService: BookService, + private fb: FormBuilder, + private confirmation: ConfirmationService + ) { + this.authors$ = bookService.getAuthorLookup().pipe(map((r) => r.items)); + } + + ngOnInit() { + const bookStreamCreator = (query) => this.bookService.getList(query); + + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); + } + + createBook() { + this.selectedBook = {} as BookDto; + this.buildForm(); + this.isModalOpen = true; + } + + editBook(id: string) { + this.bookService.get(id).subscribe((book) => { + this.selectedBook = book; + this.buildForm(); + this.isModalOpen = true; + }); + } + + buildForm() { + this.form = this.fb.group({ + authorId: [this.selectedBook.authorId || null, Validators.required], + name: [this.selectedBook.name || null, Validators.required], + type: [this.selectedBook.type || null, Validators.required], + publishDate: [ + this.selectedBook.publishDate ? new Date(this.selectedBook.publishDate) : null, + Validators.required, + ], + price: [this.selectedBook.price || null, Validators.required], + }); + } + + save() { + if (this.form.invalid) { + return; + } + + const request = this.selectedBook.id + ? this.bookService.update(this.selectedBook.id, this.form.value) + : this.bookService.create(this.form.value); + + request.subscribe(() => { + this.isModalOpen = false; + this.form.reset(); + this.list.get(); + }); + } + + delete(id: string) { + this.confirmation.warn('::AreYouSureToDelete', 'AbpAccount::AreYouSure').subscribe((status) => { + if (status === Confirmation.Status.confirm) { + this.bookService.delete(id).subscribe(() => this.list.get()); + } + }); + } +} +```` + +* Added imports for the `AuthorLookupDto`, `Observable` and `map`. +* Added `authors$: Observable;` field after the `selectedBook`. +* Added `this.authors$ = bookService.getAuthorLookup().pipe(map((r) => r.items));` into the constructor. +* Added ` authorId: [this.selectedBook.authorId || null, Validators.required],` into the `buildForm()` function. + +Open the `/src/app/book/book.component.html` and add the following form group just before the book name form group: + +````html +
+ * + +
+```` + +That's all. Just run the application and try to create or edit an author. {{end}} \ No newline at end of file diff --git a/docs/en/Tutorials/Part-2.md b/docs/en/Tutorials/Part-2.md index c947f4495d..bcec504886 100644 --- a/docs/en/Tutorials/Part-2.md +++ b/docs/en/Tutorials/Part-2.md @@ -347,9 +347,9 @@ This is a fully working, server side paged, sorted and localized table of books. ## Install NPM packages -> Notice: This tutorial is based on the ABP Framework v3.0.3+ If your project version is older, then please upgrade your solution. See the [migration guide](../UI/Angular/Migration-Guide-v3.md) if you are upgrading an existing project with v2.x. +> Notice: This tutorial is based on the ABP Framework v3.1.0+ If your project version is older, then please upgrade your solution. See the [migration guide](../UI/Angular/Migration-Guide-v3.md) if you are upgrading an existing project with v2.x. -If you haven't done it before, open a new command line interface (terminal window) and go to your `angular` folder and then run `yarn` command to install NPM packages: +If you haven't done it before, open a new command line interface (terminal window) and go to your `angular` folder and then run `yarn` command to install the NPM packages: ```bash yarn @@ -473,9 +473,9 @@ Run the following command in the `angular` folder: abp generate-proxy ``` -The generated files looks like below: +This command will create the following files under the `/src/app/proxy/books` folder: -![Generated files](./images/generated-proxies-2.png) +![Generated files](./images/generated-proxies-3.png) ### BookComponent @@ -484,8 +484,7 @@ Open the `/src/app/book/book.component.ts` file and replace the content as below ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto } from './models'; -import { BookService } from './services'; +import { BookService, BookDto } from '@proxy/books'; @Component({ selector: 'app-book', @@ -499,7 +498,7 @@ export class BookComponent implements OnInit { constructor(public readonly list: ListService, private bookService: BookService) {} ngOnInit() { - const bookStreamCreator = (query) => this.bookService.getListByInput(query); + const bookStreamCreator = (query) => this.bookService.getList(query); this.list.hookToQuery(bookStreamCreator).subscribe((response) => { this.book = response; diff --git a/docs/en/Tutorials/Part-3.md b/docs/en/Tutorials/Part-3.md index 13aa5df8c3..be3dd75d64 100644 --- a/docs/en/Tutorials/Part-3.md +++ b/docs/en/Tutorials/Part-3.md @@ -656,8 +656,7 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto } from './models'; -import { BookService } from './services'; +import { BookService, BookDto } from '@proxy/books'; @Component({ selector: 'app-book', @@ -673,7 +672,7 @@ export class BookComponent implements OnInit { constructor(public readonly list: ListService, private bookService: BookService) {} ngOnInit() { - const bookStreamCreator = (query) => this.bookService.getListByInput(query); + const bookStreamCreator = (query) => this.bookService.getList(query); this.list.hookToQuery(bookStreamCreator).subscribe((response) => { this.book = response; @@ -749,8 +748,8 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto, BookType } from './models'; // add BookType -import { BookService } from './services'; +// import bookTypeOptions from @proxy/books +import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // add this @Component({ @@ -764,12 +763,8 @@ export class BookComponent implements OnInit { form: FormGroup; // add this line - bookType = BookType; // add this line - // add bookTypes as a list of BookType enum members - bookTypes = Object.keys(this.bookType).filter( - (key) => typeof this.bookType[key] === 'number' - ); + bookTypes = bookTypeOptions; isModalOpen = false; @@ -780,7 +775,7 @@ export class BookComponent implements OnInit { ) {} ngOnInit() { - const bookStreamCreator = (query) => this.bookService.getListByInput(query); + const bookStreamCreator = (query) => this.bookService.getList(query); this.list.hookToQuery(bookStreamCreator).subscribe((response) => { this.book = response; @@ -808,7 +803,7 @@ export class BookComponent implements OnInit { return; } - this.bookService.createByInput(this.form.value).subscribe(() => { + this.bookService.create(this.form.value).subscribe(() => { this.isModalOpen = false; this.form.reset(); this.list.get(); @@ -819,7 +814,6 @@ export class BookComponent implements OnInit { * Imported `FormGroup`, `FormBuilder` and `Validators` from `@angular/forms`. * Added `form: FormGroup` property. -* Added `bookType` property so that you can reach `BookType` enum members from template. * Added `bookTypes` property as a list of `BookType` enum members. That will be used in form options. * Injected `FormBuilder` into the constructor. [FormBuilder](https://angular.io/api/forms/FormBuilder) provides convenient methods for generating form controls. It reduces the amount of boilerplate needed to build complex forms. * Added `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method. @@ -844,7 +838,7 @@ Open `/src/app/book/book.component.html` and replace ` Type * @@ -910,8 +904,7 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto, BookType } from './models'; -import { BookService } from './services'; +import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // added this line @@ -931,11 +924,7 @@ export class BookComponent implements OnInit { form: FormGroup; - bookType = BookType; - - bookTypes = Object.keys(this.bookType).filter( - (key) => typeof this.bookType[key] === 'number' - ); + bookTypes = bookTypeOptions; isModalOpen = false; @@ -946,7 +935,7 @@ export class BookComponent implements OnInit { ) {} ngOnInit() { - const bookStreamCreator = (query) => this.bookService.getListByInput(query); + const bookStreamCreator = (query) => this.bookService.getList(query); this.list.hookToQuery(bookStreamCreator).subscribe((response) => { this.book = response; @@ -972,7 +961,7 @@ export class BookComponent implements OnInit { return; } - this.bookService.createByInput(this.form.value).subscribe(() => { + this.bookService.create(this.form.value).subscribe(() => { this.isModalOpen = false; this.form.reset(); this.list.get(); @@ -995,8 +984,7 @@ Open `/src/app/book/book.component.ts` and replace the content as shown below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto, BookType, CreateUpdateBookDto } from './models'; -import { BookService } from './services'; +import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; @@ -1009,15 +997,11 @@ import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap export class BookComponent implements OnInit { book = { items: [], totalCount: 0 } as PagedResultDto; - selectedBook = new BookDto(); // declare selectedBook + selectedBook = {} as BookDto; // declare selectedBook form: FormGroup; - bookType = BookType; - - bookTypes = Object.keys(this.bookType).filter( - (key) => typeof this.bookType[key] === 'number' - ); + bookTypes = bookTypeOptions; isModalOpen = false; @@ -1028,7 +1012,7 @@ export class BookComponent implements OnInit { ) {} ngOnInit() { - const bookStreamCreator = (query) => this.bookService.getListByInput(query); + const bookStreamCreator = (query) => this.bookService.getList(query); this.list.hookToQuery(bookStreamCreator).subscribe((response) => { this.book = response; @@ -1036,14 +1020,14 @@ export class BookComponent implements OnInit { } createBook() { - this.selectedBook = new BookDto(); // reset the selected book + this.selectedBook = {} as BookDto; // reset the selected book this.buildForm(); this.isModalOpen = true; } // Add editBook method editBook(id: string) { - this.bookService.getById(id).subscribe((book) => { + this.bookService.get(id).subscribe((book) => { this.selectedBook = book; this.buildForm(); this.isModalOpen = true; @@ -1069,8 +1053,8 @@ export class BookComponent implements OnInit { } const request = this.selectedBook.id - ? this.bookService.updateByIdAndInput(this.form.value, this.selectedBook.id) - : this.bookService.createByInput(this.form.value); + ? this.bookService.update(this.selectedBook.id, this.form.value) + : this.bookService.create(this.form.value); request.subscribe(() => { this.isModalOpen = false; @@ -1155,7 +1139,7 @@ constructor( delete(id: string) { this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure').subscribe((status) => { if (status === Confirmation.Status.confirm) { - this.bookService.deleteById(id).subscribe(() => this.list.get()); + this.bookService.delete(id).subscribe(() => this.list.get()); } }); } diff --git a/docs/en/Tutorials/Part-9.md b/docs/en/Tutorials/Part-9.md index 1b9451700d..0d78d584b8 100644 --- a/docs/en/Tutorials/Part-9.md +++ b/docs/en/Tutorials/Part-9.md @@ -621,7 +621,7 @@ abp generate-proxy This command generates the service proxy for the author service and the related model (DTO) classes: -![bookstore-angular-service-proxy-author](images/bookstore-angular-service-proxy-author.png) +![bookstore-angular-service-proxy-author](images/bookstore-angular-service-proxy-author-2.png) ### AuthorComponent @@ -630,8 +630,7 @@ Open the `/src/app/author/author.component.ts` file and replace the content as b ```js import { Component, OnInit } from '@angular/core'; import { ListService, PagedResultDto } from '@abp/ng.core'; -import { AuthorDto } from './models'; -import { AuthorService } from './services'; +import { AuthorService, AuthorDto } from '@proxy/authors'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; @@ -649,7 +648,7 @@ export class AuthorComponent implements OnInit { form: FormGroup; - selectedAuthor = new AuthorDto(); + selectedAuthor = {} as AuthorDto; constructor( public readonly list: ListService, @@ -659,7 +658,7 @@ export class AuthorComponent implements OnInit { ) {} ngOnInit(): void { - const authorStreamCreator = (query) => this.authorService.getListByInput(query); + const authorStreamCreator = (query) => this.authorService.getList(query); this.list.hookToQuery(authorStreamCreator).subscribe((response) => { this.author = response; @@ -667,13 +666,13 @@ export class AuthorComponent implements OnInit { } createAuthor() { - this.selectedAuthor = new AuthorDto(); + this.selectedAuthor = {} as AuthorDto; this.buildForm(); this.isModalOpen = true; } editAuthor(id: string) { - this.authorService.getById(id).subscribe((author) => { + this.authorService.get(id).subscribe((author) => { this.selectedAuthor = author; this.buildForm(); this.isModalOpen = true; @@ -697,14 +696,14 @@ export class AuthorComponent implements OnInit { if (this.selectedAuthor.id) { this.authorService - .updateByIdAndInput(this.form.value, this.selectedAuthor.id) + .update(this.selectedAuthor.id, this.form.value) .subscribe(() => { this.isModalOpen = false; this.form.reset(); this.list.get(); }); } else { - this.authorService.createByInput(this.form.value).subscribe(() => { + this.authorService.create(this.form.value).subscribe(() => { this.isModalOpen = false; this.form.reset(); this.list.get(); @@ -716,7 +715,7 @@ export class AuthorComponent implements OnInit { this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure') .subscribe((status) => { if (status === Confirmation.Status.confirm) { - this.authorService.deleteById(id).subscribe(() => this.list.get()); + this.authorService.delete(id).subscribe(() => this.list.get()); } }); } diff --git a/docs/en/Tutorials/images/bookstore-angular-author-selection.png b/docs/en/Tutorials/images/bookstore-angular-author-selection.png new file mode 100644 index 0000000000..bb604233ab Binary files /dev/null and b/docs/en/Tutorials/images/bookstore-angular-author-selection.png differ diff --git a/docs/en/Tutorials/images/bookstore-angular-service-proxy-author-2.png b/docs/en/Tutorials/images/bookstore-angular-service-proxy-author-2.png new file mode 100644 index 0000000000..d76179bb78 Binary files /dev/null and b/docs/en/Tutorials/images/bookstore-angular-service-proxy-author-2.png differ diff --git a/docs/en/Tutorials/images/bookstore-books-with-authorname-angular.png b/docs/en/Tutorials/images/bookstore-books-with-authorname-angular.png new file mode 100644 index 0000000000..6f081c16f9 Binary files /dev/null and b/docs/en/Tutorials/images/bookstore-books-with-authorname-angular.png differ diff --git a/docs/en/Tutorials/images/generated-proxies-3.png b/docs/en/Tutorials/images/generated-proxies-3.png new file mode 100644 index 0000000000..2a94f4e389 Binary files /dev/null and b/docs/en/Tutorials/images/generated-proxies-3.png differ diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index fd34fcbae7..577129e139 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -8,27 +8,22 @@ The reason that you **can replace** but **cannot customize** default ABP compone Create a new component that you want to use instead of an ABP component. Add that component to `declarations` and `entryComponents` in the `AppModule`. -Then, open the `app.component.ts` and dispatch the `AddReplaceableComponent` action to replace your component with an ABP component as shown below: +Then, open the `app.component.ts` and execute the `add` method of `ReplaceableComponentsService` to replace your component with an ABP component as shown below: ```js -import { AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent action +import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { eIdentityComponents } from '@abp/ng.identity'; // imported eIdentityComponents enum -import { Store } from '@ngxs/store'; // imported Store //... @Component(/* component metadata */) export class AppComponent { constructor( - private store: Store // injected Store - ) - { - // dispatched the AddReplaceableComponent action - this.store.dispatch( - new AddReplaceableComponent({ - component: YourNewRoleComponent, - key: eIdentityComponents.Roles, - }), - ); + private replaceableComponents: ReplaceableComponentsService, // injected the service + ) { + this.replaceableComponents.add({ + component: YourNewRoleComponent, + key: eIdentityComponents.Roles, + }); } } ``` @@ -59,28 +54,24 @@ Add the following code in your layout template (`my-layout.component.html`) wher Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js -import { AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent +import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents enum for component keys -import { Store } from '@ngxs/store'; // imported Store import { MyApplicationLayoutComponent } from './my-application-layout/my-application-layout.component'; // imported MyApplicationLayoutComponent @Component(/* component metadata */) export class AppComponent { constructor( - private store: Store, // injected Store + private replaceableComponents: ReplaceableComponentsService, // injected the service ) { - // dispatched the AddReplaceableComponent action - this.store.dispatch( - new AddReplaceableComponent({ - component: MyApplicationLayoutComponent, - key: eThemeBasicComponents.ApplicationLayout, - }), - ); + this.replaceableComponents.add({ + component: MyApplicationLayoutComponent, + key: eThemeBasicComponents.ApplicationLayout, + }); } } ``` -> If you like to replace a layout component at runtime (e.g: changing the layout by pressing a button), pass the second parameter of the AddReplaceableComponent action as true. DynamicLayoutComponent loads content using a router-outlet. When the second parameter of AddReplaceableComponent is true, the route will be refreshed, so use it with caution. Your component state will be gone and any initiation logic (including HTTP requests) will be repeated. +> If you like to replace a layout component at runtime (e.g: changing the layout by pressing a button), pass the second parameter of the `add` method of `ReplaceableComponentsService` as true. DynamicLayoutComponent loads content using a router-outlet. When the second parameter of the `add` method is true, the route will be refreshed, so use it with caution. Your component state will be gone and any initiation logic (including HTTP requests) will be repeated. ### Layout Components @@ -123,26 +114,22 @@ export class LogoComponent {} Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js -import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent -import { Store } from '@ngxs/store'; // imported Store +import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { LogoComponent } from './logo/logo.component'; // imported NavItemsComponent import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents //... @Component(/* component metadata */) export class AppComponent implements OnInit { - constructor(..., private store: Store) {} // injected Store + constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService ngOnInit() { //... - // added dispatch - this.store.dispatch( - new AddReplaceableComponent({ + this.replaceableComponents.add({ component: LogoComponent, key: eThemeBasicComponents.Logo, - }), - ); + }); } } ``` @@ -158,15 +145,13 @@ The final UI looks like below: Run the following command in `angular` folder to create a new component called `RoutesComponent`. ```bash -yarn ng generate component routes --entryComponent - -# You don't need the --entryComponent option in Angular 9 +yarn ng generate component routes ``` Open the generated `routes.component.ts` in `src/app/routes` folder and replace its content with the following: ```js -import { ABP, ReplaceableComponents } from '@abp/ng.core'; +import { ABP } from '@abp/ng.core'; import { Component, HostBinding, @@ -200,6 +185,21 @@ export class RoutesComponent implements AfterViewInit { } ``` +Import the `SharedModule` to the `imports` array of `AppModule`: + +```js +// app.module.ts + +import { SharedModule } from './shared/shared.module'; + +@NgModule({ + imports: [ + //... + SharedModule + ] +)} +``` + Open the generated `routes.component.html` in `src/app/routes` folder and replace its content with the following: ```html @@ -309,26 +309,22 @@ Open the generated `routes.component.html` in `src/app/routes` folder and replac Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js -import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent -import { Store } from '@ngxs/store'; // imported Store +import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { RoutesComponent } from './routes/routes.component'; // imported NavItemsComponent import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents //... @Component(/* component metadata */) export class AppComponent implements OnInit { - constructor(..., private store: Store) {} // injected Store + constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService ngOnInit() { //... - // added dispatch - this.store.dispatch( - new AddReplaceableComponent({ + this.replaceableComponents.add({ component: RoutesComponent, key: eThemeBasicComponents.Routes, - }), - ); + }); } } ``` @@ -344,9 +340,7 @@ The final UI looks like below: Run the following command in `angular` folder to create a new component called `NavItemsComponent`. ```bash -yarn ng generate component nav-items --entryComponent - -# You don't need the --entryComponent option in Angular 9 +yarn ng generate component nav-items ``` Open the generated `nav-items.component.ts` in `src/app/nav-items` folder and replace the content with the following: @@ -431,6 +425,21 @@ export class NavItemsComponent implements AfterViewInit { } ``` +Import the `SharedModule` to the `imports` array of `AppModule`: + +```js +// app.module.ts + +import { SharedModule } from './shared/shared.module'; + +@NgModule({ + imports: [ + //... + SharedModule + ] +)} +``` + Open the generated `nav-items.component.html` in `src/app/nav-items` folder and replace the content with the following: ```html @@ -511,26 +520,22 @@ Open the generated `nav-items.component.html` in `src/app/nav-items` folder and Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js -import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent -import { Store } from '@ngxs/store'; // imported Store +import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { NavItemsComponent } from './nav-items/nav-items.component'; // imported NavItemsComponent import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents //... @Component(/* component metadata */) export class AppComponent implements OnInit { - constructor(..., private store: Store) {} // injected Store + constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService ngOnInit() { //... - // added dispatch - this.store.dispatch( - new AddReplaceableComponent({ + this.replaceableComponents.add({ component: NavItemsComponent, key: eThemeBasicComponents.NavItems, - }), - ); + }); } } ``` diff --git a/docs/en/UI/Angular/Environment.md b/docs/en/UI/Angular/Environment.md index 86978cfa16..402e110f94 100644 --- a/docs/en/UI/Angular/Environment.md +++ b/docs/en/UI/Angular/Environment.md @@ -1,6 +1,6 @@ # Environment -Every application needs some ** environment ** variables. In Angular world, this is usually managed by `environment.ts`, `environment.prod.ts` and so on. It is the same for ABP as well. +Every application needs some **environment** variables. In Angular world, this is usually managed by `environment.ts`, `environment.prod.ts` and so on. It is the same for ABP as well. Current `Environment` configuration holds sub config classes as follows: diff --git a/docs/en/UI/Angular/Features.md b/docs/en/UI/Angular/Features.md new file mode 100644 index 0000000000..f749030a26 --- /dev/null +++ b/docs/en/UI/Angular/Features.md @@ -0,0 +1,3 @@ +# Angular UI: Features + +> This document explains how to get feature values in an Angular application. See the [Features document](../../Features.md) to learn the feature system. \ No newline at end of file diff --git a/docs/en/UI/Angular/Permission-Management-Component-Replacement.md b/docs/en/UI/Angular/Permission-Management-Component-Replacement.md index acdfffb948..9ae712cedd 100644 --- a/docs/en/UI/Angular/Permission-Management-Component-Replacement.md +++ b/docs/en/UI/Angular/Permission-Management-Component-Replacement.md @@ -473,24 +473,20 @@ Open the generated `permission-management.component.html` in `src/app/permission Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js -import { AddReplaceableComponent } from '@abp/ng.core'; +import { ReplaceableComponentsService } from '@abp/ng.core'; import { ePermissionManagementComponents } from '@abp/ng.permission-management'; import { Component, OnInit } from '@angular/core'; -import { Store } from '@ngxs/store'; import { PermissionManagementComponent } from './permission-management/permission-management.component'; //... export class AppComponent implements OnInit { - constructor(private store: Store) {} // injected store + constructor(private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService ngOnInit() { - // added dispatching the AddReplaceableComponent action - this.store.dispatch( - new AddReplaceableComponent({ + this.replaceableComponents.add({ component: PermissionManagementComponent, key: ePermissionManagementComponents.PermissionManagement, - }) - ); + }); } } ``` diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md index 40fb18f45d..7dfb2c052c 100644 --- a/docs/en/UI/Angular/Service-Proxies.md +++ b/docs/en/UI/Angular/Service-Proxies.md @@ -4,42 +4,91 @@ It is common to call a REST endpoint in the server from our Angular applications 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: -* 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 **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. -ABP CLI `generate-proxies` command automatically generates the typescript client proxies by creating folders which separated by module names in the `src/app` folder. +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 abp generate-proxy ``` -It only creates proxies only for your own application's services. It doesn't create proxies for the services of the application modules you're using (by default). There are several options. See the [CLI documentation](../../CLI). +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 files generated with the `--module all` option like below: +The generated files will be placed in a folder called `proxy` at the root of 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. + +### Angular Project Configuration + +> If you've created your project with version 3.1 or later, you can skip this part since it will be already installed in your solution. + +For a solution that was created before v3.1, follow the steps below to configure your Angular application: + +1. Add `@abp/ng.schematics` package to the `devDependencies` of the Angular project. Run the following command in the root folder of the angular application: + +```bash +npm install @abp/ng.schematics -D +``` + +2. Add `rootNamespace` property to the `/src/environments/environment.ts` in your application project as shown below. `MyCompanyName.MyProjectName` should be replaced by the root namespace of your .NET project. + +```js +export const environment: Config.Environment = { + // other environment variables... + apis: { + default: { + rootNamespace: "MyCompanyName.MyProjectName", + // other environment variables... + }, + }, +}; +``` + +3. [OPTIONAL] Add the following paths to `tsconfig.base.json` in order to have a shortcut for importing proxies: + +```json +{ + // other TS configuration... + "compilerOptions": { + // other TS configuration... + "paths": { + "@proxy": ["src/app/proxy/index.ts"], + "@proxy/*": ["src/app/proxy/*"] + } + } +} +``` + +> The destination the `proxy` folder is created and the paths above may change based on your project structure. + ### Services -Each generated service matches a back-end controller. The services methods call back-end APIs via [RestService](./Http-Requests#restservice). +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) -The `providedIn` property of the services is defined as `'root'`. Therefore no need to add a service as a provider to a module. You can use a service by injecting it into a 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 constructor as shown below: ```js -import { AbpApplicationConfigurationService } from '../abp/applicationconfiguration/services'; +import { BookService } from '@proxy/books'; -//... -export class HomeComponent{ - constructor(private appConfigService: AbpApplicationConfigurationService) {} +@Component(/* component metadata here */) +export class BookComponent implements OnInit { + constructor(private service: BookService) {} ngOnInit() { - this.appConfigService.get().subscribe() + this.service.get().subscribe( + // do something with the response + ); } } ``` @@ -48,20 +97,48 @@ The Angular compiler removes the services that have not been injected anywhere f ### Models -The generated models match the DTOs in the back-end. Each model is generated as a class under the `src/app/*/models` folder. +The `generate-proxy` command generates interfaces matching DTOs in the back-end. There are also a few [core DTOs](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/dtos.ts) in the `@abp/ng.core` package. In combination, these models can be used to reflect the APIs. -There are a few [base classes](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/dtos.ts) in the `@abp/ng.core` package. Some models extend these classes. +```js +import { PagedResultDto } from "@abp/ng.core"; +import { BookDto } from "@proxy/books"; + +@Component(/* component metadata here */) +export class BookComponent implements OnInit { + data: PagedResultDto = { + items: [], + totalCount: 0, + }; +} +``` -A class instance can be created as shown below: +### 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: ```js -import { IdentityRoleCreateDto } from '../identity/role/models' -//... -const instance = new IdentityRoleCreateDto({name: 'Role 1', isDefault: false, isPublic: true}) +import { bookGenreOptions } from "@proxy/books"; + +@Component(/* component metadata here */) +export class BookComponent implements OnInit { + genres = bookGenreOptions; +} +``` + +...and consume the options in the template as follows: + +```html + + ``` -Initial values ​​can optionally be passed to each class constructor. +> Please [see this article](https://github.com/abpframework/abp/blob/dev/docs/en/Blog-Posts/2020-09-07%20Angular-Service-Proxies/POST.md) to learn more about service proxies. ## What's Next? -* [HTTP Requests](./Http-Requests) +- [HTTP Requests](./Http-Requests) diff --git a/docs/en/UI/Angular/images/generated-files-via-generate-proxy.png b/docs/en/UI/Angular/images/generated-files-via-generate-proxy.png index 0d062cc2d3..a52c4bcabb 100644 Binary files a/docs/en/UI/Angular/images/generated-files-via-generate-proxy.png and b/docs/en/UI/Angular/images/generated-files-via-generate-proxy.png differ diff --git a/docs/en/Upgrading.md b/docs/en/Upgrading.md new file mode 100644 index 0000000000..1140c5d573 --- /dev/null +++ b/docs/en/Upgrading.md @@ -0,0 +1,41 @@ +# Upgrading the ABP Framework + +This document explains how to upgrade your existing solution when a new ABP Framework version is published. + +## ABP UPDATE Command + +ABP Framework & module ecosystem consist of hundreds of NuGet and NPM packages. It would be tedious to manually update all these packages to upgrade your application. + +[ABP CLI](CLI.md) provides a handy command to update all the ABP related NuGet and NPM packages in your solution with a single command: + +````bash +abp update +```` + +Run this command in the terminal while you are in the root folder of your solution. + +> If your solution has the Angular UI, you probably have `aspnet-core` and `angular` folders in the solution. Run this command in the parent folder of these two folders. + +## The Blog Posts + +Sometimes we introduce new features/changes that requires to make changes in the startup template. We already implement the changes in the startup template for new applications. However, in some cases you need to manually make some minor changes in your solution. + +Whenever you upgrade your solution, it is strongly suggested to check the [ABP BLOG](https://blog.abp.io/?_ga=2.177248992.411298747.1597771169-1910388957.1594128976) to learn the new features and changes coming with the new version. We regularly publish posts and write these kind of changes. If the changes are not trivial, we also provide migration guides. + +## Semantic Versioning & Breaking Changes + +We are working hard to keep the semantic versioning rules, so you don't get breaking changes for minor (feature) versions like 3.1, 3.2, 3.3... + +However, there are some cases we may introduce breaking changes in feature versions too; + +* ABP has many integration packages and sometimes the integrated libraries/frameworks releases major versions and makes breaking changes. In such cases, we carefully check these changes and decide to upgrade the integration package or not. If the impact of the change is relatively small, we update the integration package and explain the change in the release blog post. In such a case, if you've used this integration package, you should follow the instructions explained in the blog post. If the change may break many applications and not easy to fix, we decide to wait this upgrade until the next major ABP Framework release. +* Sometimes we have to make breaking change to fix a major bug or usage problem. In this case, we think that developer already can't properly use that feature, so no problem to fix it with a breaking change. In such cases, the feature will generally be a rarely used feature. Again, we try to keep the impact minimum. + +## Preview Releases & Nightly Builds + +Preview releases and nightly builds can help you to try new features and adapt your solution earlier than a new stable release. + +* [Preview releases](Previews.md) are typically published ~2 weeks before a minor (feature) version (our minor version development cycle is about ~4 weeks). +* [Nightly builds](Nightly-Builds.md) are published in every night (except weekends) from the development branch. That means you can try the previous day's development. + +Refer to the their documents to learn details about these kind of releases. \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 4c7703ff70..0273030308 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -170,6 +170,10 @@ "text": "Settings", "path": "Settings.md" }, + { + "text": "Features", + "path": "Features.md" + }, { "text": "Data Filtering", "path": "Data-Filtering.md" @@ -684,6 +688,10 @@ "text": "Road Map", "path": "Road-Map.md" }, + { + "text": "Upgrading", + "path": "Upgrading.md" + }, { "text": "Contribution Guide", "path": "Contribution/Index.md" diff --git a/docs/en/images/features-action.png b/docs/en/images/features-action.png new file mode 100644 index 0000000000..8283a95be9 Binary files /dev/null and b/docs/en/images/features-action.png differ diff --git a/docs/en/images/features-modal.png b/docs/en/images/features-modal.png new file mode 100644 index 0000000000..74ee8aabc3 Binary files /dev/null and b/docs/en/images/features-modal.png differ diff --git a/docs/zh-Hans/Authentication/Social-External-Logins.md b/docs/zh-Hans/Authentication/Social-External-Logins.md index 3d599a962d..55ab97374c 100644 --- a/docs/zh-Hans/Authentication/Social-External-Logins.md +++ b/docs/zh-Hans/Authentication/Social-External-Logins.md @@ -1,10 +1,9 @@ # 社交/外部登录 -## ASP.NET Core MVC / Razor Pages UI [帐户模块](../Modules/Account.md)已配置为开箱即用的处理社交或外部登录. 你可以按照ASP.NET Core文档向你的应用程序添加社交/外部登录提供程序. -### 示例: Facebook 认证 +## 示例: Facebook 认证 按照[ASP.NET Core Facebook集成文档](https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/social/facebook-logins)向你应用程序添加Facebook登录. @@ -27,4 +26,8 @@ context.Services.AddAuthentication() }); ```` -> 最佳实践是使用 `appsettings.json` 或ASP.NET Core用户机密系统来存储你的凭据,而不是像这样硬编码值. 请参阅[微软](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/facebook-logins)文档了解如何使用用户机密. \ No newline at end of file +> 最佳实践是使用 `appsettings.json` 或ASP.NET Core用户机密系统来存储你的凭据,而不是像这样硬编码值. 请参阅[微软](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/facebook-logins)文档了解如何使用用户机密. + +## Angular UI + +从v3.1开始,Angular UI使用授权码流程(作为最佳实践)通过重定向到MVC UI登录页面来对用户进行身份验证. 因此,即使你使用的是Angular UI,社交/外部登录集成也与上面说明的相同.并且可以开箱即用. \ No newline at end of file diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md index 82a72ec7ed..11f9964279 100644 --- a/docs/zh-Hans/CLI.md +++ b/docs/zh-Hans/CLI.md @@ -16,6 +16,12 @@ dotnet tool install -g Volo.Abp.Cli dotnet tool update -g Volo.Abp.Cli ```` +## 全局选项 + +虽然每个命令可能都有一组选项,但有些全局选项可以与任何命令一起使用: + +* `--skip-cli-version-check`: 跳过检查最新版本的ABP CLI. 如果没有指定,它会检查最新版本,如果检查到ABP CLI的新版本,会显示一条警告消息. + ## Commands 这里是所有可用的命令列表: @@ -25,7 +31,9 @@ dotnet tool update -g Volo.Abp.Cli * **`update`**:自动更新的ABP解决方案ABP相关的NuGet和NPM包. * **`add-package`**: 添加ABP包到项目. * **`add-module`**: 添加[应用模块](https://docs.abp.io/en/abp/latest/Modules/Index)到解决方案. -* **`generate-proxy`**: 生成客户端代理以使用服务器上的HTTP API端点. +* **`generate-proxy`**: 生成客户端代理以使用HTTP API端点. +* **`remove-proxy`**: 移除以前生成的客户端代理. +* **`switch-to-preview`**: 切换到ABP框架的最新预览版本。 * **`switch-to-preview`**: 切换解决方案所有ABP相关包为[夜间构建](Nightly-Builds.md)版本. * **`switch-to-stable`**: 切换解决方案所有ABP相关包为最新的稳定版本. * **`translate`**: 当源代码控制存储库中有多个JSON[本地化](Localization.md文件时,可简化翻译本地化文件的过程. @@ -77,6 +85,8 @@ abp new Acme.BookStore * `--tiered`: 创建分层解决方案,Web和Http Api层在物理上是分开的.如果未指定会创建一个分层的解决方案,此解决方案没有那么复杂,适合大多数场景. * `angular`: Angular. 这个模板还有一些额外的选项: * `--separate-identity-server`: 将Identity Server应用程序与API host应用程序分开. 如果未指定,则服务器端将只有一个端点. + * `blazor`: Blazor. 这个模板还有一些额外的选项: + * `--separate-identity-server`: 将Identity Server应用程序与API host应用程序分开. 如果未指定,则服务器端将只有一个端点. * `none`: 无UI. 这个模板还有一些额外的选项: * `--separate-identity-server`: 将Identity Server应用程序与API host应用程序分开. 如果未指定,则服务器端将只有一个端点. * `--mobile` 或者 `-m`: 指定移动应用程序框架. 如果未指定,则不会创建任何移动应用程序,其他选项: @@ -90,12 +100,33 @@ abp new Acme.BookStore * **`console`**: [Console template](Startup-Templates/Console.md). * `--output-folder` 或者 `-o`: 指定输出文件夹,默认是当前目录. * `--version` 或者 `-v`: 指定ABP和模板的版本.它可以是 [release tag](https://github.com/abpframework/abp/releases) 或者 [branch name](https://github.com/abpframework/abp/branches). 如果没有指定,则使用最新版本.大多数情况下,你会希望使用最新的版本. -* `--preview`: 使用最新的预发行版本 (仅在未指定 `--version` 且最新稳定版本之后至少有一个预发行版时). +* `--preview`: 使用最新的预览版本. * `--template-source` 或者 `-ts`: 指定自定义模板源用于生成项目,可以使用本地源和网络源(例如 `D:\local-templat` 或 `https://.../my-template-file.zip`). * `--create-solution-folder` 或者 `-csf`: 指定项目是在输出文件夹中的新文件夹中还是直接在输出文件夹中. * `--connection-string` 或者 `-cs`: 重写所有 `appsettings.json` 文件的默认连接字符串. 默认连接字符串是 `Server=localhost;Database=MyProjectName;Trusted_Connection=True;MultipleActiveResultSets=true`. 默认的数据库提供程序是 `SQL Server`. 如果你使用EF Core但需要更改DBMS,可以按[这里所述](Entity-Framework-Core-Other-DBMS.md)进行更改(创建解决方案之后). * `--local-framework-ref --abp-path`: 使用对项目的本地引用,而不是替换为NuGet包引用. +### update + +更新所有ABP相关的包可能会很繁琐,框架和模块都有很多包. 此命令自动将解决方案或项目中所有ABP相关的包更新到最新版本. + +用法: + +````bash +abp update [options] +```` + +* 如果你的文件夹中有.sln文件,运行命令会将解决方案中所有项目ABP相关的包更新到最新版本. +* 如果你的文件夹中有.csproj文件,运行命令会将项目中所有ABP相关的包更新到最新版本. + +#### Options + +* `--npm`: 仅更新NPM包 +* `--nuget`: 仅更新的NuGet包 +* `--solution-path` 或 `-sp`: 指定解决方案路径/目录. 默认使用当前目录 +* `--solution-name` 或 `-sn`: 指定解决方案名称. 默认在目录中搜索`*.sln`文件. +*`--check-all`: 分别检查每个包的新版本. 默认是 `false`. + ### add-package 通过以下方式将ABP包添加到项目中 @@ -150,105 +181,157 @@ abp add-module Volo.Blogging * `-sp` 或 `--startup-project`: 启动项目的项目文件夹的相对路径. 默认值是当前文件夹. * `--with-source-code`: 添加模块的源代码,而不是NuGet/NPM软件包. -### update +### generate-proxy -更新所有ABP相关的包可能会很繁琐,框架和模块都有很多包. 此命令自动将解决方案或项目中所有ABP相关的包更新到最新版本. +为您的HTTP API生成Angular服务代理,简化从客户端使用服务的成本. 在运行此命令之前,你的host必须启动正在运行. 用法: ````bash -abp update [options] +abp generate-proxy ```` -* 如果你的文件夹中有.sln文件,运行命令会将解决方案中所有项目ABP相关的包更新到最新版本. -* 如果你的文件夹中有.csproj文件,运行命令会将项目中所有ABP相关的包更新到最新版本. - #### Options -* `--include-previews` 或 `-p`: 将预览版, 测试版本 和 rc 包 同时更新到最新版本. -* `--npm`: 仅更新NPM包 -* `--nuget`: 仅更新的NuGet包 -* `--solution-path` 或 `-sp`: 指定解决方案路径/目录. 默认使用当前目录 -* `--solution-name` 或 `-sn`: 指定解决方案名称. 默认在目录中搜索`*.sln`文件. -*`--check-all`: 分别检查每个包的新版本. 默认是 `false`. - -### 切换到每晚构建(预览)包 +* `--module` 或 `-m`: 指定要为其生成代理的后端模块的名称. 默认值: `app`. +* `--api-name` 或 `-a`: 在 `/src/environments/environment.ts` 中定义的API端点名称。. 默认值: `default`. +* `--source` 或 `-s`: 指定解析根名称空间和API定义URL的Angular项目名称. 默认值: `defaultProject` +* `--target` 或 `-t`: 指定放置生成的代码的Angular项目名称. 默认值: `defaultProject`. +* `--prompt` 或 `-p`: 在命令行提示符下询问选项(未指定的选项). -想要切换到ABP框架的最新**每晚构建**预览版可以使用此命令. +> 参阅 [Angular服务代理文档](UI/Angular/Service-Proxies.md) 了解更多. -用法: +### remove-proxy -````bash -abp switch-to-nightly [options] -```` +从Angular应用程序中删除以前生成的代理代码. 在运行此命令之前,你的host必须启动正在运行. + +This can be especially useful when you generate proxies for multiple modules before and need to remove one of them later. -你也可以使用切换回最新稳定版本: +Usage: ````bash -abp switch-to-stable [options] +abp remove-proxy ```` #### Options -`--solution-directory` 或 `-sd`: 指定解决方案文件夹. 解决方案应该在指定文件夹或子文件夹中. 如果未指定,默认为当前目录. +* `--module` 或 `-m`: 指定要为其生成代理的后端模块的名称. 默认值: `app`. +* `--api-name` 或 `-a`: 在 `/src/environments/environment.ts` 中定义的API端点名称。. 默认值: `default`. +* `--source` 或 `-s`: 指定解析根名称空间和API定义URL的Angular项目名称. 默认值: `defaultProject` +* `--target` 或 `-t`: 指定放置生成的代码的Angular项目名称. 默认值: `defaultProject`. +* `--prompt` 或 `-p`: 在命令行提示符下询问选项(未指定的选项). -### login +> 参阅 [Angular服务代理文档](UI/Angular/Service-Proxies.md) 了解更多. -CLI的一些功能需要登录到abp.io平台. 使用你的用户名登录 +### switch-to-preview -```bash -abp login -``` +你可以使用此命令将项目切换到ABP框架的最新预览版本. -```bash -abp login -p -``` - -请注意,新的登录将终止先前的会话并创建一个新的会话. - -### logout +用法: -通过从计算机中删除会话令牌来注销. +````bash +abp switch-to-preview [options] +```` -``` -abp logout -``` +#### Options -### generate-proxy +* `--solution-directory` 或 `-sd`: 指定目录. 解决方案应该在该目录或其子目录中. 如果未指定默认为当前目录. + +### switch-to-nightly -为你的HTTP API生成客户端代码,简化客户端使用服务的成本. 在运行 `generate-proxy` 命令之前,你的host必须启动正在运行. +想要切换到ABP框架的最新[每晚构建](Nightly-Builds.md)预览版可以使用此命令. 用法: ````bash -abp generate-proxy [options] +abp switch-to-nightly [options] ```` #### Options -* `--apiUrl` 或者 `-a`:指定HTTP API的根URL. 如果未指定这个选项,默认使用你Angular应用程序的`environment.ts`文件API URL. 在运行 `generate-proxy` 命令之前,你的host必须启动正在运行. -* `--ui` 或者 `-u`: 指定UI框架,默认框架是angular.当前只有angular一个选项, 但我们会通过更改CLI增加新的选项. 尽请关注! -* `--module` 或者 `-m`:指定模块名. 默认模块名称为app. 如果你想所有模块,你可以指定 `--module all` 命令. +`--solution-directory` 或 `-sd`: 指定目录. 解决方案应该在该目录或其子目录中. 如果未指定默认为当前目录. -示例: +### switch-to-stable + +如果你使用的是ABP框架预览包(包括每晚构建),可以使用此命令切换回最新的稳定版本. + +用法: ````bash -abp generate-proxy --apiUrl https://localhost:44305 --ui angular --module all +abp switch-to-stable [options] ```` +#### Options -### help +`--solution-directory` 或 `-sd`: 指定目录. 解决方案应该在该目录或其子目录中. 如果未指定默认为当前目录. -CLI的基本用法信息. +### translate -用法: + +源代码控制存储库中有多个JSON[本地化](Localization.md)文件时,用于简化翻译[本地化](Localization.md)文件的过程. + +* 该命令将基于参考文化创建一个统一的json文件 +* 它搜索当前目录和所有子目录中的所有本地化"JSON"文件(递归). 然后创建一个包含所有需要翻译的条目的文件(默认情况下名为 "abp-translation.json"). +* 翻译了此文件中的条目后,你就可以使用 `--apply` 命令将更改应用于原始本地化文件. + +> 该命令的主要目的是翻译ABP框架本地化文件(因为[abp仓库](https://github.com/abpframework/abp)包括数十个要在不同目录中转换的本地化文件). + +#### 创建翻译文件 + +第一步是创建统一的翻译文件: ````bash -abp help [命令名] +abp translate -c [options] ```` 示例: ````bash -abp help # 显示常规帮助. -abp help new # 显示有关 "New" 命令的帮助. +abp translate -c de-DE +```` + +该命令为 `de-DE` (德语)文化创建了统一的翻译文件. + +##### 附加选项 + +* `--reference-culture` 或 `-r`: 默认值 `en`. 指定参考文化. +* `--output` 或 `-o`: 输出文件名. 默认值 `abp-translation.json`. +* `--all-values` 或 `-all`: 包括所有要翻译的键. 默认情况下,统一翻译文件仅包含目标文化的缺失文本. 如果你可能需要修改之前已经翻译的值,请指定此参数. + +#### 应用更改 + + +翻译完统一翻译文件中的条目后,你可以使用 `--apply` 参数将更改应用于原始本地化文件: + +````bash +abp translate --apply # apply all changes +abp translate -a # shortcut for --apply ```` + +然后,检查源代码控制系统上的更改,以确保它已更改了正确的文件. 如果你翻译了ABP框架资源, 请发送 "Pull Request". 提前感谢你的贡献. + +##### 附加选项 + +* `--file` 或 `-f`: 默认值: `abp-translation.json`. 翻译文件(仅在之前使用过 `--output` 选项时使用). + +### login + +CLI的一些功能需要登录到abp.io平台. 使用你的用户名登录 + +```bash +abp login # Allows you to enter your password hidden +abp login -p # Specify the password as a parameter (password is visible) +abp login --organization # If you have multiple organizations, you need set your active organization +abp login -p -o # You can enter both your password and organization in the same command +``` + +> 当使用-p参数,请注意,因为你的密码是可见的. 它对于CI / CD自动化管道很有用. + +请注意,新的登录将终止先前的会话并创建一个新的会话. + +### logout + +通过从计算机中删除会话令牌来注销. + +``` +abp logout +``` diff --git a/docs/zh-Hans/Contribution/Index.md b/docs/zh-Hans/Contribution/Index.md index f3bafe9293..7b1c3544ef 100644 --- a/docs/zh-Hans/Contribution/Index.md +++ b/docs/zh-Hans/Contribution/Index.md @@ -1,8 +1,12 @@ -## 贡献指南 +# 贡献指南 ABP是[开源](https://github.com/abpframework)和社区驱动项目. 本指南旨在帮助任何想要为项目做出贡献的人. -### 贡献代码 +## community.abp.io + +如果你可编写文章或关于ASP框架和ASP.NET Core的 "如何" 指南,请提交你的文章到[community.abp.io](https://community.abp.io/)网站. + +## 贡献代码 你可以将Pull request(拉取请求)发送到Github存储库. @@ -12,15 +16,15 @@ ABP是[开源](https://github.com/abpframework)和社区驱动项目. 本指南 在进行任何更改之前,请在[Github问题](https://github.com/abpframework/abp/issues)上进行讨论. 通过这种方式, 其他开发人员将不会处理同一个问题, 你的PR将有更好的机会被接受. -#### Bug修复 & 增强功能 +### Bug修复 & 增强功能 你可能希望修复已知Bug或处理计划的增强功能. 请参阅Github上的[问题列表](https://github.com/abpframework/abp/issues). -#### 功能请求 +### 功能请求 如果你对框架或模块有功能的想法, 请在Github上[创建一个问题](https://github.com/abpframework/abp/issues/new)或参加现有的讨论. 如果它被社区所接受你就可以实现它. -### 文档翻译 +## 文档翻译 你可能希望将完整的[文档](https://abp.io/documents/)(包括本文)翻译成你的母语. 请按照下列步骤操作: @@ -37,13 +41,13 @@ ABP是[开源](https://github.com/abpframework)和社区驱动项目. 本指南 完成了这些基本的翻译后,将添加一种新的语言 -### 资源本地化 +## 资源本地化 ABP框架具有灵活的[本地化系统](../Localization.md). 你可以为自己的应用程序创建本地化用户界面. 除此之外,框架和预构建模块已经本地化了文本.请参阅[Volo.Abp.UI包的本地化文本](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json). -#### 使用 "abp translate" 命令 +### 使用 "abp translate" 命令 这是推荐的方法,因为它会自动查找所有缺少的文本的特定文化,让你在一个地方翻译. @@ -54,14 +58,10 @@ ABP框架具有灵活的[本地化系统](../Localization.md). 你可以为自 * 一旦你完成了翻译,使用 `abp translate -a` 命令应用更改到相关的文件. * 在GitHub上发送PR. -#### 手动翻译 - -如果你想更改特定的资源文件,你可以自己找到这个文件进行必要的更改(或为你的语言创建新文件),并在GitHub上发送PR。 - -### 博客文章和教程 +### 手动翻译 -如果你发布了一些ABP框架的教程或博客帖子, 请通知我们(通过创建[Github问题](https://github.com/abpframework/abp/issues)), 我们可能会在官方文档中添加指向你的教程或博客帖子的链接和在[推特](https://twitter.com/abpframework)上公布. +如果你想更改特定的资源文件,你可以自己找到这个文件进行必要的更改(或为你的语言创建新文件),并在GitHub上发送PR. -### Bug 报告 +## Bug 报告 如果你发现任何Bug, 请[在Github存储库上创建一个问题](https://github.com/abpframework/abp/issues/new). \ No newline at end of file diff --git a/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md b/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md index 3e5ff3f6cd..6c895f71d2 100644 --- a/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md +++ b/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md @@ -43,7 +43,10 @@ return user.GetProperty("Title"); ObjectExtensionManager.Instance .MapEfCoreProperty( "SocialSecurityNumber", - b => { b.HasMaxLength(32); } + (entityBuilder, propertyBuilder) => + { + propertyBuilder.HasMaxLength(32); + } ); ```` diff --git a/docs/zh-Hans/Data-Filtering.md b/docs/zh-Hans/Data-Filtering.md index 548f70c80c..45adcb6b05 100644 --- a/docs/zh-Hans/Data-Filtering.md +++ b/docs/zh-Hans/Data-Filtering.md @@ -151,11 +151,21 @@ public class Book : AggregateRoot, IIsActive ABP使用[EF Core的全局过滤](https://docs.microsoft.com/en-us/ef/core/querying/filters)系统用于[EF Core 集成](Entity-Framework-Core.md). 所以它很好的集成到EF Core中,即使你直接使用 `DbContext` 它也可以正常工作. -实现自定义过滤的最佳方法是为重写你的 `DbContext` 的 `CreateFilterExpression` 方法. 示例: +实现自定义过滤的最佳方法是为重写你的 `DbContext` 的 `ShouldFilterEntity` 和 `CreateFilterExpression` 方法. 示例: ````csharp protected bool IsActiveFilterEnabled => DataFilter?.IsEnabled() ?? false; +protected override bool ShouldFilterEntity(IMutableEntityType entityType) +{ + if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity))) + { + return true; + } + + return base.ShouldFilterEntity(entityType); +} + protected override Expression> CreateFilterExpression() { var expression = base.CreateFilterExpression(); @@ -174,7 +184,7 @@ protected override Expression> CreateFilterExpression`(或`BasicAggregateRoot`). + ## 基类和接口的审计属性 有一些属性,像`CreationTime`,`CreatorId`,`LastModificationTime`...在所有应用中都很常见. ABP框架提供了一些接口和基类来**标准化**这些属性,并**自动设置它们的值**. diff --git a/docs/zh-Hans/Entity-Framework-Core-Migrations.md b/docs/zh-Hans/Entity-Framework-Core-Migrations.md index 876d98721b..c6f1086540 100644 --- a/docs/zh-Hans/Entity-Framework-Core-Migrations.md +++ b/docs/zh-Hans/Entity-Framework-Core-Migrations.md @@ -414,7 +414,10 @@ public static class MyProjectNameEntityExtensions ObjectExtensionManager.Instance .MapEfCoreProperty( "Title", - builder => { builder.HasMaxLength(64); } + (entityBuilder, propertyBuilder) => + { + propertyBuilder.HasMaxLength(128); + } ); }); } diff --git a/docs/zh-Hans/Entity-Framework-Core.md b/docs/zh-Hans/Entity-Framework-Core.md index 5ae6ce1070..211ec4d65f 100644 --- a/docs/zh-Hans/Entity-Framework-Core.md +++ b/docs/zh-Hans/Entity-Framework-Core.md @@ -325,7 +325,10 @@ public class BookService ObjectExtensionManager.Instance .MapEfCoreProperty( "Title", - builder => { builder.HasMaxLength(64); } + (entityBuilder, propertyBuilder) => + { + propertyBuilder.HasMaxLength(64); + } ); ```` diff --git a/docs/zh-Hans/Getting-Started-Console-Application.md b/docs/zh-Hans/Getting-Started-Console-Application.md deleted file mode 100644 index 1bf48cefd4..0000000000 --- a/docs/zh-Hans/Getting-Started-Console-Application.md +++ /dev/null @@ -1,3 +0,0 @@ -## 在控制台应用中使用ABP - -ABP提供了控制台应用程序启动模板. 参阅[控制台应用程序启动模板]文档了解更多信息. \ No newline at end of file diff --git a/docs/zh-Hans/Global-Features.md b/docs/zh-Hans/Global-Features.md new file mode 100644 index 0000000000..776d4e0718 --- /dev/null +++ b/docs/zh-Hans/Global-Features.md @@ -0,0 +1,3 @@ +# Global Features + +TODO... \ No newline at end of file diff --git a/docs/zh-Hans/How-To/Index.md b/docs/zh-Hans/How-To/Index.md deleted file mode 100644 index 3190ced7ca..0000000000 --- a/docs/zh-Hans/How-To/Index.md +++ /dev/null @@ -1,9 +0,0 @@ -# "如何" 指南 - -本部分包含一些常见问题的 "如何" 指南. 尽管其中是一些常见的开发任务和ABP并不直接相关,但我们认为有一些具体的示例可以直接与基于ABP的应用程序一起使用. - -## Authentication - -* [如何为MVC / Razor页面应用程序自定义登录页面](Customize-Login-Page-MVC.md) -* [如何对MVC / Razor页面应用程序使用Azure Active Directory身份验证](Azure-Active-Directory-Authentication-MVC.md) -* [如何为ABP应用程序定制SignIn Manager](Customize-SignIn-Manager.md) \ No newline at end of file diff --git a/docs/zh-Hans/Local-Event-Bus.md b/docs/zh-Hans/Local-Event-Bus.md index 44e21d0384..3a955e90d7 100644 --- a/docs/zh-Hans/Local-Event-Bus.md +++ b/docs/zh-Hans/Local-Event-Bus.md @@ -156,6 +156,8 @@ namespace AbpDemo > 事件处理程序类必须注册到依赖注入(DI),示例中使用了 `ITransientDependency`. 参阅[DI文档](Dependency-Injection.md)了解更多选项. +如果您执行**数据库操作**并在事件处理程序中使用[仓储](Repositories.md),那么您可能需要创建一个[工作单元](Unit-Of-Work.md),因为一些存储库方法需要在**活动的工作单元**中工作. 确保处理方法设置为 `virtual`,并为该方法添加一个 `[UnitOfWork]` attribute. 或者手动使用 `IUnitOfWorkManager` 创建一个工作单元范围. + ## 事务和异常行为 当一个事件发布,订阅的事件处理程序将立即执行.所以; diff --git a/docs/zh-Hans/MailKit.md b/docs/zh-Hans/MailKit.md new file mode 100644 index 0000000000..cb82a640d5 --- /dev/null +++ b/docs/zh-Hans/MailKit.md @@ -0,0 +1 @@ +TODO... \ No newline at end of file diff --git a/docs/zh-Hans/Module-Development-Basics.md b/docs/zh-Hans/Module-Development-Basics.md index e43c57d0b2..1e1e9a42cd 100644 --- a/docs/zh-Hans/Module-Development-Basics.md +++ b/docs/zh-Hans/Module-Development-Basics.md @@ -1,4 +1,4 @@ -## 模块开发 +## 模块化 ### 介绍 diff --git a/docs/zh-Hans/Modules/Identity.md b/docs/zh-Hans/Modules/Identity.md index f396de00c1..5589fb367e 100644 --- a/docs/zh-Hans/Modules/Identity.md +++ b/docs/zh-Hans/Modules/Identity.md @@ -1,5 +1,28 @@ # 身份管理模块 -身份模块基于Microsoft Identity 库用于管理[组织单元](Organization-Units.md), 角色, 用户和他们的权限. +身份模块基于Microsoft Identity库用于管理[组织单元](Organization-Units.md), 角色, 用户和他们的权限. -参阅 [源码](https://github.com/abpframework/abp/tree/dev/modules/identity). 文档很快会被完善. \ No newline at end of file +参阅 [源码](https://github.com/abpframework/abp/tree/dev/modules/identity). 文档很快会被完善. + +## Identity安全日志 + +安全日志可以记录账户的一些重要的操作或者改动, 你可以在在一些功能中保存安全日志. + +你可以注入和使用 `IdentitySecurityLogManager` 或 `ISecurityLogManager` 来保存安全日志. 默认它会创建一个安全日志对象并填充常用的值. 如 `CreationTime`, `ClientIpAddress`, `BrowserInfo`, `current user/tenant`等等. 当然你可以自定义这些值. + +```cs +await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext() +{ + Identity = "IdentityServer"; + Action = "ChangePassword"; +}); +``` + +通过配置 `AbpSecurityLogOptions` 来提供应用程序的名称或者禁用安全日志功能. 默认是**启用**状态. + +```cs +Configure(options => +{ + options.ApplicationName = "AbpSecurityTest"; +}); +``` diff --git a/docs/zh-Hans/Moodule-Entity-Extensions.md b/docs/zh-Hans/Moodule-Entity-Extensions.md new file mode 100644 index 0000000000..6e8c73c2a2 --- /dev/null +++ b/docs/zh-Hans/Moodule-Entity-Extensions.md @@ -0,0 +1,3 @@ +# Module Entity Extensions + +参阅 https://docs.abp.io/en/commercial/latest/guides/module-entity-extensions (文档会在近期完成). \ No newline at end of file diff --git a/docs/zh-Hans/Nightly-Builds.md b/docs/zh-Hans/Nightly-Builds.md index 020d69e02e..14a5b8ad8c 100644 --- a/docs/zh-Hans/Nightly-Builds.md +++ b/docs/zh-Hans/Nightly-Builds.md @@ -2,40 +2,18 @@ 所有框架和模块包每晚都部署到MyGet. 因此你可以使用或测试最新的代码,而无需等待下一个版本. -## 在Visual Studio配置 +## 安装和卸载每晚预览包 -> 需要Visual Studio 2017以上 - -1. 在VS中打开: `工具 > 选项 > NuGet 包管理器 > 程序包源` -2. 单击绿色的`+`图标 -3. 在底部输入名称(ABP Nightly)和并粘贴URL(`https://www.myget.org/F/abp-nightly/api/v3/index.json`)到源上. - ![night-build-add-nuget-source](images/night-build-add-nuget-source.png) -3. 单击`更新`按钮 -4. 点击`确定`按钮保存 - -## 安装包 - -现在, 你可以从**管理NuGet包** 或 **程序包管理器控制台** 将预览/夜间程序包安装到你的项目中. - -![night-build-add-nuget-package](images/night-build-add-nuget-package.png) - -1. 在nuget浏览中,选择"包括预发行版". -2. 将包源更改为`全部`. -3. 搜索nuget包. 你将看到包的预发布格式为`(VERSION)-preview(DATE)` (如本示例中的**v0.16.0-preview20190401**). -4. 你可以单击`安装`按钮将包添加到项目中. - -## 安装和卸载预览NPM包 - -预览NPM包的最新版本可以通过在应用程序的根文件夹命令运行命令安装: +可以通过在应用程序的根文件夹中运行以下命令安装最新版本的夜间预览软件包: ```bash -abp switch-to-preview --npm +abp switch-to-nightly ``` -如果你正在使用ABP框架预览包,你可以使用此命令切换回稳定版本: +如果你正在使用ABP框架每晚预览包,你可以使用此命令切换回稳定版本: ```bash -abp switch-to-stable --npm +abp switch-to-stable ``` 参阅 [ABP CLI 文档](./CLI.md) 了解更多信息. \ No newline at end of file diff --git a/docs/zh-Hans/Previews.md b/docs/zh-Hans/Previews.md new file mode 100644 index 0000000000..cb82a640d5 --- /dev/null +++ b/docs/zh-Hans/Previews.md @@ -0,0 +1 @@ +TODO... \ No newline at end of file diff --git a/docs/zh-Hans/Repositories.md b/docs/zh-Hans/Repositories.md index ee48186985..79186b79da 100644 --- a/docs/zh-Hans/Repositories.md +++ b/docs/zh-Hans/Repositories.md @@ -6,7 +6,11 @@ ## 通用(泛型)仓储 -ABP为每个聚合根或实体提供了 **默认的通用(泛型)仓储** . 你可以在服务中[注入](Dependency-Injection.md) `IRepository` 使用标准的**CRUD**操作. 用法示例: +ABP为每个聚合根或实体提供了 **默认的通用(泛型)仓储** . 你可以在服务中[注入](Dependency-Injection.md) `IRepository` 使用标准的**CRUD**操作. + +> 数据库提供程序层应正确配置为能够使用默认的通用存储库. 如果你已经使用启动模板创建了项目,则这些配置 **已经完成**了. 如果不是,请参考数据库提供程序文档([EF Core](Entity-Framework-Core.md) / [MongoDB](MongoDB.md))进行配置. + +**默认通用仓储用法示例:** ````C# public class PersonAppService : ApplicationService diff --git a/docs/zh-Hans/Samples/Index.md b/docs/zh-Hans/Samples/Index.md index 94e5392b51..db2e680883 100644 --- a/docs/zh-Hans/Samples/Index.md +++ b/docs/zh-Hans/Samples/Index.md @@ -15,17 +15,14 @@ 一个简单的CRUD应用程序,展示了使用ABP框架开发应用程序的基本原理. 使用不同的技术实现了相同的示例: * **Book Store: Razor Pages UI & Entity Framework Core** - - * [教程](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC) - * [源码](https://github.com/abpframework/abp-samples/tree/master/BookStore) + * [教程](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC&DB=EF) + * [源码](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore) * **Book Store: Angular UI & MongoDB** - - * [教程](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=NG) + * [教程](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=NG&DB=Mongo) * [源码](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb) * **Book Store: Modular application (Razor Pages UI & EF Core)** - * [源码](https://github.com/abpframework/abp-samples/tree/master/BookStore-Modular) 如果没有Razor Pages & MongoDB 结合,但你可以检查两个文档来理解它,因为DB和UI不会互相影响. @@ -33,11 +30,14 @@ ### 其他示例 * **Entity Framework 迁移**: 演示如何将应用程序拆分为多个数据库的解决方案. 每个数据库包含不同的模块. - * [源码](https://github.com/abpframework/abp-samples/tree/master/DashboardDemo) + * [源码](https://github.com/abpframework/abp-samples/tree/master/EfCoreMigrationDemo) * [EF Core数据库迁移文档](../Entity-Framework-Core-Migrations.md) * **SignalR Demo**: A simple chat application that allows to send and receive messages among authenticated users. * [源码](https://github.com/abpframework/abp-samples/tree/master/SignalRDemo) * [SignalR 集成文档](../SignalR-Integration.md) +* **分布式架构中的实时消息** (使用 SingalR & RabbitMQ) + * [源码](https://github.com/abpframework/abp-samples/tree/master/SignalRTieredDemo) + * [文章](https://community.abp.io/articles/real-time-messaging-in-a-distributed-architecture-using-abp-framework-singalr-rabbitmq-daf47e17) * **Dashboard Demo**: 一个简单的应用程序,展示了如何在ASP.NET Core MVC UI中使用widget系统. * [源码](https://github.com/abpframework/abp-samples/tree/master/DashboardDemo) * [Widget 文档](../UI/AspNetCore/Widgets.md) @@ -50,15 +50,20 @@ * [文本模板文档](../Text-Templating.md) * **存储过程 Demo**: 演示如何以最佳实践使用存储过程,数据库视图和函数. * [源码](https://github.com/abpframework/abp-samples/tree/master/StoredProcedureDemo) +* **无密码认证**: 演示如何添加自定义令牌提供者使用链接验证用户身份,而不是输入密码. + * [源码](https://github.com/abpframework/abp-samples/tree/master/PasswordlessAuthentication) + * [文章](https://community.abp.io/articles/implementing-passwordless-authentication-with-asp.net-core-identity-c25l8koj) * **自定义认证**: 如何为ASP.NET Core MVC / Razor Pages应用程序自定义身份验证的解决方案. * [源码](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization) - * 相关 "[How To](../How-To/Index.md)" 文档: - * [Azure Active Directory 认证](../How-To/Azure-Active-Directory-Authentication-MVC.md) - * [自定义登录页面](../How-To/Customize-Login-Page-MVC.md) - * [自定义 SignIn Manager](../How-To/Customize-SignIn-Manager.md) + * 相关文章: + * [Azure Active Directory 认证](https://community.abp.io/articles/how-to-use-the-azure-active-directory-authentication-for-mvc-razor-page-applications-4603b9cf) + * [自定义登录页面](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd) + * [自定义 SignIn Manager](https://community.abp.io/articles/how-to-customize-the-signin-manager-3e858753) * **空的ASP.NET Core应用程序**: 从基本的ASP.NET Core应用程序使用ABP框架. * [源码](https://github.com/abpframework/abp-samples/tree/master/BasicAspNetCoreApplication) * [文档](../Getting-Started-AspNetCore-Application.md) +* **GRPC Demo**: 演示如何将gRPC服务添加到基于ABP框架的Web应用程序以及如何从控制台应用程序使用它. + * [源码](https://github.com/abpframework/abp-samples/tree/master/GrpcDemo) * **空的控制台应用程序**: 从基本的控制台应用程序安装ABP框架. * [源码](https://github.com/abpframework/abp-samples/tree/master/BasicConsoleApplication) * [文档](../Getting-Started-Console-Application.md) \ No newline at end of file diff --git a/docs/zh-Hans/Startup-Templates/Application.md b/docs/zh-Hans/Startup-Templates/Application.md index 534a26d8fb..58287cef5a 100644 --- a/docs/zh-Hans/Startup-Templates/Application.md +++ b/docs/zh-Hans/Startup-Templates/Application.md @@ -59,6 +59,20 @@ abp new Acme.BookStore -d mongodb ### 指定移动应用程序框架 +此模板支持以下移动应用程序框架: + +- `react-native`: React Native + +使用 `-m` (或 `--mobile`) 选项指定移动应用程序框架: + +````bash +abp new Acme.BookStore -m react-native +```` + +如果未指定,不会创建移动应用程序. + +### 指定移动应用程序框架 + 该模板支持以下移动应用程序框架: - `react-native`: React Native diff --git a/docs/zh-Hans/UI/Angular/Environment.md b/docs/zh-Hans/UI/Angular/Environment.md new file mode 100644 index 0000000000..cb82a640d5 --- /dev/null +++ b/docs/zh-Hans/UI/Angular/Environment.md @@ -0,0 +1 @@ +TODO... \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Migration-Guide-v3.md b/docs/zh-Hans/UI/Angular/Migration-Guide-v3.md index eb16c21e03..fd40affc55 100644 --- a/docs/zh-Hans/UI/Angular/Migration-Guide-v3.md +++ b/docs/zh-Hans/UI/Angular/Migration-Guide-v3.md @@ -450,4 +450,4 @@ export function switchLogos(store: Store) { ## 下一步是什么? -* [服务代理](Service-Proxies.md) \ No newline at end of file +* [环境](./Environment.md) \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Multi-Tenancy.md b/docs/zh-Hans/UI/Angular/Multi-Tenancy.md new file mode 100644 index 0000000000..cb82a640d5 --- /dev/null +++ b/docs/zh-Hans/UI/Angular/Multi-Tenancy.md @@ -0,0 +1 @@ +TODO... \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Permission-Management.md b/docs/zh-Hans/UI/Angular/Permission-Management.md index 7f28035105..08496f03fe 100644 --- a/docs/zh-Hans/UI/Angular/Permission-Management.md +++ b/docs/zh-Hans/UI/Angular/Permission-Management.md @@ -4,7 +4,7 @@ 你可以使用 `ConfigState` 的 `getGrantedPolicy` 选择器获取经过身份验证的用户的权限. -你可以从Store中获取权限的布尔值: +你可以获取权限的布尔值: ```js import { Store } from '@ngxs/store'; @@ -78,4 +78,4 @@ const routes: Routes = [ ## 下一步是什么? -* [确认弹层](./Confirmation-Service.md) \ No newline at end of file +* [多租户](./Multi-Tenancy.md) \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Toaster-Service.md b/docs/zh-Hans/UI/Angular/Toaster-Service.md index 045cf9f2cf..405e1b6400 100644 --- a/docs/zh-Hans/UI/Angular/Toaster-Service.md +++ b/docs/zh-Hans/UI/Angular/Toaster-Service.md @@ -24,7 +24,7 @@ class DemoComponent { ### 如何显示一个Toast Overlay ```js -this.toast.success('Message', 'Title'); +this.toaster.success('Message', 'Title'); ``` - `ToasterService` 方法接收三个参数,分别是 `message`, `title`, 和 `options`. @@ -70,9 +70,9 @@ const options: Partial = { 已打开的toast overlay可以通过手动调用 `remove` 方法传递指定的 toast `id`删除. ```js -const toastId = this.toast.success('Message', 'Title') +const toastId = this.toaster.success('Message', 'Title') -this.toast.remove(toastId); +this.toaster.remove(toastId); ``` ### 如何删除所有的Toasts @@ -80,7 +80,7 @@ this.toast.remove(toastId); 可以手动调用 `clear` 方法删除所有的已打开的toasts. ```js -this.toast.clear(); +this.toaster.clear(); ``` ## API diff --git a/docs/zh-Hans/UI/AspNetCore/Customization-User-Interface.md b/docs/zh-Hans/UI/AspNetCore/Customization-User-Interface.md index c4a90a9f1a..7daf6c5d4b 100644 --- a/docs/zh-Hans/UI/AspNetCore/Customization-User-Interface.md +++ b/docs/zh-Hans/UI/AspNetCore/Customization-User-Interface.md @@ -157,7 +157,7 @@ public class MyLoginModel : LoginModel ## 重写静态资源 -重写模块的静态资源(像JavaScript,Css或图片文件)是很简单的. 只需要在解决方案的相同路径创建文件,虚拟文件系统会自动处理它. +重写模块的静态资源(像JavaScript,Css或图片文件)是很简单的. 只需要在解决方案的相同路径创建文件,[虚拟文件系统](../../Virtual-File-System.md)会自动处理它. ## 操作捆绑 diff --git a/docs/zh-Hans/Upgrading.md b/docs/zh-Hans/Upgrading.md new file mode 100644 index 0000000000..cb82a640d5 --- /dev/null +++ b/docs/zh-Hans/Upgrading.md @@ -0,0 +1 @@ +TODO... \ No newline at end of file diff --git a/docs/zh-Hans/Virtual-File-System.md b/docs/zh-Hans/Virtual-File-System.md index 6952c4d5da..e2e4c9e865 100644 --- a/docs/zh-Hans/Virtual-File-System.md +++ b/docs/zh-Hans/Virtual-File-System.md @@ -27,13 +27,20 @@ 如果需要添加多个文件, 这样做会很乏味. 作为选择, 你可以直接编辑 **.csproj** 文件: +````C# + + + + +```` + +此配置以递归方式添加项目的 **MyResources** 文件夹下的所有文件(包括将来新添加的文件). + 如果文件名包含一些特殊字符,在项目/程序集中嵌入文件可能会导致问题. 为了克服这个限制; 1. 将[Microsoft.Extensions.FileProviders.Embedded](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Embedded) NuGet包添加到包含嵌入式资源的项目中. 2. 添加 `true` 到 `.csproj` 文件的 `...` 部分中. -此配置以递归方式添加项目的 **MyResources** 文件夹下的所有文件(包括将来新添加的文件). - > 尽管这两个步骤是可选的,并且ABP无需这些配置即可工作,但强烈建议你这样做. ### 配置AbpVirtualFileSystemOptions @@ -74,53 +81,12 @@ Configure(options => * 你的项目有一个名为 `MyFiles` 的目录. * 你只想添加 `MyFiles` 目录到虚拟文件系统. -#### 在开发过程中处理嵌入式文件 - -将文件嵌入到模块程序集中并能够通过引用程序集(或添加nuget包)在另一个项目中使用它对于创建可重用模块非常有价值. 但是, 这使得开发模块本身变得有点困难. - -假设你正在开发一个包含嵌入式JavaScript文件的模块. 当你更改文件时, 你必须重新编译项目, 重新启动应用程序并刷新浏览器页面以使更改生效. 显然, 这是非常耗时和乏味的. - -我们需要的是应用程序在开发时直接使用物理文件的能力, 让浏览器刷新时同步JavaScript文件的任何更改. `ReplaceEmbeddedByPhysical` 方法使其成为可能. - -下面的示例展示了应用程序依赖于包含嵌入文件的模块("MyModule"), 并且应用程序可以在开发过程中直接使用模块的源代码. - -````C# -[DependsOn(typeof(MyModule))] -public class MyWebAppModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - - if (hostingEnvironment.IsDevelopment()) //only for development time - { - Configure(options => - { - options.FileSets.ReplaceEmbeddedByPhysical( - Path.Combine( - hostingEnvironment.ContentRootPath, - string.Format( - "..{0}MyModuleProject", - Path.DirectorySeparatorChar - ) - ) - ); - }); - } - } -} -```` - -上面的代码假设`MyWebAppModule`和`MyModule`是Visual Studio解决方案中的两个不同的项目, `MyWebAppModule`依赖于`MyModule`. - -> [应用程序启动模板]已经为本地化文件应用这个方法,所以当你更改一个本地化文件时,它会自动检测到更改. - ## IVirtualFileProvider 将文件嵌入到程序集中并注册到虚拟文件系统后,可以使用 `IVirtualFileProvider` 接口来获取文件或目录内容: ````C# -public class MyService +public class MyService : ITransientDependency { private readonly IVirtualFileProvider _virtualFileProvider; @@ -129,7 +95,7 @@ public class MyService _virtualFileProvider = virtualFileProvider; } - public void Foo() + public void Test() { //Getting a single file var file = _virtualFileProvider @@ -154,7 +120,9 @@ public class MyService #### 虚拟文件中间件 -虚拟文件中间件用于向客户端/浏览器提供嵌入式(js, css, image ...)文件, 就像 **wwwroot** 文件夹中的物理(静态)文件一样. 在静态文件中间件之后添加它, 如下所示: +虚拟文件中间件用于向客户端/浏览器提供嵌入式(js, css, image ...)文件, 就像 **wwwroot** 文件夹中的物理(静态)文件一样. 它同时涵盖了物理文件. + +在你ASP.NET Core中间件配置中替换 `app.UseStaticFiles()` 为 `app.UseVirtualFiles()`: ````C# app.UseVirtualFiles(); @@ -170,6 +138,62 @@ app.UseVirtualFiles(); * Pages * Views +* Components * Themes 这允许你可以在 `.cshtml` 文件附近添加 `.js`, `.css`... 文件,更易于开发和维护你的项目. + +#### 在开发过程中处理嵌入式文件 + +将文件嵌入到模块程序集中并能够通过引用程序集(或添加nuget包)在另一个项目中使用它对于创建可重用模块非常有价值. 但是, 这使得开发模块本身变得有点困难. + +假设你正在开发一个包含嵌入式JavaScript文件的模块. 当你更改文件时, 你必须重新编译项目, 重新启动应用程序并刷新浏览器页面以使更改生效. 显然, 这是非常耗时和乏味的. + +我们需要的是应用程序在开发时直接使用物理文件的能力, 让浏览器刷新时同步JavaScript文件的任何更改. `ReplaceEmbeddedByPhysical` 方法使其成为可能. + +下面的示例展示了应用程序依赖于包含嵌入文件的模块("MyModule"), 并且应用程序可以在开发过程中直接使用模块的源代码. + +````C# +[DependsOn(typeof(MyModule))] +public class MyWebAppModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + if (hostingEnvironment.IsDevelopment()) //only for development time + { + Configure(options => + { + options.FileSets.ReplaceEmbeddedByPhysical( + Path.Combine( + hostingEnvironment.ContentRootPath, + string.Format( + "..{0}MyModuleProject", + Path.DirectorySeparatorChar + ) + ) + ); + }); + } + } +} +```` + +上面的代码假设`MyWebAppModule`和`MyModule`是Visual Studio解决方案中的两个不同的项目, `MyWebAppModule`依赖于`MyModule`. + +> [应用程序启动模板]已经为本地化文件应用这个方法,所以当你更改一个本地化文件时,它会自动检测到更改. + +## 替换/重写虚拟文件 + +虚拟文件系统在运行时创建一个统一的文件系统,其中实际的文件在开发时被分配到不同的模块中. + +如果两个模块将文件添加到相同的虚拟路径(如`my-path/my-file.css`),之后添加的模块将替换/替换前一个([模块依赖](Module-Development-Basics.md)顺序决定了添加文件的顺序). + +此功能允许你的应用程序可以覆盖/替换定义应用程序所使用的模块的任何虚拟文件. 这是ABP框架的基本可扩展性功能之一. + +因此,如果需要替换模块的文件,只需在模块/应用程序中完全相同的路径中创建该文件. + +### 物理文件 + +物理文件总是覆盖虚拟文件. 这意味着如果你把一个文件放在 `/wwwroot/my-folder/my-file.css`,它将覆盖虚拟文件系统相同位置的文件.因此你需要知道在模块中定义的文件路径来覆盖它们. \ No newline at end of file diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index df72d6e3df..5df3376507 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -4,21 +4,16 @@ "text": "入门", "items": [ { - "text": "从启动模板开始", + "text": "Web应用程序", "path": "Getting-Started.md" }, { - "text": "从空项目开始", - "items": [ - { - "text": "使用ASP.NET Core Web Application", - "path": "Getting-Started-AspNetCore-Application.md" - }, - { - "text": "使用Console Application", - "path": "Getting-Started-Console-Application.md" - } - ] + "text": "控制台应用程序", + "path": "Startup-Templates/Console.md" + }, + { + "text": "空Web应用程序t", + "path": "Getting-Started-AspNetCore-Application.md" } ] }, @@ -66,10 +61,6 @@ } ] }, - { - "text": "\"如何\" 指南", - "path": "How-To/Index.md" - }, { "text": "从ASP.NET Boilerplate迁移", "path": "AspNet-Boilerplate-Migration-Guide.md" @@ -201,6 +192,19 @@ "path": "Object-To-Object-Mapping.md" }, + { + "text": "邮件发送", + "items": [ + { + "text": "邮件发送系统", + "path": "Emailing.md" + }, + { + "text": "MailKit集成", + "path": "MailKit.md" + } + ] + }, { "text": "BLOB存储", "items": [ @@ -397,6 +401,10 @@ "text": "v2.x 到 v3 迁移指南", "path": "UI/Angular/Migration-Guide-v3.md" }, + { + "text": "环境", + "path": "UI/Angular/Environment.md" + }, { "text": "服务代理", "path": "UI/Angular/Service-Proxies.md" @@ -413,6 +421,10 @@ "text": "权限管理", "path": "UI/Angular/Permission-Management.md" }, + { + "text": "多租户", + "path": "UI/Angular/Multi-Tenancy.md" + }, { "text": "确认弹层", "path": "UI/Angular/Confirmation-Service.md" @@ -635,6 +647,10 @@ "text": "微服务架构", "path": "Microservice-Architecture.md" }, + { + "text": "预览版本", + "path": "Previews.md" + }, { "text": "每日构建", "path": "Nightly-Builds.md" @@ -643,6 +659,10 @@ "text": "路线图", "path": "Road-Map.md" }, + { + "text": "升级", + "path": "Upgrading.md" + }, { "text": "贡献指南", "path": "Contribution/Index.md" diff --git a/docs/zh-Hans/images/replace-email-layout.png b/docs/zh-Hans/images/replace-email-layout.png new file mode 100644 index 0000000000..67db895f92 Binary files /dev/null and b/docs/zh-Hans/images/replace-email-layout.png differ diff --git a/docs/zh-Hans/images/solution-files-non-mvc.png b/docs/zh-Hans/images/solution-files-non-mvc.png index 880cf20d46..323991b95c 100644 Binary files a/docs/zh-Hans/images/solution-files-non-mvc.png and b/docs/zh-Hans/images/solution-files-non-mvc.png differ diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index f45ae3d9dc..51484f7c04 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -335,6 +335,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MultiLingualObject EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MultiLingualObject.Tests", "test\Volo.Abp.MultiLingualObject.Tests\Volo.Abp.MultiLingualObject.Tests.csproj", "{A30D63B0-E952-4052-BAEE-38B8BF924093}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Http.Client.IdentityModel.WebAssembly", "src\Volo.Abp.Http.Client.IdentityModel.WebAssembly\Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj", "{3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.Client.Common", "src\Volo.Abp.AspNetCore.Mvc.Client.Common\Volo.Abp.AspNetCore.Mvc.Client.Common.csproj", "{8A22D962-016E-474A-8BB7-F831F0ABF3AC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Components.WebAssembly", "src\Volo.Abp.AspNetCore.Components.WebAssembly\Volo.Abp.AspNetCore.Components.WebAssembly.csproj", "{E1A62D10-F2FB-4040-BD60-11A3934058DF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlazoriseUI", "src\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj", "{4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme", "src\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj", "{ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Components.WebAssembly.Theming", "src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj", "{29CA7471-4E3E-4E75-8B33-001DDF682F01}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Autofac.WebAssembly", "src\Volo.Abp.Autofac.WebAssembly\Volo.Abp.Autofac.WebAssembly.csproj", "{37F89B0B-1C6B-426F-A5EE-676D1956D9E9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Authentication.OpenIdConnect", "src\Volo.Abp.AspNetCore.Authentication.OpenIdConnect\Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj", "{DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -989,6 +1005,38 @@ Global {231F1581-AA21-44C3-BF27-51EB3AD5355C}.Debug|Any CPU.Build.0 = Debug|Any CPU {231F1581-AA21-44C3-BF27-51EB3AD5355C}.Release|Any CPU.ActiveCfg = Release|Any CPU {231F1581-AA21-44C3-BF27-51EB3AD5355C}.Release|Any CPU.Build.0 = Release|Any CPU + {3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8}.Release|Any CPU.Build.0 = Release|Any CPU + {8A22D962-016E-474A-8BB7-F831F0ABF3AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A22D962-016E-474A-8BB7-F831F0ABF3AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A22D962-016E-474A-8BB7-F831F0ABF3AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A22D962-016E-474A-8BB7-F831F0ABF3AC}.Release|Any CPU.Build.0 = Release|Any CPU + {E1A62D10-F2FB-4040-BD60-11A3934058DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1A62D10-F2FB-4040-BD60-11A3934058DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1A62D10-F2FB-4040-BD60-11A3934058DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1A62D10-F2FB-4040-BD60-11A3934058DF}.Release|Any CPU.Build.0 = Release|Any CPU + {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5}.Release|Any CPU.Build.0 = Release|Any CPU + {ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABC27C10-C0FF-44CB-B4FF-A09C0B79F695}.Release|Any CPU.Build.0 = Release|Any CPU + {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29CA7471-4E3E-4E75-8B33-001DDF682F01}.Release|Any CPU.Build.0 = Release|Any CPU + {37F89B0B-1C6B-426F-A5EE-676D1956D9E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37F89B0B-1C6B-426F-A5EE-676D1956D9E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37F89B0B-1C6B-426F-A5EE-676D1956D9E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37F89B0B-1C6B-426F-A5EE-676D1956D9E9}.Release|Any CPU.Build.0 = Release|Any CPU + {DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5}.Release|Any CPU.Build.0 = Release|Any CPU {C9142DED-1F6C-4385-A37D-81E46B233306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C9142DED-1F6C-4385-A37D-81E46B233306}.Debug|Any CPU.Build.0 = Debug|Any CPU {C9142DED-1F6C-4385-A37D-81E46B233306}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1164,6 +1212,14 @@ Global {C1D891B0-AE83-42CB-987D-425A2787DE78} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {04F44063-C952-403A-815F-EFB778BDA125} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {231F1581-AA21-44C3-BF27-51EB3AD5355C} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {8A22D962-016E-474A-8BB7-F831F0ABF3AC} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {E1A62D10-F2FB-4040-BD60-11A3934058DF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {4EBDDB1B-D6C5-4FAE-B5A7-2171B18CDFA5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {ABC27C10-C0FF-44CB-B4FF-A09C0B79F695} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {29CA7471-4E3E-4E75-8B33-001DDF682F01} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {37F89B0B-1C6B-426F-A5EE-676D1956D9E9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {DEFE3DB2-EA4F-4F90-87FC-B25D64427BC5} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {C9142DED-1F6C-4385-A37D-81E46B233306} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {A30D63B0-E952-4052-BAEE-38B8BF924093} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs new file mode 100644 index 0000000000..56886f679e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.OAuth.Claims; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.MultiTenancy; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class AbpOpenIdConnectExtensions + { + public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder) + => builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, _ => { }); + + public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, Action configureOptions) + => builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, configureOptions); + + public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, Action configureOptions) + => builder.AddAbpOpenIdConnect(authenticationScheme, OpenIdConnectDefaults.DisplayName, configureOptions); + + public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action configureOptions) + { + return builder.AddOpenIdConnect(authenticationScheme, displayName, options => + { + options.ClaimActions.MapAbpClaimTypes(); + + options.Events = new OpenIdConnectEvents + { + OnAuthorizationCodeReceived = receivedContext => + { + var tenantKey = receivedContext.HttpContext.RequestServices + .GetRequiredService>().Value.TenantKey; + + if (receivedContext.HttpContext.Request != null && + receivedContext.Request.Cookies.ContainsKey(tenantKey)) + { + receivedContext.TokenEndpointRequest.SetParameter(tenantKey, + receivedContext.Request.Cookies[tenantKey]); + } + + return Task.CompletedTask; + } + }; + + configureOptions?.Invoke(options); + }); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj new file mode 100644 index 0000000000..30f56491c5 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj @@ -0,0 +1,20 @@ + + + + + + + netcoreapp3.1 + + + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo/Abp/AspNetCore/Authentication/OpenIdConnect/AbpAspNetCoreAuthenticationOpenIdConnectModule.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo/Abp/AspNetCore/Authentication/OpenIdConnect/AbpAspNetCoreAuthenticationOpenIdConnectModule.cs new file mode 100644 index 0000000000..13a8fd5c04 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo/Abp/AspNetCore/Authentication/OpenIdConnect/AbpAspNetCoreAuthenticationOpenIdConnectModule.cs @@ -0,0 +1,14 @@ +using Volo.Abp.AspNetCore.Authentication.OAuth; +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.AspNetCore.Authentication.OpenIdConnect +{ + [DependsOn( + typeof(AbpMultiTenancyModule), + typeof(AbpAspNetCoreAuthenticationOAuthModule))] + public class AbpAspNetCoreAuthenticationOpenIdConnectModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/AbpAspNetCoreComponentsWebAssemblyBasicTheme.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/AbpAspNetCoreComponentsWebAssemblyBasicTheme.cs new file mode 100644 index 0000000000..74c81ed72c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/AbpAspNetCoreComponentsWebAssemblyBasicTheme.cs @@ -0,0 +1,20 @@ +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme +{ + [DependsOn( + typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule) + )] + public class AbpAspNetCoreComponentsWebAssemblyBasicThemeModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AdditionalAssemblies.Add(typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeModule).Assembly); + }); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor new file mode 100644 index 0000000000..e237cea555 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Pages/Authentication.razor @@ -0,0 +1,7 @@ +@page "/authentication/{action}" +@using Microsoft.AspNetCore.Components.WebAssembly.Authentication + + +@code{ + [Parameter] public string Action { get; set; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/App.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/App.razor new file mode 100644 index 0000000000..b6bba50bab --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/App.razor @@ -0,0 +1,27 @@ +@using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing +@using Microsoft.Extensions.Options +@inject IOptions RouterOptions + + + + + + @if (!context.User.Identity.IsAuthenticated) + { + + } + else + { +

You are not authorized to access this resource.

+ } +
+
+
+ + +

Sorry, there's nothing at this address.

+
+
+
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor new file mode 100644 index 0000000000..8c7b348f7d --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor @@ -0,0 +1,65 @@ +@using Volo.Abp.Localization +@using System.Globalization +@using System.Collections.Immutable +@inject ILanguageProvider LanguageProvider +@inject IJSRuntime JsRuntime +@if (_otherLanguages != null && _otherLanguages.Any()) +{ + + + @_currentLanguage.DisplayName + + + @foreach (var language in _otherLanguages) + { + @language.DisplayName + } + + +} +@code { + private IReadOnlyList _otherLanguages; + private LanguageInfo _currentLanguage; + + protected override async Task OnInitializedAsync() + { + var selectedLanguageName = await JsRuntime.InvokeAsync( + "localStorage.getItem", + "Abp.SelectedLanguage" + ); + + _otherLanguages = await LanguageProvider.GetLanguagesAsync(); + + if (!_otherLanguages.Any()) + { + return; + } + + if (!selectedLanguageName.IsNullOrWhiteSpace()) + { + _currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName); + } + + if (_currentLanguage == null) + { + _currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name); + } + + if (_currentLanguage == null) + { + _currentLanguage = _otherLanguages.FirstOrDefault(); + } + + _otherLanguages = _otherLanguages.Where(l => l != _currentLanguage).ToImmutableList(); + } + + private async Task ChangeLanguageAsync(LanguageInfo language) + { + await JsRuntime.InvokeVoidAsync( + "localStorage.setItem", + "Abp.SelectedLanguage", language.UiCultureName + ); + + await JsRuntime.InvokeVoidAsync("location.reload"); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor new file mode 100644 index 0000000000..88a005d7bf --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor @@ -0,0 +1,41 @@ +@using Microsoft.AspNetCore.Components.WebAssembly.Authentication +@using Volo.Abp.Users +@inject ICurrentUser CurrentUser +@inject NavigationManager Navigation +@inject SignOutSessionStateManager SignOutManager + + + + + @CurrentUser.UserName + + + @if (Menu != null) + { + @foreach (var menuItem in Menu.Items) + { + @menuItem.DisplayName + } + } + + Logout + + + + + Log in + + +@code{ + + private void NavigateTo(string uri) + { + Navigation.NavigateTo(uri); + } + + private async Task BeginSignOut() + { + await SignOutManager.SetSignOutState(); + NavigateTo("authentication/logout"); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs new file mode 100644 index 0000000000..e0ad688513 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic +{ + public partial class LoginDisplay + { + [Inject] protected IMenuManager MenuManager { get; set; } + + protected ApplicationMenu Menu { get; set; } + + protected override async Task OnInitializedAsync() + { + Menu = await MenuManager.GetAsync(StandardMenus.User); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor new file mode 100644 index 0000000000..af88212f0a --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor @@ -0,0 +1,29 @@ +@inherits LayoutComponentBase +@using Volo.Abp.Ui.Branding +@inject IBrandingProvider BrandingProvider + +
+ @Body +
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor new file mode 100644 index 0000000000..e1ede1c0fd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor @@ -0,0 +1,7 @@ +@if (Menu != null) +{ + foreach (var menuItem in Menu.Items) + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs new file mode 100644 index 0000000000..e47603e163 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic +{ + public partial class NavMenu + { + [Inject] protected IMenuManager MenuManager { get; set; } + + protected ApplicationMenu Menu { get; set; } + + private bool collapseNavMenu = true; + + private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; + + protected override async Task OnInitializedAsync() + { + Menu = await MenuManager.GetAsync(StandardMenus.Main); + } + + private void ToggleNavMenu() + { + collapseNavMenu = !collapseNavMenu; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenuItem.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenuItem.razor new file mode 100644 index 0000000000..8194896f61 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenuItem.razor @@ -0,0 +1,52 @@ +@using Volo.Abp.UI.Navigation +@{ + var elementId = MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_"); + var cssClass = string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass; + var url = string.IsNullOrEmpty(MenuItem.Url) ? "#" : MenuItem.Url; +} +@if (MenuItem.IsLeaf) +{ + if (MenuItem.Url != null) + { + + } +} +else +{ + + +} +@code { + [Parameter] + public ApplicationMenuItem MenuItem { get; set; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/RedirectToLogin.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/RedirectToLogin.razor new file mode 100644 index 0000000000..b535ae4216 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/RedirectToLogin.razor @@ -0,0 +1,8 @@ +@inject NavigationManager Navigation +@using Microsoft.AspNetCore.Components.WebAssembly.Authentication +@code { + protected override void OnInitialized() + { + Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}"); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/_Imports.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/_Imports.razor new file mode 100644 index 0000000000..f1ebc76453 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/_Imports.razor @@ -0,0 +1,10 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.WebAssembly.Http +@using Microsoft.JSInterop +@using Volo.Abp.AspNetCore.Components.WebAssembly +@using Blazorise +@using Blazorise.DataGrid diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj new file mode 100644 index 0000000000..783af0b202 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj @@ -0,0 +1,16 @@ + + + + + + + netstandard2.1 + 3.0 + Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.css b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.css new file mode 100644 index 0000000000..fc47596044 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.css @@ -0,0 +1,105 @@ + +#main-navbar-tools a.dropdown-toggle { + text-decoration: none; + color: #fff; +} + +.navbar .dropdown-submenu { + position: relative; +} +.navbar .dropdown-menu { + margin: 0; + padding: 0; +} + .navbar .dropdown-menu a { + font-size: .9em; + padding: 10px 15px; + display: block; + min-width: 210px; + text-align: left; + border-radius: 0.25rem; + min-height: 44px; + } +.navbar .dropdown-submenu a::after { + transform: rotate(-90deg); + position: absolute; + right: 16px; + top: 18px; +} +.navbar .dropdown-submenu .dropdown-menu { + top: 0; + left: 100%; +} + +.card-header .btn { + padding: 2px 6px; +} +.card-header h5 { + margin: 0; +} +.container > .card { + box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; +} + +@media screen and (min-width: 768px) { + .navbar .dropdown:hover > .dropdown-menu { + display: block; + } + + .navbar .dropdown-submenu:hover > .dropdown-menu { + display: block; + } +} +.input-validation-error { + border-color: #dc3545; +} +.field-validation-error { + font-size: 0.8em; +} + +.dataTables_scrollBody { + min-height: 248px; +} + +div.dataTables_wrapper div.dataTables_info { + padding-top: 11px; + white-space: nowrap; +} + +div.dataTables_wrapper div.dataTables_length label { + padding-top: 10px; + margin-bottom: 0; +} + +.rtl .dropdown-menu-right { + right: auto; + left: 0; +} + + .rtl .dropdown-menu-right a { + text-align: right; + } + +.rtl .navbar .dropdown-menu a { + text-align: right; +} +.rtl .navbar .dropdown-submenu .dropdown-menu { + top: 0; + left: auto; + right: 100%; +} + +/* TEMP */ + +.navbar-dark .navbar-nav .nav-link { + color: #000 !important; +} + +.navbar-nav > .nav-item > .nav-link, +.navbar-nav > .nav-item > .dropdown > .nav-link { + color: #fff !important; +} + +.navbar-nav>.nav-item>div>button{ + color:#fff; +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.js b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.js new file mode 100644 index 0000000000..8a5b94c7c6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/wwwroot/theme.js @@ -0,0 +1,16 @@ +$(function () { + $('.dropdown-menu a.dropdown-toggle').on('click', function (e) { + if (!$(this).next().hasClass('show')) { + $(this).parents('.dropdown-menu').first().find('.show').removeClass("show"); + } + + var $subMenu = $(this).next(".dropdown-menu"); + $subMenu.toggleClass('show'); + + $(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function (e) { + $('.dropdown-submenu .show').removeClass("show"); + }); + + return false; + }); +}); \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpAspNetCoreComponentsWebAssemblyThemingModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpAspNetCoreComponentsWebAssemblyThemingModule.cs new file mode 100644 index 0000000000..867e01467f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpAspNetCoreComponentsWebAssemblyThemingModule.cs @@ -0,0 +1,17 @@ +using Volo.Abp.BlazoriseUI; +using Volo.Abp.Http.Client.IdentityModel.WebAssembly; +using Volo.Abp.Modularity; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming +{ + [DependsOn( + typeof(AbpBlazoriseUIModule), + typeof(AbpHttpClientIdentityModelWebAssemblyModule), + typeof(AbpUiNavigationModule) + )] + public class AbpAspNetCoreComponentsWebAssemblyThemingModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Routing/AbpBlazorRouterOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Routing/AbpBlazorRouterOptions.cs new file mode 100644 index 0000000000..107fc9b078 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Routing/AbpBlazorRouterOptions.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing +{ + public class AbpRouterOptions + { + public Assembly AppAssembly { get; set; } + + public RouterAssemblyList AdditionalAssemblies { get; } + + public AbpRouterOptions() + { + AdditionalAssemblies = new RouterAssemblyList(); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Routing/RouterAssemblyList.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Routing/RouterAssemblyList.cs new file mode 100644 index 0000000000..e7a4a49343 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Routing/RouterAssemblyList.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Reflection; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing +{ + public class RouterAssemblyList : List + { + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj new file mode 100644 index 0000000000..86902f7038 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj @@ -0,0 +1,17 @@ + + + + + + + netstandard2.1 + 3.0 + + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs new file mode 100644 index 0000000000..865a6f0edc --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs @@ -0,0 +1,51 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.Modularity; + +namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting +{ + public static class AbpWebAssemblyHostBuilderExtensions + { + public static IAbpApplicationWithExternalServiceProvider AddApplication( + [NotNull] this WebAssemblyHostBuilder builder, + Action options) + where TStartupModule : IAbpModule + { + Check.NotNull(builder, nameof(builder)); + + builder.Services.AddSingleton(builder.Configuration); + builder.Services.AddSingleton(builder); + + var application = builder.Services.AddApplication(opts => + { + options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); + }); + + return application; + } + + public static async Task InitializeAsync( + [NotNull] this IAbpApplicationWithExternalServiceProvider application, + [NotNull] IServiceProvider serviceProvider) + { + Check.NotNull(application, nameof(application)); + Check.NotNull(serviceProvider, nameof(serviceProvider)); + + application.Initialize(serviceProvider); + + using (var scope = serviceProvider.CreateScope()) + { + await scope.ServiceProvider + .GetRequiredService() + .InitializeAsync(); + } + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj new file mode 100644 index 0000000000..89f2d08b49 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo.Abp.AspNetCore.Components.WebAssembly.csproj @@ -0,0 +1,27 @@ + + + + + + + netstandard2.1 + Volo.Abp.AspNetCore.Components.WebAssembly + Volo.Abp.AspNetCore.Components.WebAssembly + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs new file mode 100644 index 0000000000..db6109e55a --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; +using Volo.Abp.UI; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + [DependsOn( + typeof(AbpAspNetCoreMvcClientCommonModule), + typeof(AbpUiModule) + )] + public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(options => + { + options.ProxyClientBuildActions.Add((_, builder) => + { + builder.AddHttpMessageHandler(); + }); + }); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpBlazorClientHttpMessageHandler.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpBlazorClientHttpMessageHandler.cs new file mode 100644 index 0000000000..7d59042806 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpBlazorClientHttpMessageHandler.cs @@ -0,0 +1,42 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.JSInterop; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency + { + private readonly IJSRuntime _jsRuntime; + + public AbpBlazorClientHttpMessageHandler(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + await SetLanguageAsync(request, cancellationToken); + + return await base.SendAsync(request, cancellationToken); + } + + private async Task SetLanguageAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var selectedLanguage = await _jsRuntime.InvokeAsync( + "localStorage.getItem", + cancellationToken, + "Abp.SelectedLanguage" + ); + + if (!selectedLanguage.IsNullOrWhiteSpace()) + { + request.Headers.AcceptLanguage.Clear(); + request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage)); + } + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpWebAssemblyApplicationCreationOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpWebAssemblyApplicationCreationOptions.cs new file mode 100644 index 0000000000..54fdf7edb4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpWebAssemblyApplicationCreationOptions.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public class AbpWebAssemblyApplicationCreationOptions + { + public WebAssemblyHostBuilder HostBuilder { get; } + + public AbpApplicationCreationOptions ApplicationCreationOptions { get; } + + public AbpWebAssemblyApplicationCreationOptions( + WebAssemblyHostBuilder hostBuilder, + AbpApplicationCreationOptions applicationCreationOptions) + { + HostBuilder = hostBuilder; + ApplicationCreationOptions = applicationCreationOptions; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs new file mode 100644 index 0000000000..df41c996b6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs @@ -0,0 +1,20 @@ +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public class ApplicationConfigurationCache : ISingletonDependency + { + protected ApplicationConfigurationDto Configuration { get; set; } + + public virtual ApplicationConfigurationDto Get() + { + return Configuration; + } + + internal void Set(ApplicationConfigurationDto configuration) + { + Configuration = configuration; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IUiMessageService.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IUiMessageService.cs new file mode 100644 index 0000000000..2c834ddc87 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IUiMessageService.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public interface IUiMessageService + { + Task InfoAsync(string message, string title = null); + + Task SuccessAsync(string message, string title = null); + + Task WarnAsync(string message, string title = null); + + Task ErrorAsync(string message, string title = null); + + Task ConfirmAsync(string message, string title = null); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/UiMessageService.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/UiMessageService.cs new file mode 100644 index 0000000000..16fe041de4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/UiMessageService.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; +using Microsoft.JSInterop; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + //TODO: Implement with sweetalert in a new package + public class UiMessageService : IUiMessageService, ITransientDependency + { + protected IJSRuntime JsRuntime { get; } + + public UiMessageService(IJSRuntime jsRuntime) + { + JsRuntime = jsRuntime; + } + + public async Task InfoAsync(string message, string title = null) + { + await JsRuntime.InvokeVoidAsync("alert", message); + } + + public async Task SuccessAsync(string message, string title = null) + { + await JsRuntime.InvokeVoidAsync("alert", message); + } + + public async Task WarnAsync(string message, string title = null) + { + await JsRuntime.InvokeVoidAsync("alert", message); + } + + public async Task ErrorAsync(string message, string title = null) + { + await JsRuntime.InvokeVoidAsync("alert", message); + } + + public async Task ConfirmAsync(string message, string title = null) + { + return await JsRuntime.InvokeAsync("confirm", message); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs new file mode 100644 index 0000000000..e403a8cfe9 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs @@ -0,0 +1,50 @@ +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.DynamicProxying; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency + { + protected IHttpClientProxy Proxy { get; } + + protected ApplicationConfigurationCache Cache { get; } + + public WebAssemblyCachedApplicationConfigurationClient( + IHttpClientProxy proxy, + ApplicationConfigurationCache cache) + { + Proxy = proxy; + Cache = cache; + } + + public virtual async Task InitializeAsync() + { + Cache.Set(await Proxy.Service.GetAsync()); + } + + public virtual Task GetAsync() + { + return Task.FromResult(GetConfigurationByChecking()); + } + + public virtual ApplicationConfigurationDto Get() + { + return GetConfigurationByChecking(); + } + + private ApplicationConfigurationDto GetConfigurationByChecking() + { + var configuration = Cache.Get(); + if (configuration == null) + { + throw new AbpException( + $"{nameof(WebAssemblyCachedApplicationConfigurationClient)} should be initialized before using it."); + } + + return configuration; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs new file mode 100644 index 0000000000..3c252ebe5e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Security.Claims; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Claims; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public class WebAssemblyCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency + { + protected ICachedApplicationConfigurationClient ConfigurationClient { get; } + + public WebAssemblyCurrentPrincipalAccessor( + ICachedApplicationConfigurationClient configurationClient) + { + ConfigurationClient = configurationClient; + } + + protected override ClaimsPrincipal GetClaimsPrincipal() + { + var configuration = ConfigurationClient.Get(); + + var claims = new List(); + + if (!configuration.CurrentUser.UserName.IsNullOrWhiteSpace()) + { + claims.Add(new Claim(AbpClaimTypes.UserName,configuration.CurrentUser.UserName)); + } + + if (!configuration.CurrentUser.Email.IsNullOrWhiteSpace()) + { + claims.Add(new Claim(AbpClaimTypes.Email,configuration.CurrentUser.Email)); + } + + if (configuration.CurrentUser.Id != null) + { + claims.Add(new Claim(AbpClaimTypes.UserId,configuration.CurrentUser.Id.ToString())); + } + + if (configuration.CurrentUser.TenantId != null) + { + claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentUser.TenantId.ToString())); + } + else if (configuration.CurrentTenant.Id != null) + { + claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentTenant.Id.ToString())); + } + + foreach (var role in configuration.CurrentUser.Roles) + { + claims.Add(new Claim(AbpClaimTypes.Role, role)); + } + + return new ClaimsPrincipal(new ClaimsIdentity(claims)); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyRemoteTenantStore.cs new file mode 100644 index 0000000000..ebe170cfa8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyRemoteTenantStore.cs @@ -0,0 +1,69 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.MultiTenancy; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.DynamicProxying; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly +{ + public class WebAssemblyRemoteTenantStore : ITenantStore, ITransientDependency + { + protected IHttpClientProxy Proxy { get; } + + public WebAssemblyRemoteTenantStore( + IHttpClientProxy proxy) + { + Proxy = proxy; + } + + public async Task FindAsync(string name) + { + //TODO: Cache + + return CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name)); + } + + public async Task FindAsync(Guid id) + { + //TODO: Cache + + return CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id)); + } + + public TenantConfiguration Find(string name) + { + //TODO: Cache + + return AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name))); + } + + public TenantConfiguration Find(Guid id) + { + //TODO: Cache + + return AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id))); + } + + protected virtual TenantConfiguration CreateTenantConfiguration(FindTenantResultDto tenantResultDto) + { + if (!tenantResultDto.Success || tenantResultDto.TenantId == null) + { + return null; + } + + return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name); + } + + protected virtual string CreateCacheKey(string tenantName) + { + return $"RemoteTenantStore_Name_{tenantName}"; + } + + protected virtual string CreateCacheKey(Guid tenantId) + { + return $"RemoteTenantStore_Id_{tenantId:N}"; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs index d757b2f5f8..1d0268556f 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs @@ -5,7 +5,7 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.AspNetCore.MultiTenancy { [DependsOn( - typeof(AbpMultiTenancyModule), + typeof(AbpMultiTenancyModule), typeof(AbpAspNetCoreModule) )] public class AbpAspNetCoreMultiTenancyModule : AbpModule @@ -15,6 +15,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy Configure(options => { options.TenantResolvers.Add(new QueryStringTenantResolveContributor()); + options.TenantResolvers.Add(new FormTenantResolveContributor()); options.TenantResolvers.Add(new RouteTenantResolveContributor()); options.TenantResolvers.Add(new HeaderTenantResolveContributor()); options.TenantResolvers.Add(new CookieTenantResolveContributor()); diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs new file mode 100644 index 0000000000..5e70559f0c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs @@ -0,0 +1,23 @@ +using System.Linq; +using Microsoft.AspNetCore.Http; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.AspNetCore.MultiTenancy +{ + public class FormTenantResolveContributor : HttpTenantResolveContributorBase + { + public const string ContributorName = "Form"; + + public override string Name => ContributorName; + + protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) + { + if (httpContext.Request == null || !httpContext.Request.Form.Any()) + { + return null; + } + + return httpContext.Request.Form[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey]; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj new file mode 100644 index 0000000000..dc672d842f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj @@ -0,0 +1,24 @@ + + + + + + + netstandard2.0 + Volo.Abp.AspNetCore.Mvc.Client.Common + Volo.Abp.AspNetCore.Mvc.Client.Common + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs new file mode 100644 index 0000000000..de5e80ff64 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Caching; +using Volo.Abp.Http.Client; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + [DependsOn( + typeof(AbpHttpClientModule), + typeof(AbpAspNetCoreMvcContractsModule), + typeof(AbpCachingModule), + typeof(AbpLocalizationModule) + )] + public class AbpAspNetCoreMvcClientCommonModule : AbpModule + { + public const string RemoteServiceName = "AbpMvcClient"; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(AbpAspNetCoreMvcContractsModule).Assembly, + RemoteServiceName, + asDefaultServices: false + ); + + Configure(options => + { + options.GlobalContributors.Add(); + }); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs similarity index 76% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs index 71d9d8cddf..d08ca7013e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs @@ -5,6 +5,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Client { public interface ICachedApplicationConfigurationClient { + Task InitializeAsync(); + Task GetAsync(); + + ApplicationConfigurationDto Get(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLanguageProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteLanguageProvider.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLanguageProvider.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteLanguageProvider.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs similarity index 94% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs index d60256a501..f8502fce78 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Localization; -using Volo.Abp.Threading; namespace Volo.Abp.AspNetCore.Mvc.Client { @@ -55,7 +54,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client private Dictionary GetResourceOrNull() { - var applicationConfigurationDto = AsyncHelper.RunSync(() => _applicationConfigurationClient.GetAsync()); + var applicationConfigurationDto = _applicationConfigurationClient.Get(); var resource = applicationConfigurationDto .Localization.Values @@ -69,4 +68,4 @@ namespace Volo.Abp.AspNetCore.Mvc.Client return resource; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemotePermissionChecker.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteSettingProvider.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj index 87641365b2..aa11e602a1 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj @@ -17,10 +17,7 @@
- - - - +
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs index 6c306073c5..1186b48ae7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs @@ -1,33 +1,11 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Caching; -using Volo.Abp.Http.Client; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; +using Volo.Abp.Modularity; namespace Volo.Abp.AspNetCore.Mvc.Client { [DependsOn( - typeof(AbpHttpClientModule), - typeof(AbpAspNetCoreMvcContractsModule), - typeof(AbpCachingModule), - typeof(AbpLocalizationModule) + typeof(AbpAspNetCoreMvcClientCommonModule) )] public class AbpAspNetCoreMvcClientModule : AbpModule { - public const string RemoteServiceName = "AbpMvcClient"; - - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddHttpClientProxies( - typeof(AbpAspNetCoreMvcContractsModule).Assembly, - RemoteServiceName, - asDefaultServices: false - ); - - Configure(options => - { - options.GlobalContributors.Add(); - }); - } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs similarity index 76% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs index 1fbb72bb3e..a357d959b2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs @@ -12,14 +12,14 @@ using Volo.Abp.Users; namespace Volo.Abp.AspNetCore.Mvc.Client { - public class CachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency + public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency { protected IHttpContextAccessor HttpContextAccessor { get; } protected IHttpClientProxy Proxy { get; } protected ICurrentUser CurrentUser { get; } protected IDistributedCache Cache { get; } - public CachedApplicationConfigurationClient( + public MvcCachedApplicationConfigurationClient( IDistributedCache cache, IHttpClientProxy proxy, ICurrentUser currentUser, @@ -31,6 +31,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Client Cache = cache; } + public async Task InitializeAsync() + { + await GetAsync(); + } + public async Task GetAsync() { var cacheKey = CreateCacheKey(); @@ -58,9 +63,22 @@ namespace Volo.Abp.AspNetCore.Mvc.Client return configuration; } + public ApplicationConfigurationDto Get() + { + var cacheKey = CreateCacheKey(); + var httpContext = HttpContextAccessor?.HttpContext; + + if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration) + { + return configuration; + } + + return AsyncHelper.RunSync(GetAsync); + } + protected virtual string CreateCacheKey() { return $"ApplicationConfiguration_{CurrentUser.Id?.ToString("N") ?? "Anonymous"}_{CultureInfo.CurrentUICulture.Name}"; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs similarity index 97% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteTenantStore.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index 236387823c..2b6a272d64 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -11,13 +11,13 @@ using Volo.Abp.Threading; namespace Volo.Abp.AspNetCore.Mvc.Client { - public class RemoteTenantStore : ITenantStore, ITransientDependency + public class MvcRemoteTenantStore : ITenantStore, ITransientDependency { protected IHttpClientProxy Proxy { get; } protected IHttpContextAccessor HttpContextAccessor { get; } protected IDistributedCache Cache { get; } - public RemoteTenantStore( + public MvcRemoteTenantStore( IHttpClientProxy proxy, IHttpContextAccessor httpContextAccessor, IDistributedCache cache) @@ -120,7 +120,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client { return tenantConfiguration; } - + tenantConfiguration = Cache.GetOrAdd( cacheKey, () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id))), diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj index a979cfa637..04b2e7ec59 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj @@ -4,7 +4,7 @@ - netcoreapp3.1 + netstandard2.0 Volo.Abp.AspNetCore.Mvc.Contracts Volo.Abp.AspNetCore.Mvc.Contracts $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs index ce08bebe87..5d1f6d8414 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs @@ -13,8 +13,18 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations public string UserName { get; set; } + public string Name { get; set; } + + public string SurName { get; set; } + public string Email { get; set; } + public bool EmailVerified { get; set; } + + public string PhoneNumber { get; set; } + + public bool PhoneNumberVerified { get; set; } + public string[] Roles { get; set; } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/AlertsDemo/AlertsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/AlertsDemo/AlertsDemoViewComponent.cs index 2599c317cf..4e1bdd133f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/AlertsDemo/AlertsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/AlertsDemo/AlertsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.AlertsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class AlertsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/AlertsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BadgesDemo/BadgesDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BadgesDemo/BadgesDemoViewComponent.cs index bdc47336cd..727b613926 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BadgesDemo/BadgesDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BadgesDemo/BadgesDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BadgesDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class BadgesDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/BadgesDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BordersDemo/BordersDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BordersDemo/BordersDemoViewComponent.cs index 2ba33feb54..b288653010 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BordersDemo/BordersDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BordersDemo/BordersDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BordersDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class BordersDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/BordersDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BreadcrumbsDemo/BreadcrumbsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BreadcrumbsDemo/BreadcrumbsDemoViewComponent.cs index e700acb667..0853f2b195 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BreadcrumbsDemo/BreadcrumbsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/BreadcrumbsDemo/BreadcrumbsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BreadcrumbsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class BreadcrumbsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/BreadcrumbsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonGroupsDemo/ButtonGroupsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonGroupsDemo/ButtonGroupsDemoViewComponent.cs index ff5b917d40..cb134673ac 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonGroupsDemo/ButtonGroupsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonGroupsDemo/ButtonGroupsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ButtonGroupsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class ButtonGroupsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/ButtonGroupsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonsDemo/ButtonsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonsDemo/ButtonsDemoViewComponent.cs index 9d7a2dd3f9..5cb6cf0779 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonsDemo/ButtonsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ButtonsDemo/ButtonsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ButtonsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class ButtonsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/ButtonsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CardsDemo/CardsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CardsDemo/CardsDemoViewComponent.cs index f192285f80..0dafa65c70 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CardsDemo/CardsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CardsDemo/CardsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CardsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class CardsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/CardsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CarouselDemo/CarouselDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CarouselDemo/CarouselDemoViewComponent.cs index 8ef48c1da5..e57b840269 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CarouselDemo/CarouselDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CarouselDemo/CarouselDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CarouselDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class CarouselDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/CarouselDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CollapseDemo/CollapseDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CollapseDemo/CollapseDemoViewComponent.cs index 28ccbcb447..44df03d3c4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CollapseDemo/CollapseDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/CollapseDemo/CollapseDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CollapseDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class CollapseDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/CollapseDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DropdownsDemo/DropdownsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DropdownsDemo/DropdownsDemoViewComponent.cs index 136ad70481..1eb9be8cf5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DropdownsDemo/DropdownsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DropdownsDemo/DropdownsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.DropdownsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class DropdownsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/DropdownsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DynamicFormsDemo/DynamicFormsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DynamicFormsDemo/DynamicFormsDemoViewComponent.cs index 3681eda627..e768536a9f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DynamicFormsDemo/DynamicFormsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/DynamicFormsDemo/DynamicFormsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.DynamicFormsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class DynamicFormsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/DynamicFormsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/FormElementsDemo/FormElementsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/FormElementsDemo/FormElementsDemoViewComponent.cs index 01c477ecb1..22bcde1e52 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/FormElementsDemo/FormElementsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/FormElementsDemo/FormElementsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.FormElementsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class FormElementsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/FormElementsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/GridsDemo/GridsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/GridsDemo/GridsDemoViewComponent.cs index 99f99186cd..e5e031afc0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/GridsDemo/GridsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/GridsDemo/GridsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.GridsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class GridsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/GridsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ListGroupsDemo/ListGroupsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ListGroupsDemo/ListGroupsDemoViewComponent.cs index 9e0f89e325..3c48462650 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ListGroupsDemo/ListGroupsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ListGroupsDemo/ListGroupsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ListGroupsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class ListGroupsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/ListGroupsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ModalsDemo/ModalsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ModalsDemo/ModalsDemoViewComponent.cs index 272ea4a480..e4c2ce2c5e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ModalsDemo/ModalsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ModalsDemo/ModalsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ModalsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class ModalsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/ModalsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavbarsDemo/NavbarsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavbarsDemo/NavbarsDemoViewComponent.cs index e282f1b923..470857a845 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavbarsDemo/NavbarsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavbarsDemo/NavbarsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.NavbarsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class NavbarsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/NavbarsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavsDemo/NavsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavsDemo/NavsDemoViewComponent.cs index 5bc0363193..7149894f46 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavsDemo/NavsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/NavsDemo/NavsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.NavsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class NavsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/NavsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PaginatorDemo/PaginatorDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PaginatorDemo/PaginatorDemoViewComponent.cs index 46b8cb2db1..92a0b19ead 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PaginatorDemo/PaginatorDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PaginatorDemo/PaginatorDemoViewComponent.cs @@ -1,10 +1,14 @@ using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.PaginatorDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class PaginatorDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/PaginatorDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PopoversDemo/PopoversDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PopoversDemo/PopoversDemoViewComponent.cs index 6114918165..408676f63d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PopoversDemo/PopoversDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/PopoversDemo/PopoversDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.PopoversDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class PopoversDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/PopoversDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ProgressBarsDemo/ProgressBarsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ProgressBarsDemo/ProgressBarsDemoViewComponent.cs index acaf9b4135..33f1e09e15 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ProgressBarsDemo/ProgressBarsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/ProgressBarsDemo/ProgressBarsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ProgressBarsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class ProgressBarsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/ProgressBarsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TablesDemo/TablesDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TablesDemo/TablesDemoViewComponent.cs index e40ecae321..181a58f07f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TablesDemo/TablesDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TablesDemo/TablesDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TablesDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class TablesDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/TablesDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TabsDemo/TabsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TabsDemo/TabsDemoViewComponent.cs index 00f3b5c2c4..e001b5157d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TabsDemo/TabsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TabsDemo/TabsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TabsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class TabsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/TabsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TooltipsDemo/TooltipsDemoViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TooltipsDemo/TooltipsDemoViewComponent.cs index a23fede627..7d30f09a79 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TooltipsDemo/TooltipsDemoViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/Demos/TooltipsDemo/TooltipsDemoViewComponent.cs @@ -1,9 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TooltipsDemo { - [Widget] + [Widget( + StyleTypes = new []{ typeof(PrismjsStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(PrismjsScriptBundleContributor) } + )] public class TooltipsDemoViewComponent : AbpViewComponent { public const string ViewPath = "/Views/Components/Themes/Shared/Demos/TooltipsDemo/Default.cshtml"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs index 5b3bd7791a..27fc4c4d13 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.FileProviders; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers; +using Volo.Abp.Guids; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.TagHelpers @@ -17,10 +18,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.S public string Title { get; set; } private readonly IVirtualFileProvider _virtualFileProvider; + private readonly IGuidGenerator _guidGenerator; - public AbpComponentDemoSectionTagHelper(IVirtualFileProvider virtualFileProvider) + public AbpComponentDemoSectionTagHelper( + IVirtualFileProvider virtualFileProvider, + IGuidGenerator guidGenerator) { _virtualFileProvider = virtualFileProvider; + _guidGenerator = guidGenerator; } public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) @@ -29,34 +34,69 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.S var content = await output.GetChildContentAsync(); - output.PreContent.AppendHtml("
"); - output.PreContent.AppendHtml($"

{Title}

"); - output.PreContent.AppendHtml("
"); + var previewId = _guidGenerator.Create(); + var codeBlockId = _guidGenerator.Create(); + + var codeBlockTabId = _guidGenerator.Create(); + var tagHelperCodeBlockId = _guidGenerator.Create(); + var bootstrapCodeBlockId = _guidGenerator.Create(); + + output.PreContent.AppendHtml("
"); + output.PreContent.AppendHtml("
"); + output.PreContent.AppendHtml("
"); + output.PreContent.AppendHtml($"

{Title}

"); + output.PreContent.AppendHtml("
"); + output.PreContent.AppendHtml(""); + output.PreContent.AppendHtml("
"); // col-auto + output.PreContent.AppendHtml("
"); // row + output.PreContent.AppendHtml("
"); // card-header + output.PreContent.AppendHtml("
"); + output.PreContent.AppendHtml($"
"); + output.PreContent.AppendHtml($"
"); + /* component rendering here */ - output.PostContent.AppendHtml("
"); //abp-component-demo-section-body - AppendRawSource(output); - AppendBootstrapSource(output, content); - output.PostContent.AppendHtml("
"); //abp-component-demo-section - } - private static void AppendBootstrapSource(TagHelperOutput output, TagHelperContent content) - { - output.PostContent.AppendHtml("
"); - output.PostContent.AppendHtml("

Bootstrap

"); - output.PostContent.AppendHtml("
");
-            output.PostContent.Append(content.GetContent());
+            output.PostContent.AppendHtml("
"); // tab-pane + output.PostContent.AppendHtml($"
"); + + /* CodeBlock tabs */ + + output.PostContent.AppendHtml($"
    "); + output.PostContent.AppendHtml("
  • "); + output.PostContent.AppendHtml($"Abp Tag Helper"); + output.PostContent.AppendHtml("
  • "); + output.PostContent.AppendHtml("
  • "); + output.PostContent.AppendHtml($"Bootstrap"); + output.PostContent.AppendHtml("
  • "); + output.PostContent.AppendHtml("
"); + output.PostContent.AppendHtml($"
"); + + output.PostContent.AppendHtml($"
"); + output.PostContent.AppendHtml("
");
+            output.PostContent.AppendHtml("");
+            output.PostContent.Append(GetRawDemoSource());
+            output.PostContent.AppendHtml("");
             output.PostContent.AppendHtml("
"); output.PostContent.AppendHtml("
"); - } - - private void AppendRawSource(TagHelperOutput output) - { - output.PostContent.AppendHtml("
"); - output.PostContent.AppendHtml("

ABP Tag Helpers

"); - output.PostContent.AppendHtml("
");
-            output.PostContent.Append(GetRawDemoSource());
+            
+            output.PostContent.AppendHtml($"
"); + output.PostContent.AppendHtml("
");
+            output.PostContent.AppendHtml("");
+            output.PostContent.Append(content.GetContent());
+            output.PostContent.AppendHtml("");
             output.PostContent.AppendHtml("
"); output.PostContent.AppendHtml("
"); + + output.PostContent.AppendHtml("
"); // tab-content + output.PostContent.AppendHtml("
"); // tab-pane + output.PostContent.AppendHtml("
"); // tab-content + output.PostContent.AppendHtml("
"); // card-body + output.PostContent.AppendHtml("
"); // card } private string GetRawDemoSource() diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js index 9a2052b267..8d85f6f6d8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js @@ -231,7 +231,7 @@ (function () { datatables.createAjax = function (serverMethod, inputAction) { return function (requestData, callback, settings) { - var input = inputAction ? inputAction() : {}; + var input = inputAction ? inputAction(requestData, settings) : {}; //Paging if (settings.oInit.paging) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index 54815d6ff5..89bf3e7cfc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -117,7 +117,12 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations Id = _currentUser.Id, TenantId = _currentUser.TenantId, UserName = _currentUser.UserName, + SurName = _currentUser.SurName, + Name = _currentUser.Name, Email = _currentUser.Email, + EmailVerified = _currentUser.EmailVerified, + PhoneNumber = _currentUser.PhoneNumber, + PhoneNumberVerified = _currentUser.PhoneNumberVerified, Roles = _currentUser.Roles }; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider.cs index c9b7cb21b3..e5131592d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider.cs @@ -27,8 +27,13 @@ namespace Volo.Abp.AspNetCore.Mvc.DataAnnotations { return new DynamicMaxLengthAttributeAdapter((DynamicMaxLengthAttribute) attribute, stringLocalizer); } - + + if (type == typeof(DynamicRangeAttribute)) + { + return new DynamicRangeAttributeAdapter((DynamicRangeAttribute) attribute, stringLocalizer); + } + return _defaultAdapter.GetAttributeAdapter(attribute, stringLocalizer); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/DynamicRangeAttributeAdapter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/DynamicRangeAttributeAdapter.cs new file mode 100644 index 0000000000..d3344c20f2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/DynamicRangeAttributeAdapter.cs @@ -0,0 +1,46 @@ +using System; +using System.Globalization; +using Microsoft.AspNetCore.Mvc.DataAnnotations; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using Microsoft.Extensions.Localization; +using Volo.Abp.Validation; + +namespace Volo.Abp.AspNetCore.Mvc.DataAnnotations +{ + public class DynamicRangeAttributeAdapter : AttributeAdapterBase + { + private readonly string _max; + private readonly string _min; + + public DynamicRangeAttributeAdapter( + DynamicRangeAttribute attribute, + IStringLocalizer stringLocalizer) + : base(attribute, stringLocalizer) + { + _min = Convert.ToString(Attribute.Minimum,CultureInfo.InvariantCulture); + _max = Convert.ToString(Attribute.Maximum,CultureInfo.InvariantCulture); + } + + public override void AddValidation(ClientModelValidationContext context) + { + Check.NotNull(context, nameof(context)); + + MergeAttribute(context.Attributes, "data-val", "true"); + MergeAttribute(context.Attributes, "data-val-range", GetErrorMessage(context)); + MergeAttribute(context.Attributes, "data-val-range-min", _min); + MergeAttribute(context.Attributes, "data-val-range-max", _max); + } + + public override string GetErrorMessage(ModelValidationContextBase validationContext) + { + Check.NotNull(validationContext, nameof(validationContext)); + + return GetErrorMessage( + validationContext.ModelMetadata, + validationContext.ModelMetadata.GetDisplayName(), + Attribute.Minimum, + Attribute.Maximum + ); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs index cd2f393104..339b249e49 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs @@ -72,7 +72,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling } var errorInfo = new RemoteServiceErrorInfo(); - + if (exception is IUserFriendlyException) { errorInfo.Message = exception.Message; @@ -101,6 +101,8 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling errorInfo.Message = L["InternalServerErrorMessage"]; } + errorInfo.Data = exception.Data; + return errorInfo; } @@ -190,7 +192,6 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling return exception; } - protected virtual RemoteServiceErrorInfo CreateDetailedErrorInfoFromException(Exception exception) { var detailBuilder = new StringBuilder(); @@ -213,7 +214,7 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling detailBuilder.AppendLine(exception.GetType().Name + ": " + exception.Message); //Additional info for UserFriendlyException - if (exception is IUserFriendlyException && + if (exception is IUserFriendlyException && exception is IHasErrorDetails) { var details = ((IHasErrorDetails) exception).Details; diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/FodyWeavers.xml b/framework/src/Volo.Abp.Autofac.WebAssembly/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac.WebAssembly/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/FodyWeavers.xsd b/framework/src/Volo.Abp.Autofac.WebAssembly/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac.WebAssembly/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs b/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs new file mode 100644 index 0000000000..427ae3ddf6 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyApplicationCreationOptionsAutofacExtensions.cs @@ -0,0 +1,23 @@ +using System; +using Autofac; +using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.AspNetCore.Components.WebAssembly; + +namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting +{ + public static class AbpWebAssemblyApplicationCreationOptionsAutofacExtensions + { + public static void UseAutofac( + [NotNull] this AbpWebAssemblyApplicationCreationOptions options, + [CanBeNull] Action configure = null) + { + options.HostBuilder.Services.AddAutofacServiceProviderFactory(); + options.HostBuilder.ConfigureContainer( + options.HostBuilder.Services.GetSingletonInstance>(), + configure + ); + } + } +} diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj b/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj new file mode 100644 index 0000000000..6d03439a85 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac.WebAssembly/Volo.Abp.Autofac.WebAssembly.csproj @@ -0,0 +1,16 @@ + + + + + + + netstandard2.1 + + + + + + + + + diff --git a/framework/src/Volo.Abp.Autofac.WebAssembly/Volo/Abp/Autofac/WebAssembly/AbpAutofacWebAssemblyModule.cs b/framework/src/Volo.Abp.Autofac.WebAssembly/Volo/Abp/Autofac/WebAssembly/AbpAutofacWebAssemblyModule.cs new file mode 100644 index 0000000000..361d3daf85 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac.WebAssembly/Volo/Abp/Autofac/WebAssembly/AbpAutofacWebAssemblyModule.cs @@ -0,0 +1,14 @@ +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Autofac.WebAssembly +{ + [DependsOn( + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreComponentsWebAssemblyModule) + )] + public class AbpAutofacWebAssemblyModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.Autofac/Volo/Abp/AbpAutofacAbpApplicationCreationOptionsExtensions.cs b/framework/src/Volo.Abp.Autofac/Volo/Abp/AbpAutofacAbpApplicationCreationOptionsExtensions.cs index f632c11495..56b91dea2d 100644 --- a/framework/src/Volo.Abp.Autofac/Volo/Abp/AbpAutofacAbpApplicationCreationOptionsExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Volo/Abp/AbpAutofacAbpApplicationCreationOptionsExtensions.cs @@ -8,9 +8,22 @@ namespace Volo.Abp { public static void UseAutofac(this AbpApplicationCreationOptions options) { - var builder = new ContainerBuilder(); - options.Services.AddObjectAccessor(builder); - options.Services.AddSingleton((IServiceProviderFactory) new AbpAutofacServiceProviderFactory(builder)); + options.Services.AddAutofacServiceProviderFactory(); + } + + public static AbpAutofacServiceProviderFactory AddAutofacServiceProviderFactory(this IServiceCollection services) + { + return services.AddAutofacServiceProviderFactory(new ContainerBuilder()); + } + + public static AbpAutofacServiceProviderFactory AddAutofacServiceProviderFactory(this IServiceCollection services, ContainerBuilder containerBuilder) + { + var factory = new AbpAutofacServiceProviderFactory(containerBuilder); + + services.AddObjectAccessor(containerBuilder); + services.AddSingleton((IServiceProviderFactory) factory); + + return factory; } } } diff --git a/framework/src/Volo.Abp.BlazoriseUI/FodyWeavers.xml b/framework/src/Volo.Abp.BlazoriseUI/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.BlazoriseUI/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.BlazoriseUI/FodyWeavers.xsd b/framework/src/Volo.Abp.BlazoriseUI/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.BlazoriseUI/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj new file mode 100644 index 0000000000..f7875a0f4a --- /dev/null +++ b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj @@ -0,0 +1,24 @@ + + + + + + + netstandard2.1 + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.BlazoriseUI/Volo/Abp/BlazoriseUI/AbpBlazoriseModule.cs b/framework/src/Volo.Abp.BlazoriseUI/Volo/Abp/BlazoriseUI/AbpBlazoriseModule.cs new file mode 100644 index 0000000000..716f36b1ea --- /dev/null +++ b/framework/src/Volo.Abp.BlazoriseUI/Volo/Abp/BlazoriseUI/AbpBlazoriseModule.cs @@ -0,0 +1,23 @@ +using Blazorise; +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.Modularity; + +namespace Volo.Abp.BlazoriseUI +{ + [DependsOn( + typeof(AbpAspNetCoreComponentsWebAssemblyModule) + )] + public class AbpBlazoriseUIModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + ConfigureBlazorise(context); + } + + private void ConfigureBlazorise(ServiceConfigurationContext context) + { + context.Services + .AddBlazorise(); + } + } +} diff --git a/framework/src/Volo.Abp.BlazoriseUI/Volo/Abp/BlazoriseUI/BlazoriseCrudPageBase.cs b/framework/src/Volo.Abp.BlazoriseUI/Volo/Abp/BlazoriseUI/BlazoriseCrudPageBase.cs new file mode 100644 index 0000000000..5889737745 --- /dev/null +++ b/framework/src/Volo.Abp.BlazoriseUI/Volo/Abp/BlazoriseUI/BlazoriseCrudPageBase.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Blazorise; +using Blazorise.DataGrid; +using Localization.Resources.AbpUi; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.ObjectMapping; + +namespace Volo.Abp.BlazoriseUI +{ + public abstract class BlazoriseCrudPageBase + : BlazoriseCrudPageBase + where TAppService : ICrudAppService + where TEntityDto : IEntityDto, new() + { + + } + + public abstract class BlazoriseCrudPageBase + : BlazoriseCrudPageBase + where TAppService : ICrudAppService + where TEntityDto : IEntityDto, new() + where TGetListInput : new() + { + + } + + public abstract class BlazoriseCrudPageBase + : BlazoriseCrudPageBase + where TAppService : ICrudAppService + where TEntityDto : IEntityDto + where TCreateInput : new() + where TGetListInput : new() + { + + } + + public abstract class BlazoriseCrudPageBase + : BlazoriseCrudPageBase + where TAppService : ICrudAppService + where TEntityDto : IEntityDto + where TCreateInput : new() + where TUpdateInput : new() + where TGetListInput : new() + { + + } + + public abstract class BlazoriseCrudPageBase + : OwningComponentBase + where TAppService : ICrudAppService + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto + where TCreateInput : new() + where TUpdateInput : new() + where TGetListInput : new() + { + [Inject] protected TAppService AppService { get; set; } + [Inject] protected IUiMessageService UiMessageService { get; set; } + [Inject] protected IStringLocalizer UiLocalizer { get; set; } + + protected virtual int PageSize { get; } = LimitedResultRequestDto.DefaultMaxResultCount; + + protected int CurrentPage; + protected string CurrentSorting; + protected int? TotalCount; + protected IReadOnlyList Entities = Array.Empty(); + protected TCreateInput NewEntity; + protected TKey EditingEntityId; + protected TUpdateInput EditingEntity; + protected Modal CreateModal; + protected Modal EditModal; + + protected Type ObjectMapperContext { get; set; } + + protected IObjectMapper ObjectMapper + { + get + { + if (_objectMapper != null) + { + return _objectMapper; + } + + if (ObjectMapperContext == null) + { + return LazyGetRequiredService(ref _objectMapper); + } + + return LazyGetRequiredService( + typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), + ref _objectMapper + ); + } + } + + private IObjectMapper _objectMapper; + + protected TService LazyGetRequiredService(ref TService reference) + => LazyGetRequiredService(typeof(TService), ref reference); + + protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) + { + if (reference == null) + { + reference = (TRef) ScopedServices.GetRequiredService(serviceType); + } + + return reference; + } + + protected BlazoriseCrudPageBase() + { + NewEntity = new TCreateInput(); + EditingEntity = new TUpdateInput(); + } + + protected override async Task OnInitializedAsync() + { + await GetEntitiesAsync(); + } + + protected virtual async Task GetEntitiesAsync() + { + var input = await CreateGetListInputAsync(); + var result = await AppService.GetListAsync(input); + Entities = result.Items; + TotalCount = (int?) result.TotalCount; + } + + protected virtual Task CreateGetListInputAsync() + { + var input = new TGetListInput(); + + if (input is ISortedResultRequest sortedResultRequestInput) + { + sortedResultRequestInput.Sorting = CurrentSorting; + } + + if (input is IPagedResultRequest pagedResultRequestInput) + { + pagedResultRequestInput.SkipCount = CurrentPage * PageSize; + } + + if (input is ILimitedResultRequest limitedResultRequestInput) + { + limitedResultRequestInput.MaxResultCount = PageSize; + } + + return Task.FromResult(input); + } + + protected virtual async Task OnDataGridReadAsync(DataGridReadDataEventArgs e) + { + CurrentSorting = e.Columns + .Where(c => c.Direction != SortDirection.None) + .Select(c => c.Field + (c.Direction == SortDirection.Descending ? " DESC" : "")) + .JoinAsString(","); + CurrentPage = e.Page - 1; + + await GetEntitiesAsync(); + + StateHasChanged(); + } + + protected virtual Task OpenCreateModalAsync() + { + NewEntity = new TCreateInput(); + CreateModal.Show(); + return Task.CompletedTask; + } + + protected virtual Task CloseCreateModalAsync() + { + CreateModal.Hide(); + return Task.CompletedTask; + } + + protected virtual async Task OpenEditModalAsync(TKey id) + { + var entityDto = await AppService.GetAsync(id); + EditingEntityId = id; + EditingEntity = MapToEditingEntity(entityDto); + EditModal.Show(); + } + + protected virtual TUpdateInput MapToEditingEntity(TGetOutputDto entityDto) + { + return ObjectMapper.Map(entityDto); + } + + protected virtual Task CloseEditModalAsync() + { + EditModal.Hide(); + return Task.CompletedTask; + } + + protected virtual async Task CreateEntityAsync() + { + await AppService.CreateAsync(NewEntity); + await GetEntitiesAsync(); + CreateModal.Hide(); + } + + protected virtual async Task UpdateEntityAsync() + { + await AppService.UpdateAsync(EditingEntityId, EditingEntity); + await GetEntitiesAsync(); + EditModal.Hide(); + } + + protected virtual async Task DeleteEntityAsync(TGetListOutputDto entity) + { + if (!await UiMessageService.ConfirmAsync(GetDeleteConfirmationMessage(entity))) + { + return; + } + + await AppService.DeleteAsync(entity.Id); + await GetEntitiesAsync(); + } + + protected virtual string GetDeleteConfirmationMessage(TGetListOutputDto entity) + { + return UiLocalizer["ItemWillBeDeletedMessage"]; + } + } +} diff --git a/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobNamingNormalizer.cs b/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobNamingNormalizer.cs index b456d7abb6..cf8ff42973 100644 --- a/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobNamingNormalizer.cs +++ b/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobNamingNormalizer.cs @@ -1,46 +1,51 @@ -using System.Text.RegularExpressions; +using System.Globalization; +using System.Text.RegularExpressions; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.BlobStoring.Aliyun { public class AliyunBlobNamingNormalizer : IBlobNamingNormalizer, ITransientDependency { /// - /// Container names can contain only letters, numbers, and the dash (-) character - /// they can't start or end with the dash (-) character + /// Container names can contain only letters, numbers, and the dash (-) character + /// they can't start or end with the dash (-) character /// Container names must be from 3 through 63 characters long /// public virtual string NormalizeContainerName(string containerName) { - // All letters in a container name must be lowercase. - containerName = containerName.ToLower(); + using (CultureHelper.Use(CultureInfo.InvariantCulture)) + { + // All letters in a container name must be lowercase. + containerName = containerName.ToLower(); - // Container names can contain only letters, numbers, and the dash (-) character. - containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); + // Container names can contain only letters, numbers, and the dash (-) character. + containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); - // Every dash (-) character must be immediately preceded and followed by a letter or number; - // consecutive dashes are not permitted in container names. - // Container names must start or end with a letter or number - containerName = Regex.Replace(containerName, "-{2,}", "-"); - containerName = Regex.Replace(containerName, "^-", string.Empty); - containerName = Regex.Replace(containerName, "-$", string.Empty); + // Every dash (-) character must be immediately preceded and followed by a letter or number; + // consecutive dashes are not permitted in container names. + // Container names must start or end with a letter or number + containerName = Regex.Replace(containerName, "-{2,}", "-"); + containerName = Regex.Replace(containerName, "^-", string.Empty); + containerName = Regex.Replace(containerName, "-$", string.Empty); - // Container names must be from 3 through 63 characters long. - if (containerName.Length < 3) - { - var length = containerName.Length; - for (var i = 0; i < 3 - length; i++) + // Container names must be from 3 through 63 characters long. + if (containerName.Length < 3) { - containerName += "0"; + var length = containerName.Length; + for (var i = 0; i < 3 - length; i++) + { + containerName += "0"; + } } - } - if (containerName.Length > 63) - { - containerName = containerName.Substring(0, 63); - } + if (containerName.Length > 63) + { + containerName = containerName.Substring(0, 63); + } - return containerName; + return containerName; + } } public virtual string NormalizeBlobName(string blobName) diff --git a/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobNamingNormalizer.cs b/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobNamingNormalizer.cs index cd8eca021e..3779f9ff70 100644 --- a/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobNamingNormalizer.cs +++ b/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobNamingNormalizer.cs @@ -1,5 +1,7 @@ -using System.Text.RegularExpressions; +using System.Globalization; +using System.Text.RegularExpressions; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.BlobStoring.Aws { @@ -10,35 +12,38 @@ namespace Volo.Abp.BlobStoring.Aws /// public virtual string NormalizeContainerName(string containerName) { - // All letters in a container name must be lowercase. - containerName = containerName.ToLower(); + using (CultureHelper.Use(CultureInfo.InvariantCulture)) + { + // All letters in a container name must be lowercase. + containerName = containerName.ToLower(); - // Container names can contain only letters, numbers, and the dash (-) character. - containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); + // Container names can contain only letters, numbers, and the dash (-) character. + containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); - // Every dash (-) character must be immediately preceded and followed by a letter or number; - // consecutive dashes are not permitted in container names. - // Container names must start or end with a letter or number - containerName = Regex.Replace(containerName, "-{2,}", "-"); - containerName = Regex.Replace(containerName, "^-", string.Empty); - containerName = Regex.Replace(containerName, "-$", string.Empty); + // Every dash (-) character must be immediately preceded and followed by a letter or number; + // consecutive dashes are not permitted in container names. + // Container names must start or end with a letter or number + containerName = Regex.Replace(containerName, "-{2,}", "-"); + containerName = Regex.Replace(containerName, "^-", string.Empty); + containerName = Regex.Replace(containerName, "-$", string.Empty); - // Container names must be from 3 through 63 characters long. - if (containerName.Length < 3) - { - var length = containerName.Length; - for (var i = 0; i < 3 - length; i++) + // Container names must be from 3 through 63 characters long. + if (containerName.Length < 3) { - containerName += "0"; + var length = containerName.Length; + for (var i = 0; i < 3 - length; i++) + { + containerName += "0"; + } } - } - if (containerName.Length > 63) - { - containerName = containerName.Substring(0, 63); - } + if (containerName.Length > 63) + { + containerName = containerName.Substring(0, 63); + } - return containerName; + return containerName; + } } /// diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobNamingNormalizer.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobNamingNormalizer.cs index 43b479e08e..767a7b6fea 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobNamingNormalizer.cs +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobNamingNormalizer.cs @@ -1,5 +1,7 @@ -using System.Text.RegularExpressions; +using System.Globalization; +using System.Text.RegularExpressions; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.BlobStoring.Azure { @@ -10,35 +12,38 @@ namespace Volo.Abp.BlobStoring.Azure /// public virtual string NormalizeContainerName(string containerName) { - // All letters in a container name must be lowercase. - containerName = containerName.ToLower(); + using (CultureHelper.Use(CultureInfo.InvariantCulture)) + { + // All letters in a container name must be lowercase. + containerName = containerName.ToLower(); - // Container names can contain only letters, numbers, and the dash (-) character. - containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); + // Container names can contain only letters, numbers, and the dash (-) character. + containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); - // Every dash (-) character must be immediately preceded and followed by a letter or number; - // consecutive dashes are not permitted in container names. - // Container names must start or end with a letter or number - containerName = Regex.Replace(containerName, "-{2,}", "-"); - containerName = Regex.Replace(containerName, "^-", string.Empty); - containerName = Regex.Replace(containerName, "-$", string.Empty); + // Every dash (-) character must be immediately preceded and followed by a letter or number; + // consecutive dashes are not permitted in container names. + // Container names must start or end with a letter or number + containerName = Regex.Replace(containerName, "-{2,}", "-"); + containerName = Regex.Replace(containerName, "^-", string.Empty); + containerName = Regex.Replace(containerName, "-$", string.Empty); - // Container names must be from 3 through 63 characters long. - if (containerName.Length < 3) - { - var length = containerName.Length; - for (var i = 0; i < 3 - length; i++) + // Container names must be from 3 through 63 characters long. + if (containerName.Length < 3) { - containerName += "0"; + var length = containerName.Length; + for (var i = 0; i < 3 - length; i++) + { + containerName += "0"; + } } - } - if (containerName.Length > 63) - { - containerName = containerName.Substring(0, 63); - } + if (containerName.Length > 63) + { + containerName = containerName.Substring(0, 63); + } - return containerName; + return containerName; + } } /// diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobNamingNormalizer.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobNamingNormalizer.cs index f7d273dca7..94c19b07f8 100644 --- a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobNamingNormalizer.cs +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobNamingNormalizer.cs @@ -1,8 +1,10 @@ using System; +using System.Globalization; using System.Runtime; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.BlobStoring.FileSystem { @@ -27,15 +29,18 @@ namespace Volo.Abp.BlobStoring.FileSystem protected virtual string Normalize(string fileName) { - var os = _iosPlatformProvider.GetCurrentOSPlatform(); - if (os == OSPlatform.Windows) + using (CultureHelper.Use(CultureInfo.InvariantCulture)) { - // A filename cannot contain any of the following characters: \ / : * ? " < > | - // In order to support the directory included in the blob name, remove / and \ - fileName = Regex.Replace(fileName, "[:\\*\\?\"<>\\|]", string.Empty); - } + var os = _iosPlatformProvider.GetCurrentOSPlatform(); + if (os == OSPlatform.Windows) + { + // A filename cannot contain any of the following characters: \ / : * ? " < > | + // In order to support the directory included in the blob name, remove / and \ + fileName = Regex.Replace(fileName, "[:\\*\\?\"<>\\|]", string.Empty); + } - return fileName; + return fileName; + } } } } diff --git a/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobNamingNormalizer.cs b/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobNamingNormalizer.cs index d350910105..c4df24f91a 100644 --- a/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobNamingNormalizer.cs +++ b/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobNamingNormalizer.cs @@ -1,5 +1,7 @@ -using System.Text.RegularExpressions; +using System.Globalization; +using System.Text.RegularExpressions; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.BlobStoring.Minio { @@ -10,35 +12,38 @@ namespace Volo.Abp.BlobStoring.Minio /// public virtual string NormalizeContainerName(string containerName) { - // All letters in a container name must be lowercase. - containerName = containerName.ToLower(); + using (CultureHelper.Use(CultureInfo.InvariantCulture)) + { + // All letters in a container name must be lowercase. + containerName = containerName.ToLower(); - // Container names can contain only letters, numbers, and the dash (-) character. - containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); + // Container names can contain only letters, numbers, and the dash (-) character. + containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); - // Every dash (-) character must be immediately preceded and followed by a letter or number; - // consecutive dashes are not permitted in container names. - // Container names must start or end with a letter or number - containerName = Regex.Replace(containerName, "-{2,}", "-"); - containerName = Regex.Replace(containerName, "^-", string.Empty); - containerName = Regex.Replace(containerName, "-$", string.Empty); + // Every dash (-) character must be immediately preceded and followed by a letter or number; + // consecutive dashes are not permitted in container names. + // Container names must start or end with a letter or number + containerName = Regex.Replace(containerName, "-{2,}", "-"); + containerName = Regex.Replace(containerName, "^-", string.Empty); + containerName = Regex.Replace(containerName, "-$", string.Empty); - // Container names must be from 3 through 63 characters long. - if (containerName.Length < 3) - { - var length = containerName.Length; - for (var i = 0; i < 3 - length; i++) + // Container names must be from 3 through 63 characters long. + if (containerName.Length < 3) { - containerName += "0"; + var length = containerName.Length; + for (var i = 0; i < 3 - length; i++) + { + containerName += "0"; + } } - } - if (containerName.Length > 63) - { - containerName = containerName.Substring(0, 63); - } + if (containerName.Length > 63) + { + containerName = containerName.Substring(0, 63); + } - return containerName; + return containerName; + } } /// diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index d5ece4361f..39ecdb8183 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -286,6 +286,8 @@ namespace Volo.Abp.Cli.Commands return UiFramework.Mvc; case "angular": return UiFramework.Angular; + case "blazor": + return UiFramework.Blazor; default: return UiFramework.NotSpecified; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProxyCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProxyCommandBase.cs index 0116c809cb..7898ae7abc 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProxyCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProxyCommandBase.cs @@ -24,6 +24,7 @@ namespace Volo.Abp.Cli.Commands var defaultValue = prompt ? null : "__default"; var module = commandLineArgs.Options.GetOrNull(Options.Module.Short, Options.Module.Long) ?? defaultValue; + var apiName = commandLineArgs.Options.GetOrNull(Options.ApiName.Short, Options.ApiName.Long) ?? defaultValue; var source = commandLineArgs.Options.GetOrNull(Options.Source.Short, Options.Source.Long) ?? defaultValue; var target = commandLineArgs.Options.GetOrNull(Options.Target.Short, Options.Target.Long) ?? defaultValue; @@ -34,6 +35,11 @@ namespace Volo.Abp.Cli.Commands commandBuilder.Append($" --module {module}"); } + if (apiName != null) + { + commandBuilder.Append($" --api-name {apiName}"); + } + if (source != null) { commandBuilder.Append($" --source {source}"); @@ -100,6 +106,7 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine("Options:"); sb.AppendLine(""); sb.AppendLine("-m|--module (default: 'app') The name of the backend module you wish to generate proxies for."); + sb.AppendLine("-a|--api-name (default: 'default') The name of the API endpoint defined in the /src/environments/environment.ts."); sb.AppendLine("-s|--source (default: 'defaultProject') Angular project name to resolve the root namespace & API definition URL from."); sb.AppendLine("-t|--target (default: 'defaultProject') Angular project name to place generated code in."); sb.AppendLine("-p|--prompt Asks the options from the command line prompt (for the missing options)"); @@ -122,6 +129,12 @@ namespace Volo.Abp.Cli.Commands public const string Long = "module"; } + public static class ApiName + { + public const string Short = "a"; + public const string Long = "api-name"; + } + public static class Source { public const string Short = "s"; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs index fbe7fa675f..2d58474ed5 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs @@ -1,10 +1,13 @@ using System; +using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using NuGet.Versioning; using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Commands.Services; +using Volo.Abp.Cli.NuGet; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; @@ -13,12 +16,14 @@ namespace Volo.Abp.Cli.Commands public class SuiteCommand : IConsoleCommand, ITransientDependency { private readonly AbpNuGetIndexUrlService _nuGetIndexUrlService; + private readonly NuGetService _nuGetService; private const string SuitePackageName = "Volo.Abp.Suite"; public ILogger Logger { get; set; } - public SuiteCommand(AbpNuGetIndexUrlService nuGetIndexUrlService) + public SuiteCommand(AbpNuGetIndexUrlService nuGetIndexUrlService, NuGetService nuGetService) { _nuGetIndexUrlService = nuGetIndexUrlService; + _nuGetService = nuGetService; Logger = NullLogger.Instance; } @@ -26,21 +31,22 @@ namespace Volo.Abp.Cli.Commands { var operationType = NamespaceHelper.NormalizeNamespace(commandLineArgs.Target); + var preview = commandLineArgs.Options.ContainsKey(Options.Preview.Long); + switch (operationType) { case "": case null: + await InstallSuiteIfNotInstalledAsync(); RunSuite(); break; case "install": - Logger.LogInformation("Installing ABP Suite..."); - await InstallSuiteAsync(); + await InstallSuiteAsync(preview); break; case "update": - Logger.LogInformation("Updating ABP Suite..."); - await UpdateSuiteAsync(); + await UpdateSuiteAsync(preview); break; case "remove": @@ -50,8 +56,34 @@ namespace Volo.Abp.Cli.Commands } } - private async Task InstallSuiteAsync() + private async Task InstallSuiteIfNotInstalledAsync() + { + var currentSuiteVersionAsString = GetCurrentSuiteVersion(); + + if (string.IsNullOrEmpty(currentSuiteVersionAsString)) + { + await InstallSuiteAsync(); + } + } + + private string GetCurrentSuiteVersion() + { + var dotnetToolList = CmdHelper.RunCmdAndGetOutput("dotnet tool list -g"); + + var suiteLine = dotnetToolList.Split(Environment.NewLine).FirstOrDefault(l => l.ToLower().StartsWith("volo.abp.suite ")); + + if (string.IsNullOrEmpty(suiteLine)) + { + return null; + } + + return suiteLine.Split(" ", StringSplitOptions.RemoveEmptyEntries)[1]; + } + + private async Task InstallSuiteAsync(bool preview = false) { + Logger.LogInformation("Installing ABP Suite..."); + var nugetIndexUrl = await _nuGetIndexUrlService.GetAsync(); if (nugetIndexUrl == null) @@ -61,7 +93,9 @@ namespace Volo.Abp.Cli.Commands try { - var result = CmdHelper.RunCmd("dotnet tool install " + SuitePackageName + " --add-source " + nugetIndexUrl + " -g"); + var versionOption = await GetVersionOption(preview); + + var result = CmdHelper.RunCmd($"dotnet tool install {SuitePackageName} {versionOption} --add-source {nugetIndexUrl} -g"); if (result == 0) { @@ -86,8 +120,10 @@ namespace Volo.Abp.Cli.Commands Logger.LogInformation("dotnet tool install -g Volo.Abp.Suite"); } - private async Task UpdateSuiteAsync() + private async Task UpdateSuiteAsync(bool preview = false) { + Logger.LogInformation("Updating ABP Suite..."); + var nugetIndexUrl = await _nuGetIndexUrlService.GetAsync(); if (nugetIndexUrl == null) @@ -97,7 +133,9 @@ namespace Volo.Abp.Cli.Commands try { - var result = CmdHelper.RunCmd("dotnet tool update " + SuitePackageName + " --add-source " + nugetIndexUrl + " -g"); + var versionOption = await GetVersionOption(preview); + + var result = CmdHelper.RunCmd($"dotnet tool update {SuitePackageName} {versionOption} --add-source {nugetIndexUrl} -g"); if (result != 0) { @@ -111,6 +149,25 @@ namespace Volo.Abp.Cli.Commands } } + private async Task GetVersionOption(bool preview) + { + if (preview) + { + var latestVersion = await GetLatestSuiteVersioAsync(true); + if (latestVersion.IsPrerelease) + { + return $"--version {latestVersion.ToString()}"; + } + } + + return ""; + } + + private async Task GetLatestSuiteVersioAsync(bool preview) + { + return await _nuGetService.GetLatestVersionOrNullAsync(SuitePackageName, includeReleaseCandidates: preview); + } + private void ShowSuiteManualUpdateCommand() { Logger.LogError("You can also run the following command to update ABP Suite."); @@ -160,7 +217,9 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine(""); sb.AppendLine(" abp suite"); sb.AppendLine(" abp suite install"); + sb.AppendLine(" abp suite install --preview"); sb.AppendLine(" abp suite update"); + sb.AppendLine(" abp suite update --preview"); sb.AppendLine(" abp suite remove"); sb.AppendLine(""); @@ -171,5 +230,13 @@ namespace Volo.Abp.Cli.Commands { return "Install, update, remove or start ABP Suite. See https://commercial.abp.io/tools/suite."; } + + public static class Options + { + public static class Preview + { + public const string Long = "preview"; + } + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs index 46d2b77f95..ad5da58a8e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs @@ -19,13 +19,14 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building pipeline.Steps.Add(new TemplateCodeDeleteStep()); pipeline.Steps.Add(new SolutionRenameStep()); - if (context.Template.Name == AppProTemplate.TemplateName || + if (context.Template.Name == AppProTemplate.TemplateName || context.Template.Name == ModuleProTemplate.TemplateName) { pipeline.Steps.Add(new LicenseCodeReplaceStep()); } - if (context.BuildArgs.UiFramework == UiFramework.Mvc && context.BuildArgs.MobileApp == MobileApp.None) + if ((context.BuildArgs.UiFramework == UiFramework.Mvc || context.BuildArgs.UiFramework == UiFramework.Blazor) + && context.BuildArgs.MobileApp == MobileApp.None) { pipeline.Steps.Add(new RemoveRootFolderStep()); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFramework.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFramework.cs index 1ea2760b1c..17e33dc22d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFramework.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFramework.cs @@ -5,6 +5,7 @@ NotSpecified = 0, None = 1, Mvc = 2, - Angular = 3 + Angular = 3, + Blazor = 4 } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFrameworkExtensions.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFrameworkExtensions.cs index 9161c9c63e..b247a8f424 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFrameworkExtensions.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/UiFrameworkExtensions.cs @@ -9,9 +9,10 @@ case UiFramework.None: return "none"; case UiFramework.Mvc: return "mvc"; case UiFramework.Angular: return "angular"; + case UiFramework.Blazor: return "blazor"; case UiFramework.NotSpecified: return "NotSpecified"; default: return "NotSpecified"; } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs index 417c004f36..d309d4858a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs @@ -65,12 +65,22 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App ConfigureWithAngularUi(context, steps); break; + + case UiFramework.Blazor: + ConfigureWithBlazorUi(context, steps); + break; + case UiFramework.Mvc: case UiFramework.NotSpecified: ConfigureWithMvcUi(context, steps); break; } + if (context.BuildArgs.UiFramework != UiFramework.Blazor) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + } + if (context.BuildArgs.UiFramework != UiFramework.Angular) { steps.Add(new RemoveFolderStep("/angular")); @@ -101,6 +111,26 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App } } + private static void ConfigureWithBlazorUi(ProjectBuildContext context, List steps) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Host")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Tests", projectFolderPath: "/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests")); + + if (context.BuildArgs.ExtraProperties.ContainsKey("separate-identity-server")) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.HttpApi.HostWithIds")); + steps.Add(new BlazorAppsettingsFilePortChangeForSeparatedIdentityServersStep()); + } + else + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.HttpApi.Host")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.IdentityServer")); + steps.Add(new AppTemplateProjectRenameStep("MyCompanyName.MyProjectName.HttpApi.HostWithIds", "MyCompanyName.MyProjectName.HttpApi.Host")); + steps.Add(new AppTemplateChangeConsoleTestClientPortSettingsStep("44305")); + } + } + private static void ConfigureWithMvcUi(ProjectBuildContext context, List steps) { if (context.BuildArgs.ExtraProperties.ContainsKey("tiered")) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/BlazorAppsettingsFilePortChangeForSeparatedIdentityServersStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/BlazorAppsettingsFilePortChangeForSeparatedIdentityServersStep.cs new file mode 100644 index 0000000000..e83a630343 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/BlazorAppsettingsFilePortChangeForSeparatedIdentityServersStep.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using Volo.Abp.Cli.ProjectBuilding.Building; + +namespace Volo.Abp.Cli.ProjectBuilding.Templates.App +{ + public class BlazorAppsettingsFilePortChangeForSeparatedIdentityServersStep : ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + var appsettingsFile = context.Files.FirstOrDefault(x => + !x.IsDirectory && + x.Name.EndsWith("aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/appsettings.json", + StringComparison.InvariantCultureIgnoreCase) + ); + + appsettingsFile.NormalizeLineEndings(); + var lines = appsettingsFile.GetLines(); + + for (var i = 0; i < lines.Length; i++) + { + var line = lines[i]; + + if (line.Contains("Authority") && line.Contains("localhost")) + { + line = line.Replace("44305", "44301"); + } + else if (line.Contains("BaseUrl") && line.Contains("localhost")) + { + line = line.Replace("44305", "44300"); + } + + lines[i] = line; + } + + appsettingsFile.SetLines(lines); + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs index 1c522a438a..8968fdf918 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IAbpApplicationWithExternalServiceProvider.cs @@ -7,4 +7,4 @@ namespace Volo.Abp { void Initialize([NotNull] IServiceProvider serviceProvider); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs index 45f02e08c8..46b4174bef 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/IAbpModule.cs @@ -1,6 +1,4 @@ -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Modularity +namespace Volo.Abp.Modularity { public interface IAbpModule { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Validation/DynamicRangeAttribute.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Validation/DynamicRangeAttribute.cs new file mode 100644 index 0000000000..49c91f593e --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Validation/DynamicRangeAttribute.cs @@ -0,0 +1,64 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; +using System.Reflection; +using JetBrains.Annotations; + +namespace Volo.Abp.Validation +{ + public class DynamicRangeAttribute : RangeAttribute + { + private static readonly FieldInfo MaximumField; + private static readonly FieldInfo MinimumField; + + static DynamicRangeAttribute() + { + MaximumField = typeof(RangeAttribute).GetField( + "k__BackingField", + BindingFlags.Instance | BindingFlags.NonPublic + ); + Debug.Assert(MaximumField != null, nameof(MaximumField) + " != null"); + + MinimumField = typeof(RangeAttribute).GetField( + "k__BackingField", + BindingFlags.Instance | BindingFlags.NonPublic + ); + Debug.Assert(MinimumField != null, nameof(MinimumField) + " != null"); + } + + /// A type to get the values of the properties + /// The type of the range parameters. Must implement IComparable. + /// The name of the public static property for the + /// The name of the public static property for the + public DynamicRangeAttribute( + [NotNull] Type sourceType, + [NotNull] Type operandType, + [CanBeNull] string minimumPropertyName, + [CanBeNull] string maximumPropertyName + ) + : base(operandType, string.Empty, string.Empty) + { + Check.NotNull(sourceType, nameof(sourceType)); + + if (minimumPropertyName != null) + { + var minimumProperty = sourceType.GetProperty( + minimumPropertyName, + BindingFlags.Static | BindingFlags.Public + ); + Debug.Assert(minimumProperty != null, nameof(minimumProperty) + " != null"); + MinimumField.SetValue(this, minimumProperty.GetValue(null)); + } + + if (maximumPropertyName != null) + { + var maximumProperty = sourceType.GetProperty( + maximumPropertyName, + BindingFlags.Static | BindingFlags.Public + ); + Debug.Assert(maximumProperty != null, nameof(maximumProperty) + " != null"); + MaximumField.SetValue(this, maximumProperty.GetValue(null)); + } + } + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs index 10f88db22a..75cbfb8e96 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Application.Services } public interface ICrudAppService - : ICrudAppService + : ICrudAppService { } diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs index db66881fb7..bf2be8e8f0 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs @@ -21,7 +21,7 @@ namespace Volo.Abp.Application.Services } public abstract class CrudAppService - : CrudAppService + : CrudAppService where TEntity : class, IEntity where TEntityDto : IEntityDto { diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj index 6196a5b682..be0537ae96 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs index bd79480326..b2b11f0a18 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs @@ -51,6 +51,12 @@ namespace Volo.Abp.Features /// public bool IsVisibleToClients { get; set; } + /// + /// Can host use this feature. + /// Default: true. + /// + public bool IsAvailableToHost { get; set; } + /// /// A list of allowed providers to get/set value of this feature. /// An empty list indicates that all providers are allowed. @@ -93,7 +99,8 @@ namespace Volo.Abp.Features ILocalizableString displayName = null, ILocalizableString description = null, IStringValueType valueType = null, - bool isVisibleToClients = true) + bool isVisibleToClients = true, + bool isAvailableToHost = true) { Name = name; DefaultValue = defaultValue; @@ -101,6 +108,7 @@ namespace Volo.Abp.Features Description = description; ValueType = valueType; IsVisibleToClients = isVisibleToClients; + IsAvailableToHost = isAvailableToHost; Properties = new Dictionary(); AllowedProviders = new List(); @@ -136,20 +144,22 @@ namespace Volo.Abp.Features /// /// Returns a newly created child feature public FeatureDefinition CreateChild( - string name, - string defaultValue = null, - ILocalizableString displayName = null, + string name, + string defaultValue = null, + ILocalizableString displayName = null, ILocalizableString description = null, IStringValueType valueType = null, - bool isVisibleToClients = true) + bool isVisibleToClients = true, + bool isAvailableToHost = true) { var feature = new FeatureDefinition( - name, - defaultValue, - displayName, + name, + defaultValue, + displayName, description, valueType, - isVisibleToClients) + isVisibleToClients, + isAvailableToHost) { Parent = this }; @@ -175,4 +185,4 @@ namespace Volo.Abp.Features return $"[{nameof(FeatureDefinition)}: {Name}]"; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinitionManager.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinitionManager.cs index f8e8d9e9fe..31498e0756 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinitionManager.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinitionManager.cs @@ -62,6 +62,11 @@ namespace Volo.Abp.Features return FeatureDefinitions.GetOrDefault(name); } + public IReadOnlyList GetGroups() + { + return FeatureGroupDefinitions.Values.ToImmutableList(); + } + protected virtual Dictionary CreateFeatureDefinitions() { var features = new Dictionary(); @@ -78,7 +83,7 @@ namespace Volo.Abp.Features } protected virtual void AddFeatureToDictionaryRecursively( - Dictionary features, + Dictionary features, FeatureDefinition feature) { if (features.ContainsKey(feature.Name)) @@ -114,4 +119,4 @@ namespace Volo.Abp.Features return context.Groups; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureDefinitionManager.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureDefinitionManager.cs index c0172d7bc3..ca0a8cbcc6 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureDefinitionManager.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureDefinitionManager.cs @@ -11,5 +11,7 @@ namespace Volo.Abp.Features IReadOnlyList GetAll(); FeatureDefinition GetOrNull(string name); + + IReadOnlyList GetGroups(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/FodyWeavers.xml b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/FodyWeavers.xml new file mode 100644 index 0000000000..bc5a74a236 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/FodyWeavers.xsd b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj new file mode 100644 index 0000000000..36838f5149 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj @@ -0,0 +1,25 @@ + + + + + + + netstandard2.1 + Volo.Abp.Http.Client.IdentityModel.WebAssembly + Volo.Abp.Http.Client.IdentityModel.WebAssembly + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AbpHttpClientIdentityModelWebAssemblyModule.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AbpHttpClientIdentityModelWebAssemblyModule.cs new file mode 100644 index 0000000000..3110c36e26 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AbpHttpClientIdentityModelWebAssemblyModule.cs @@ -0,0 +1,13 @@ +using System; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly +{ + [DependsOn( + typeof(AbpHttpClientIdentityModelModule) + )] + public class AbpHttpClientIdentityModelWebAssemblyModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs new file mode 100644 index 0000000000..c86fc095c7 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -0,0 +1,50 @@ +using System.Threading.Tasks; +using IdentityModel.Client; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; +using Volo.Abp.IdentityModel; + +namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly +{ + [Dependency(ReplaceServices = true)] + public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator + { + protected IAccessTokenProvider AccessTokenProvider { get; } + + public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator( + IIdentityModelAuthenticationService identityModelAuthenticationService, + IAccessTokenProvider accessTokenProvider) + : base(identityModelAuthenticationService) + { + AccessTokenProvider = accessTokenProvider; + } + + public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + { + if (context.RemoteService.GetUseCurrentAccessToken() != false) + { + var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync(); + if (accessToken != null) + { + context.Request.SetBearerToken(accessToken); + return; + } + } + + await base.Authenticate(context); + } + + protected virtual async Task GetAccessTokenFromAccessTokenProviderOrNullAsync() + { + var result = await AccessTokenProvider.RequestAccessToken(); + if (result.Status != AccessTokenResultStatus.Success) + { + return null; + } + + result.TryGetToken(out var token); + return token.Value; + } + } +} diff --git a/framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs b/framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs index e20b60bf54..4d79779dd1 100644 --- a/framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs +++ b/framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Reflection; using Castle.DynamicProxy; using JetBrains.Annotations; -using Polly; using Volo.Abp; using Volo.Abp.Castle.DynamicProxy; using Volo.Abp.Http.Client; @@ -30,23 +29,15 @@ namespace Microsoft.Extensions.DependencyInjection /// /// True, to register the HTTP client proxy as the default implementation for the services. /// - /// - /// A delegate that is used to configure an . - /// public static IServiceCollection AddHttpClientProxies( [NotNull] this IServiceCollection services, [NotNull] Assembly assembly, [NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName, - bool asDefaultServices = true, - Action configureHttpClientBuilder = null) + bool asDefaultServices = true) { Check.NotNull(services, nameof(assembly)); - AddHttpClientFactoryAndPolicy(services, remoteServiceConfigurationName, configureHttpClientBuilder); - - //TODO: Make a configuration option and add remoteServiceName inside it! - - var serviceTypes = assembly.GetTypes().Where(IsSuitableForDynamicClientProxying); + var serviceTypes = assembly.GetTypes().Where(IsSuitableForDynamicClientProxying).ToArray(); foreach (var serviceType in serviceTypes) { @@ -72,17 +63,11 @@ namespace Microsoft.Extensions.DependencyInjection /// /// True, to register the HTTP client proxy as the default implementation for the service . /// - /// - /// A delegate that is used to configure an . - /// public static IServiceCollection AddHttpClientProxy( [NotNull] this IServiceCollection services, [NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName, - bool asDefaultService = true, - Action configureHttpClientBuilder = null) + bool asDefaultService = true) { - AddHttpClientFactoryAndPolicy(services, remoteServiceConfigurationName, configureHttpClientBuilder); - return services.AddHttpClientProxy( typeof(T), remoteServiceConfigurationName, @@ -90,37 +75,6 @@ namespace Microsoft.Extensions.DependencyInjection ); } - /// - /// Use IHttpClientFactory and polly - /// - /// Service collection - /// - /// The name of the remote service configuration to be used by the HTTP Client proxies. - /// See . - /// - /// - /// A delegate that is used to configure an . - /// - public static IServiceCollection AddHttpClientFactoryAndPolicy( - [NotNull] this IServiceCollection services, - [NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName, - Action configureHttpClientBuilder = null) - { - var httpClientBuilder = services.AddHttpClient(remoteServiceConfigurationName); - if (configureHttpClientBuilder == null) - { - httpClientBuilder.AddTransientHttpErrorPolicy(builder => - // retry 3 times - builder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i)))); - } - else - { - configureHttpClientBuilder.Invoke(httpClientBuilder); - } - - return services; - } - /// /// Registers HTTP Client Proxy for given service . /// @@ -143,6 +97,8 @@ namespace Microsoft.Extensions.DependencyInjection Check.NotNull(type, nameof(type)); Check.NotNullOrWhiteSpace(remoteServiceConfigurationName, nameof(remoteServiceConfigurationName)); + AddHttpClientFactoryAndPolicy(services, remoteServiceConfigurationName); + services.Configure(options => { options.HttpClientProxies[type] = new DynamicHttpClientProxyConfig(type, remoteServiceConfigurationName); @@ -189,13 +145,36 @@ namespace Microsoft.Extensions.DependencyInjection return services; } + private static IServiceCollection AddHttpClientFactoryAndPolicy( + [NotNull] this IServiceCollection services, + [NotNull] string remoteServiceConfigurationName = RemoteServiceConfigurationDictionary.DefaultName) + { + var preOptions = services.ExecutePreConfiguredActions(); + + if (preOptions.ConfiguredProxyClients.Contains(remoteServiceConfigurationName)) + { + return services; + } + + var clientBuilder = services.AddHttpClient(remoteServiceConfigurationName); + + foreach (var clientBuildAction in preOptions.ProxyClientBuildActions) + { + clientBuildAction(remoteServiceConfigurationName, clientBuilder); + } + + preOptions.ConfiguredProxyClients.Add(remoteServiceConfigurationName); + + return services; + } + /// /// Checks wether the type is suitable to use with the dynamic proxying. /// Currently the type is checked statically against some fixed conditions. /// /// Type to check /// True, if the type is suitable for dynamic proxying. Otherwise false. - static bool IsSuitableForDynamicClientProxying(Type type) + private static bool IsSuitableForDynamicClientProxying(Type type) { //TODO: Add option to change type filter diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientBuilderOptions.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientBuilderOptions.cs new file mode 100644 index 0000000000..7f11a6be12 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientBuilderOptions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; + +namespace Volo.Abp.Http.Client +{ + public class AbpHttpClientBuilderOptions + { + public List> ProxyClientBuildActions { get; } + + internal HashSet ConfiguredProxyClients { get; } + + public AbpHttpClientBuilderOptions() + { + ProxyClientBuildActions = new List>(); + ConfiguredProxyClients = new HashSet(); + } + } +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs index e2e5b7b9fe..e4e4f3e802 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs @@ -1,11 +1,11 @@ -using System.Linq; +using System; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Http; using Volo.Abp.Castle; using Volo.Abp.Modularity; using Volo.Abp.MultiTenancy; using Volo.Abp.Threading; using Volo.Abp.Validation; +using Polly; namespace Volo.Abp.Http.Client { @@ -18,29 +18,26 @@ namespace Volo.Abp.Http.Client )] public class AbpHttpClientModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - Configure(configuration); - } - - public override void PostConfigureServices(ServiceConfigurationContext context) + public override void PreConfigureServices(ServiceConfigurationContext context) { - Configure(options => + PreConfigure(options => { - if (options.HttpClientActions.Any()) + options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) => { - var httpClientNames = options.HttpClientProxies.Select(x => x.Value.RemoteServiceName); - foreach (var httpClientName in httpClientNames) - { - foreach (var httpClientAction in options.HttpClientActions) - { - context.Services.Configure(httpClientName, - x => x.HttpClientActions.Add(httpClientAction.Invoke(httpClientName))); - } - } - } + clientBuilder.AddTransientHttpErrorPolicy(policyBuilder => + policyBuilder.WaitAndRetryAsync( + 3, + i => TimeSpan.FromSeconds(Math.Pow(2, i)) + ) + ); + }); }); } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + Configure(configuration); + } } } diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientOptions.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientOptions.cs index 54cc4eb624..2e6cd3798d 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientOptions.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientOptions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Net.Http; using Volo.Abp.Http.Client.DynamicProxying; namespace Volo.Abp.Http.Client @@ -9,12 +8,9 @@ namespace Volo.Abp.Http.Client { public Dictionary HttpClientProxies { get; set; } - public List>> HttpClientActions { get; } - public AbpHttpClientOptions() { HttpClientProxies = new Dictionary(); - HttpClientActions = new List>>(); } } } diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpRemoteCallException.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpRemoteCallException.cs index d5cbc10c0b..19ecfba0ab 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpRemoteCallException.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpRemoteCallException.cs @@ -28,6 +28,14 @@ namespace Volo.Abp.Http.Client : base(error.Message) { Error = error; + + if (error.Data != null) + { + foreach (var dataKey in error.Data.Keys) + { + Data[dataKey] = error.Data[dataKey]; + } + } } } } diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index af9eb59b7f..5313457ba7 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -25,7 +25,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying public class DynamicHttpProxyInterceptor : AbpInterceptor, ITransientDependency { // ReSharper disable once StaticMemberInGenericType - protected static MethodInfo GenericInterceptAsyncMethod { get; } + protected static MethodInfo MakeRequestAndGetResultAsyncMethod { get; } protected ICancellationTokenProvider CancellationTokenProvider { get; } protected ICorrelationIdProvider CorrelationIdProvider { get; } @@ -42,7 +42,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying static DynamicHttpProxyInterceptor() { - GenericInterceptAsyncMethod = typeof(DynamicHttpProxyInterceptor) + MakeRequestAndGetResultAsyncMethod = typeof(DynamicHttpProxyInterceptor) .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) .First(m => m.Name == nameof(MakeRequestAndGetResultAsync) && m.IsGenericMethodDefinition); } @@ -81,7 +81,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying } else { - var result = (Task)GenericInterceptAsyncMethod + var result = (Task)MakeRequestAndGetResultAsyncMethod .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) .Invoke(this, new object[] { invocation }); @@ -90,7 +90,6 @@ namespace Volo.Abp.Http.Client.DynamicProxying invocation.Method.ReturnType.GetGenericArguments()[0] ); } - } private async Task GetResultAsync(Task task, Type resultType) diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/RemoteServiceErrorInfo.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/RemoteServiceErrorInfo.cs index 25792d1b24..287b423c20 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/RemoteServiceErrorInfo.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/RemoteServiceErrorInfo.cs @@ -1,4 +1,6 @@ using System; +using System.Collections; +using System.Collections.Generic; namespace Volo.Abp.Http { @@ -23,6 +25,8 @@ namespace Volo.Abp.Http /// public string Details { get; set; } + public IDictionary Data { get; set; } + /// /// Validation errors if exists. /// @@ -49,4 +53,4 @@ namespace Volo.Abp.Http Code = code; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj index 2b9e46f43d..e2f589b399 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj +++ b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 8676ac0f34..02dd0e5de7 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -29,6 +29,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB public virtual IMongoDatabase Database => DbContext.Database; + public virtual IClientSessionHandle SessionHandle => DbContext.SessionHandle; + public virtual TMongoDbContext DbContext => DbContextProvider.GetDbContext(); protected IMongoDbContextProvider DbContextProvider { get; } @@ -60,10 +62,21 @@ namespace Volo.Abp.Domain.Repositories.MongoDB { await ApplyAbpConceptsForAddedEntityAsync(entity); - await Collection.InsertOneAsync( - entity, - cancellationToken: GetCancellationToken(cancellationToken) - ); + if (SessionHandle != null) + { + await Collection.InsertOneAsync( + SessionHandle, + entity, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } + else + { + await Collection.InsertOneAsync( + entity, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } return entity; } @@ -88,12 +101,27 @@ namespace Volo.Abp.Domain.Repositories.MongoDB await TriggerDomainEventsAsync(entity); var oldConcurrencyStamp = SetNewConcurrencyStamp(entity); + ReplaceOneResult result; + + if (SessionHandle != null) + { + result = await Collection.ReplaceOneAsync( + SessionHandle, + CreateEntityFilter(entity, true, oldConcurrencyStamp), + entity, + cancellationToken: GetCancellationToken(cancellationToken) + ); - var result = await Collection.ReplaceOneAsync( - CreateEntityFilter(entity, true, oldConcurrencyStamp), - entity, - cancellationToken: GetCancellationToken(cancellationToken) - ); + + } + else + { + result = await Collection.ReplaceOneAsync( + CreateEntityFilter(entity, true, oldConcurrencyStamp), + entity, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } if (result.MatchedCount <= 0) { @@ -114,11 +142,25 @@ namespace Volo.Abp.Domain.Repositories.MongoDB if (entity is ISoftDelete softDeleteEntity && !IsHardDeleted(entity)) { softDeleteEntity.IsDeleted = true; - var result = await Collection.ReplaceOneAsync( - CreateEntityFilter(entity, true, oldConcurrencyStamp), - entity, - cancellationToken: GetCancellationToken(cancellationToken) - ); + ReplaceOneResult result; + + if (SessionHandle != null) + { + result = await Collection.ReplaceOneAsync( + SessionHandle, + CreateEntityFilter(entity, true, oldConcurrencyStamp), + entity, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } + else + { + result = await Collection.ReplaceOneAsync( + CreateEntityFilter(entity, true, oldConcurrencyStamp), + entity, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } if (result.MatchedCount <= 0) { @@ -127,10 +169,23 @@ namespace Volo.Abp.Domain.Repositories.MongoDB } else { - var result = await Collection.DeleteOneAsync( - CreateEntityFilter(entity, true, oldConcurrencyStamp), - GetCancellationToken(cancellationToken) - ); + DeleteResult result; + + if (SessionHandle != null) + { + result = await Collection.DeleteOneAsync( + SessionHandle, + CreateEntityFilter(entity, true, oldConcurrencyStamp), + cancellationToken: GetCancellationToken(cancellationToken) + ); + } + else + { + result = await Collection.DeleteOneAsync( + CreateEntityFilter(entity, true, oldConcurrencyStamp), + GetCancellationToken(cancellationToken) + ); + } if (result.DeletedCount <= 0) { @@ -195,9 +250,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB public virtual IMongoQueryable GetMongoQueryable() { - return ApplyDataFilters( - Collection.AsQueryable() - ); + return ApplyDataFilters(SessionHandle != null ? Collection.AsQueryable(SessionHandle) : Collection.AsQueryable()); } protected virtual bool IsHardDeleted(TEntity entity) { @@ -404,6 +457,13 @@ namespace Volo.Abp.Domain.Repositories.MongoDB bool includeDetails = true, CancellationToken cancellationToken = default) { + if (SessionHandle != null) + { + return await Collection + .Find(SessionHandle, RepositoryFilterer.CreateEntityFilter(id, true)) + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + } + return await Collection .Find(RepositoryFilterer.CreateEntityFilter(id, true)) .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs index bfa4b87da1..e961fdf256 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using MongoDB.Bson; using MongoDB.Driver; using Volo.Abp.DependencyInjection; @@ -10,14 +11,17 @@ namespace Volo.Abp.MongoDB public IMongoDatabase Database { get; private set; } + public IClientSessionHandle SessionHandle { get; private set; } + protected internal virtual void CreateModel(IMongoModelBuilder modelBuilder) { } - public virtual void InitializeDatabase(IMongoDatabase database) + public virtual void InitializeDatabase(IMongoDatabase database, IClientSessionHandle sessionHandle) { Database = database; + SessionHandle = sessionHandle; } public virtual IMongoCollection Collection() @@ -25,6 +29,12 @@ namespace Volo.Abp.MongoDB return Database.GetCollection(GetCollectionName()); } + public virtual void InitializeCollections(IMongoDatabase database) + { + Database = database; + ModelSource.GetModel(this); + } + protected virtual string GetCollectionName() { return GetEntityModel().CollectionName; @@ -42,4 +52,4 @@ namespace Volo.Abp.MongoDB return model; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs index e36e972954..d32f015a33 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs @@ -1,7 +1,9 @@ -using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Domain; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Modularity; +using Volo.Abp.MongoDB.DependencyInjection; using Volo.Abp.Uow.MongoDB; namespace Volo.Abp.MongoDB @@ -9,18 +11,23 @@ namespace Volo.Abp.MongoDB [DependsOn(typeof(AbpDddDomainModule))] public class AbpMongoDbModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddConventionalRegistrar(new AbpMongoDbConventionalRegistrar()); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.TryAddTransient( typeof(IMongoDbContextProvider<>), typeof(UnitOfWorkMongoDbContextProvider<>) ); - + context.Services.TryAddTransient( typeof(IMongoDbRepositoryFilterer<>), typeof(MongoDbRepositoryFilterer<>) ); - + context.Services.TryAddTransient( typeof(IMongoDbRepositoryFilterer<,>), typeof(MongoDbRepositoryFilterer<,>) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs new file mode 100644 index 0000000000..cb1ed7ea54 --- /dev/null +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs @@ -0,0 +1,27 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.MongoDB.DependencyInjection +{ + public class AbpMongoDbConventionalRegistrar : DefaultConventionalRegistrar + { + public override void AddType(IServiceCollection services, Type type) + { + if (!typeof(IAbpMongoDbContext).IsAssignableFrom(type) || type == typeof(AbpMongoDbContext)) + { + return; + } + + var dependencyAttribute = GetDependencyAttributeOrNull(type); + var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute); + + if (lifeTime == null) + { + return; + } + + services.Add(ServiceDescriptor.Describe(typeof(IAbpMongoDbContext), type, ServiceLifetime.Transient)); + } + } +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IAbpMongoDbContext.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IAbpMongoDbContext.cs index a2f48fd323..c4049e1389 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IAbpMongoDbContext.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IAbpMongoDbContext.cs @@ -7,5 +7,7 @@ namespace Volo.Abp.MongoDB IMongoDatabase Database { get; } IMongoCollection Collection(); + + IClientSessionHandle SessionHandle { get; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs index 43ffbabf4a..6d8706d7ee 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using MongoDB.Bson; +using MongoDB.Driver; using Volo.Abp.Domain.Entities; namespace Volo.Abp.MongoDB @@ -18,7 +20,7 @@ namespace Volo.Abp.MongoDB _entityModelBuilders = new Dictionary(); } - public MongoDbContextModel Build() + public MongoDbContextModel Build(AbpMongoDbContext dbContext) { lock (SyncObj) { @@ -38,6 +40,8 @@ namespace Volo.Abp.MongoDB } baseClasses.AddRange(entityModel.EntityType.GetBaseClasses(includeObject: false)); + + CreateCollectionIfNotExists(dbContext, entityModel.CollectionName); } baseClasses = baseClasses.Distinct().ToList(); @@ -84,5 +88,16 @@ namespace Volo.Abp.MongoDB { return _entityModelBuilders.Values.Cast().ToImmutableList(); } + + protected virtual void CreateCollectionIfNotExists(AbpMongoDbContext dbContext, string collectionName) + { + var filter = new BsonDocument("name", collectionName); + var options = new ListCollectionNamesOptions { Filter = filter }; + + if (!dbContext.Database.ListCollectionNames(options).Any()) + { + dbContext.Database.CreateCollection(collectionName); + } + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelSource.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelSource.cs index c5cb0da1c8..295cb8b84f 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelSource.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelSource.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.MongoDB public class MongoModelSource : IMongoModelSource, ISingletonDependency { protected readonly ConcurrentDictionary ModelCache = new ConcurrentDictionary(); - + public virtual MongoDbContextModel GetModel(AbpMongoDbContext dbContext) { return ModelCache.GetOrAdd( @@ -26,7 +26,7 @@ namespace Volo.Abp.MongoDB var modelBuilder = CreateModelBuilder(); BuildModelFromDbContextType(modelBuilder, dbContext.GetType()); BuildModelFromDbContextInstance(modelBuilder, dbContext); - return modelBuilder.Build(); + return modelBuilder.Build(dbContext); } protected virtual MongoModelBuilder CreateModelBuilder() @@ -65,4 +65,4 @@ namespace Volo.Abp.MongoDB dbContext.CreateModel(modelBuilder); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs new file mode 100644 index 0000000000..6c3ab76ee5 --- /dev/null +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; + +namespace Volo.Abp.Uow.MongoDB +{ + public class MongoDbTransactionApi : ITransactionApi, ISupportsRollback + { + public IClientSessionHandle SessionHandle { get; } + + public MongoDbTransactionApi(IClientSessionHandle sessionHandle) + { + SessionHandle = sessionHandle; + } + + public async Task CommitAsync() + { + await SessionHandle.CommitTransactionAsync(); + } + + protected void Commit() + { + SessionHandle.CommitTransaction(); + } + + public void Dispose() + { + SessionHandle.Dispose(); + } + + public void Rollback() + { + SessionHandle.AbortTransaction(); + } + + public async Task RollbackAsync(CancellationToken cancellationToken) + { + await SessionHandle.AbortTransactionAsync(cancellationToken); + } + } +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs index 0d527efc4c..0d9969ee51 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs @@ -1,5 +1,6 @@ using System; using Microsoft.Extensions.DependencyInjection; +using MongoDB.Bson; using MongoDB.Driver; using Volo.Abp.Data; using Volo.Abp.MongoDB; @@ -25,7 +26,8 @@ namespace Volo.Abp.Uow.MongoDB var unitOfWork = _unitOfWorkManager.Current; if (unitOfWork == null) { - throw new AbpException($"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!"); + throw new AbpException( + $"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!"); } var connectionString = _connectionStringResolver.Resolve(); @@ -41,18 +43,61 @@ namespace Volo.Abp.Uow.MongoDB //TODO: Create only single MongoDbClient per connection string in an application (extract MongoClientCache for example). var databaseApi = unitOfWork.GetOrAddDatabaseApi( dbContextKey, - () => + () => new MongoDbDatabaseApi(CreateDbContext(unitOfWork, mongoUrl, databaseName))); + + return ((MongoDbDatabaseApi) databaseApi).DbContext; + } + + private TMongoDbContext CreateDbContext(IUnitOfWork unitOfWork, MongoUrl mongoUrl, string databaseName) + { + var client = new MongoClient(mongoUrl); + var database = client.GetDatabase(databaseName); + + if (unitOfWork.Options.IsTransactional) + { + return CreateDbContextWithTransaction(unitOfWork, mongoUrl, client, database); + } + + var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); + dbContext.ToAbpMongoDbContext().InitializeDatabase(database, null); + + return dbContext; + } + + public TMongoDbContext CreateDbContextWithTransaction( + IUnitOfWork unitOfWork, + MongoUrl url, + MongoClient client, + IMongoDatabase database) + { + var transactionApiKey = $"MongoDb_{url}"; + var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as MongoDbTransactionApi; + var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); + + if (activeTransaction?.SessionHandle == null) + { + var session = client.StartSession(); + + if (unitOfWork.Options.Timeout.HasValue) { - var database = new MongoClient(mongoUrl).GetDatabase(databaseName); + session.AdvanceOperationTime(new BsonTimestamp(unitOfWork.Options.Timeout.Value)); + } - var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); + session.StartTransaction(); - dbContext.ToAbpMongoDbContext().InitializeDatabase(database); + unitOfWork.AddTransactionApi( + transactionApiKey, + new MongoDbTransactionApi(session) + ); - return new MongoDbDatabaseApi(dbContext); - }); + dbContext.ToAbpMongoDbContext().InitializeDatabase(database, session); + } + else + { + dbContext.ToAbpMongoDbContext().InitializeDatabase(database, activeTransaction.SessionHandle); + } - return ((MongoDbDatabaseApi)databaseApi).DbContext; + return dbContext; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs index d0b883e4f3..271d5d3d94 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs @@ -13,6 +13,16 @@ namespace Volo.Abp.Security.Claims /// public static string UserName { get; set; } = ClaimTypes.Name; + /// + /// Default: + /// + public static string Name { get; set; } = ClaimTypes.GivenName; + + /// + /// Default: + /// + public static string SurName { get; set; } = ClaimTypes.Surname; + /// /// Default: /// @@ -48,7 +58,6 @@ namespace Volo.Abp.Security.Claims /// public static string TenantId { get; set; } = "tenantid"; - /// /// Default: "editionid". /// diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs new file mode 100644 index 0000000000..0ebedc8d44 --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/CurrentPrincipalAccessorBase.cs @@ -0,0 +1,30 @@ +using System; +using System.Security.Claims; +using System.Threading; + +namespace Volo.Abp.Security.Claims +{ + public abstract class CurrentPrincipalAccessorBase : ICurrentPrincipalAccessor + { + public ClaimsPrincipal Principal => _currentPrincipal.Value ?? GetClaimsPrincipal(); + + private readonly AsyncLocal _currentPrincipal = new AsyncLocal(); + + protected abstract ClaimsPrincipal GetClaimsPrincipal(); + + public virtual IDisposable Change(ClaimsPrincipal principal) + { + return SetCurrent(principal); + } + + private IDisposable SetCurrent(ClaimsPrincipal principal) + { + var parent = Principal; + _currentPrincipal.Value = principal; + return new DisposeAction(() => + { + _currentPrincipal.Value = parent; + }); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs index ad496ba916..ea7ed7106f 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ThreadCurrentPrincipalAccessor.cs @@ -1,34 +1,14 @@ -using System; -using System.Security.Claims; +using System.Security.Claims; using System.Threading; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Security.Claims { - public class ThreadCurrentPrincipalAccessor : ICurrentPrincipalAccessor, ISingletonDependency + public class ThreadCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ISingletonDependency { - public ClaimsPrincipal Principal => _currentPrincipal.Value ?? GetClaimsPrincipal(); - - private readonly AsyncLocal _currentPrincipal = new AsyncLocal(); - - protected virtual ClaimsPrincipal GetClaimsPrincipal() + protected override ClaimsPrincipal GetClaimsPrincipal() { return Thread.CurrentPrincipal as ClaimsPrincipal; } - - public virtual IDisposable Change(ClaimsPrincipal principal) - { - return SetCurrent(principal); - } - - private IDisposable SetCurrent(ClaimsPrincipal principal) - { - var parent = Principal; - _currentPrincipal.Value = principal; - return new DisposeAction(() => - { - _currentPrincipal.Value = parent; - }); - } } } diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs index 487274860f..e769b9ec11 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs @@ -17,6 +17,10 @@ namespace Volo.Abp.Users public virtual string UserName => this.FindClaimValue(AbpClaimTypes.UserName); + public virtual string Name => this.FindClaimValue(AbpClaimTypes.Name); + + public virtual string SurName => this.FindClaimValue(AbpClaimTypes.SurName); + public virtual string PhoneNumber => this.FindClaimValue(AbpClaimTypes.PhoneNumber); public virtual bool PhoneNumberVerified => string.Equals(this.FindClaimValue(AbpClaimTypes.PhoneNumberVerified), "true", StringComparison.InvariantCultureIgnoreCase); @@ -56,4 +60,4 @@ namespace Volo.Abp.Users return FindClaims(AbpClaimTypes.Role).Any(c => c.Value == roleName); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Users/ICurrentUser.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Users/ICurrentUser.cs index 18613406d8..528f176c94 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Users/ICurrentUser.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Users/ICurrentUser.cs @@ -14,9 +14,15 @@ namespace Volo.Abp.Users [CanBeNull] string UserName { get; } + [CanBeNull] + string Name { get; } + + [CanBeNull] + string SurName { get; } + [CanBeNull] string PhoneNumber { get; } - + bool PhoneNumberVerified { get; } [CanBeNull] diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Urls/AppUrlProvider.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Urls/AppUrlProvider.cs index ffa31e66a2..912621c424 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Urls/AppUrlProvider.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Urls/AppUrlProvider.cs @@ -87,13 +87,16 @@ namespace Volo.Abp.UI.Navigation.Urls tenantNamePlaceHolder = TenantNamePlaceHolder + '.'; } - if (CurrentTenant.Id.HasValue) + if (url.Contains(tenantNamePlaceHolder)) { - url = url.Replace(tenantNamePlaceHolder, await GetCurrentTenantNameAsync()); - } - else - { - url = url.Replace(tenantNamePlaceHolder, ""); + if (CurrentTenant.Id.HasValue) + { + url = url.Replace(tenantNamePlaceHolder, await GetCurrentTenantNameAsync()); + } + else + { + url = url.Replace(tenantNamePlaceHolder, ""); + } } return url; @@ -110,4 +113,4 @@ namespace Volo.Abp.UI.Navigation.Urls return CurrentTenant.Name; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json index d6f24833a9..e0cdee07af 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json @@ -62,6 +62,8 @@ "500Message": "Internal Server Error", "GoHomePage": "Go to the homepage", "GoBack": "Go back", - "Search": "Search" + "Search": "Search", + "ItemWillBeDeletedMessageWithFormat": "{0} will be deleted!", + "ItemWillBeDeletedMessage": "This item will be deleted!" } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json index f4fffd3f7f..db803e01e2 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json @@ -62,6 +62,8 @@ "500Message": "Sunucu tarafında hata", "GoHomePage": "Ana sayfaya git", "GoBack": "Geri dön", - "Search": "Arama" + "Search": "Arama", + "ItemWillBeDeletedMessageWithFormat": "{0} silinecektir!", + "ItemWillBeDeletedMessage": "Bu nesne silinecektir!" } } diff --git a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs new file mode 100644 index 0000000000..d6a09e1c19 --- /dev/null +++ b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/DefaultBrandingProvider.cs @@ -0,0 +1,13 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Ui.Branding +{ + public class DefaultBrandingProvider : IBrandingProvider, ITransientDependency + { + public virtual string AppName => "MyApplication"; + + public virtual string LogoUrl => null; + + public virtual string LogoReverseUrl => null; + } +} diff --git a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/IBrandingProvider.cs b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/IBrandingProvider.cs new file mode 100644 index 0000000000..93e7fd957b --- /dev/null +++ b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/Branding/IBrandingProvider.cs @@ -0,0 +1,17 @@ +namespace Volo.Abp.Ui.Branding +{ + public interface IBrandingProvider + { + string AppName { get; } + + /// + /// Logo on white background + /// + string LogoUrl { get; } + + /// + /// Logo on dark background + /// + string LogoReverseUrl { get; } + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController.cs index 6ce47c4679..de0e24002f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; @@ -32,7 +33,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation { return Content("ModelState.IsValid: " + ModelState.IsValid.ToString().ToLowerInvariant()); } - + [HttpGet] [Route("object-result-action-dynamic-length")] public Task ObjectResultActionDynamicLength(ValidationDynamicTestModel model) @@ -47,7 +48,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation [StringLength(5, MinimumLength = 2)] public string Value1 { get; set; } } - + public class ValidationDynamicTestModel { [DynamicStringLength(typeof(Consts), nameof(Consts.MaxValue1Length), nameof(Consts.MinValue1Length))] @@ -55,18 +56,41 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation [DynamicMaxLength(typeof(Consts), nameof(Consts.MaxValue2Length))] public string Value2 { get; set; } - + [DynamicMaxLength(typeof(Consts), nameof(Consts.MaxValue3Length))] public int[] Value3 { get; set; } - + + [DynamicRange(typeof(Consts), typeof(int), nameof(Consts.MinValue1), nameof(Consts.MaxValue1))] + public int Value4 { get; set; } + + [DynamicRange(typeof(Consts), typeof(double), nameof(Consts.MinValue2), nameof(Consts.MaxValue2))] + public double Value5 { get; set; } + + [DynamicRange(typeof(Consts), typeof(DateTime), nameof(Consts.MinValue3), nameof(Consts.MaxValue3))] + public DateTime Value6 { get; set; } + public static class Consts { public static int MinValue1Length { get; set; } = 2; public static int MaxValue1Length { get; set; } = 7; public static int MaxValue2Length { get; set; } = 4; - + public static int MaxValue3Length { get; set; } = 2; + + + public static int MinValue1 { get; set; } = 1; + + public static int MaxValue1 { get; set; } = 5; + + + public static double MinValue2 { get; set; } = 1.2; + + public static double MaxValue2 { get; set; } = 7.2; + + public static string MinValue3 { get; set; } = "1/2/2004"; + + public static string MaxValue3 { get; set; } = "3/4/2004"; } } @@ -83,4 +107,4 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation } } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs index 9e22784ba7..715e55799a 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs @@ -61,9 +61,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation [Fact] public async Task Should_Validate_Dynamic_Length_Object_Result_Success() { - var result = await GetResponseAsStringAsync("/api/validation-test/object-result-action-dynamic-length?value1=hello&value3[0]=53&value3[1]=54"); + var result = await GetResponseAsStringAsync("/api/validation-test/object-result-action-dynamic-length?value1=hello&value3[0]=53&value3[1]=54&value4=4&value5=1.5&value6=2004-02-04"); result.ShouldBe("hello"); - + } [Fact] @@ -71,15 +71,24 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation { var result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=a", HttpStatusCode.BadRequest); //value1 has min string length of 2 chars. result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); - + result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=12345678", HttpStatusCode.BadRequest); //value1 has max string length of 7 chars. result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); - + result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=123458&value2=12345", HttpStatusCode.BadRequest); //value2 has max length of 5 chars. result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); - + result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=123458&value3[0]=53&value3[1]=54&value3[2]=55&value3[3]=56", HttpStatusCode.BadRequest); //value3 has max length of 2. result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); + + result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=123458&value3[0]=53&value3[1]=54&value[4]=10", HttpStatusCode.BadRequest); //value4 has max num of 5. + result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); + + result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=123458&value3[0]=53&value3[1]=54&value4=2&value5=1.1", HttpStatusCode.BadRequest); //value4 has min num of 1.2. + result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); + + result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action-dynamic-length?value1=123458&value3[0]=53&value3[1]=54&value4=2&value5=1.2&value6=2004-05-04", HttpStatusCode.BadRequest); //value4 has max date of 3/4/2004. + result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); } } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json index 00021c8fb2..a37af33e79 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json @@ -3,7 +3,7 @@ "name": "asp.net", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.shared": "^3.1.0-rc.3", + "@abp/aspnetcore.mvc.ui.theme.shared": "^3.1.2", "highlight.js": "^9.13.1" }, "devDependencies": {} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/luxon/abp.luxon.js b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/luxon/abp.luxon.js new file mode 100644 index 0000000000..b04de7cadf --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/luxon/abp.luxon.js @@ -0,0 +1,46 @@ +var abp = abp || {}; +(function () { + + if (!luxon) { + throw "abp/luxon library requires the luxon library included to the page!"; + } + + /* TIMING *************************************************/ + + abp.timing = abp.timing || {}; + + var setObjectValue = function (obj, property, value) { + if (typeof property === "string") { + property = property.split('.'); + } + + if (property.length > 1) { + var p = property.shift(); + setObjectValue(obj[p], property, value); + } else { + obj[property[0]] = value; + } + } + + var getObjectValue = function (obj, property) { + return property.split('.').reduce((a, v) => a[v], obj) + } + + abp.timing.convertFieldsToIsoDate = function (form, fields) { + for (var field of fields) { + var dateTime = luxon.DateTime + .fromFormat( + getObjectValue(form, field), + abp.localization.currentCulture.dateTimeFormat.shortDatePattern, + {locale: abp.localization.currentCulture.cultureName} + ); + + if (!dateTime.invalid) { + setObjectValue(form, field, dateTime.toFormat("yyyy-MM-dd HH:mm:ss")) + } + } + + return form; + } + +})(jQuery); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock index 664291812e..5d59728037 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock @@ -2,30 +2,30 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.shared@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.shared@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -34,144 +34,144 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json index b2bc192cea..9e281c4b1f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json @@ -3,7 +3,7 @@ "name": "asp.net", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2" }, "devDependencies": {} } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/luxon/abp.luxon.js b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/luxon/abp.luxon.js new file mode 100644 index 0000000000..b04de7cadf --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/luxon/abp.luxon.js @@ -0,0 +1,46 @@ +var abp = abp || {}; +(function () { + + if (!luxon) { + throw "abp/luxon library requires the luxon library included to the page!"; + } + + /* TIMING *************************************************/ + + abp.timing = abp.timing || {}; + + var setObjectValue = function (obj, property, value) { + if (typeof property === "string") { + property = property.split('.'); + } + + if (property.length > 1) { + var p = property.shift(); + setObjectValue(obj[p], property, value); + } else { + obj[property[0]] = value; + } + } + + var getObjectValue = function (obj, property) { + return property.split('.').reduce((a, v) => a[v], obj) + } + + abp.timing.convertFieldsToIsoDate = function (form, fields) { + for (var field of fields) { + var dateTime = luxon.DateTime + .fromFormat( + getObjectValue(form, field), + abp.localization.currentCulture.dateTimeFormat.shortDatePattern, + {locale: abp.localization.currentCulture.cultureName} + ); + + if (!dateTime.invalid) { + setObjectValue(form, field, dateTime.toFormat("yyyy-MM-dd HH:mm:ss")) + } + } + + return form; + } + +})(jQuery); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock index 0c2e9764b1..5f63f5733b 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock @@ -2,37 +2,37 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -41,144 +41,144 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj b/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj index 07708ce189..6b4e1ce4f0 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj @@ -14,4 +14,8 @@ + + + + diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpClientTestModule.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpClientTestModule.cs index 9b2a28ad3e..6a18b06620 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpClientTestModule.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpClientTestModule.cs @@ -2,8 +2,12 @@ using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Http.Client; using Volo.Abp.Http.DynamicProxying; +using Volo.Abp.Http.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; using Volo.Abp.TestApp; +using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Http { @@ -22,6 +26,24 @@ namespace Volo.Abp.Http { options.RemoteServices.Default = new RemoteServiceConfiguration("/"); }); + + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add("en") + .AddVirtualJson("/Volo/Abp/Http/Localization"); + }); + + Configure(options => + { + options.MapCodeNamespace("Volo.Abp.Http.DynamicProxying", typeof(HttpClientTestResource)); + }); } } } diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs index 546968d402..23694e4e72 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs @@ -9,6 +9,8 @@ namespace Volo.Abp.Http.DynamicProxying Task GetException1Async(); + Task GetException2Async(); + Task GetWithDateTimeParameterAsync(DateTime dateTime1); Task PostValueWithHeaderAndQueryStringAsync(string headerValue, string qsValue); diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs index ef2a8bface..da61333d4e 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs @@ -27,6 +27,14 @@ namespace Volo.Abp.Http.DynamicProxying throw new UserFriendlyException("This is an error message!"); } + [HttpGet] + [Route("get-exception2")] + public Task GetException2Async() + { + throw new BusinessException("Volo.Abp.Http.DynamicProxying:10001") + .WithData("0","TEST"); + } + [HttpGet] [Route("get-with-datetime-parameter")] public Task GetWithDateTimeParameterAsync(DateTime dateTime1) @@ -133,4 +141,4 @@ namespace Volo.Abp.Http.DynamicProxying [FromQuery] public DateTime FirstReleaseDate { get; set; } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs index 85825263bd..2ac327e5e7 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs @@ -1,8 +1,10 @@ using System; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; using Shouldly; using Volo.Abp.Http.Client; +using Volo.Abp.Http.Localization; using Volo.Abp.Localization; using Xunit; @@ -32,6 +34,13 @@ namespace Volo.Abp.Http.DynamicProxying exception.Error.Message.ShouldBe("This is an error message!"); } + [Fact] + public async Task GetException2Async() + { + var exception = await Assert.ThrowsAsync(async () => await _controller.GetException2Async()); + exception.Error.Message.ShouldBe("Business exception with data: TEST"); + } + [Fact] public async Task GetWithDateTimeParameterAsync() { @@ -151,4 +160,4 @@ namespace Volo.Abp.Http.DynamicProxying } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/HttpClientTestResource.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/HttpClientTestResource.cs new file mode 100644 index 0000000000..fc87525b87 --- /dev/null +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/HttpClientTestResource.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Localization; + +namespace Volo.Abp.Http.Localization +{ + [LocalizationResourceName("HttpClientTest")] + public class HttpClientTestResource + { + + } +} diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/en.json b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/en.json new file mode 100644 index 0000000000..9c88edf323 --- /dev/null +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/en.json @@ -0,0 +1,6 @@ +{ + "culture": "en", + "texts": { + "Volo.Abp.Http.DynamicProxying:10001": "Business exception with data: {0}" + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs index cfa7b033b7..8ec0b026cd 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs @@ -1,10 +1,15 @@ using System; +using System.Linq; +using System.Threading; using Microsoft.Extensions.DependencyInjection; +using MongoDB.Driver; +using MongoDB.Driver.Core.Servers; using Volo.Abp.Data; using Volo.Abp.Modularity; using Volo.Abp.TestApp; using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.MongoDB; +using Volo.Abp.Uow; namespace Volo.Abp.MongoDB { @@ -16,7 +21,7 @@ namespace Volo.Abp.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); @@ -30,6 +35,11 @@ namespace Volo.Abp.MongoDB options.AddDefaultRepositories(); options.AddRepository(); }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/HardDelete_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/HardDelete_Tests.cs index 66c6e58b5c..699e6de5a3 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/HardDelete_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/HardDelete_Tests.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Text; using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { + [Collection(MongoTestCollection.Name)] public class HardDelete_Tests : HardDelete_Tests { } diff --git a/global.json b/global.json new file mode 100644 index 0000000000..6156170057 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "3.1.102", + "rollForward": "latestFeature" + } +} \ No newline at end of file diff --git a/modules/account/Volo.Abp.Account.sln b/modules/account/Volo.Abp.Account.sln index c2b195f05b..b96627aac9 100644 --- a/modules/account/Volo.Abp.Account.sln +++ b/modules/account/Volo.Abp.Account.sln @@ -21,6 +21,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{12FAE513-7 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Application.Tests", "test\Volo.Abp.Account.Application.Tests\Volo.Abp.Account.Application.Tests.csproj", "{356EAC51-5D55-4852-A8A5-2F90EAC8DAE3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Blazor", "src\Volo.Abp.Account.Blazor\Volo.Abp.Account.Blazor.csproj", "{EE8858B3-A638-481B-8EB9-74F5E7D43D80}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -55,6 +57,10 @@ Global {356EAC51-5D55-4852-A8A5-2F90EAC8DAE3}.Debug|Any CPU.Build.0 = Debug|Any CPU {356EAC51-5D55-4852-A8A5-2F90EAC8DAE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {356EAC51-5D55-4852-A8A5-2F90EAC8DAE3}.Release|Any CPU.Build.0 = Release|Any CPU + {EE8858B3-A638-481B-8EB9-74F5E7D43D80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE8858B3-A638-481B-8EB9-74F5E7D43D80}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE8858B3-A638-481B-8EB9-74F5E7D43D80}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE8858B3-A638-481B-8EB9-74F5E7D43D80}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -67,6 +73,7 @@ Global {EBF0C2B3-14CB-4DFC-9753-ECBF959CBA2E} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E} {7BCA5955-B3F6-41E8-9D5D-D115195C6098} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E} {356EAC51-5D55-4852-A8A5-2F90EAC8DAE3} = {12FAE513-7575-4235-89DF-277BA1A3B098} + {EE8858B3-A638-481B-8EB9-74F5E7D43D80} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2B054393-D2B2-4EA8-8A15-D60CBCF3E7A9} diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/en.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/en.json index e9215d3f5a..85bd040d8c 100644 --- a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/en.json +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/en.json @@ -53,6 +53,8 @@ "ResetPassword_Information": "Please enter your new password.", "YourPasswordIsSuccessfullyReset": "Your password is successfully reset.", "GoToTheApplication": "Go to the application", - "BackToLogin": "Back to login" + "BackToLogin": "Back to login", + "ProfileTab:Password": "Change password", + "ProfileTab:PersonalInfo": "Personal info" } } diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json index bbb2ac3638..c9aff72675 100644 --- a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json @@ -52,6 +52,8 @@ "ResetPassword_Information": "Lütfen yeni şifrenizi belirleyin.", "YourPasswordIsSuccessfullyReset": "Şifreniz başarıyla sıfırlandı.", "GoToTheApplication": "Uygulamaya git", - "BackToLogin": "Girişe dön" + "BackToLogin": "Girişe dön", + "ProfileTab:Password": "Şifre değiştir", + "ProfileTab:PersonalInfo": "Kişisel bilgiler" } } diff --git a/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorAutoMapperProfile.cs b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorAutoMapperProfile.cs new file mode 100644 index 0000000000..f5c4cdc01d --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorAutoMapperProfile.cs @@ -0,0 +1,20 @@ +using AutoMapper; +using Volo.Abp.Account.Blazor.Pages.Account; +using Volo.Abp.AutoMapper; +using Volo.Abp.Identity; + +namespace Volo.Abp.Account.Blazor +{ + public class AbpAccountBlazorAutoMapperProfile : Profile + { + public AbpAccountBlazorAutoMapperProfile() + { + CreateMap() + .Ignore(x => x.PhoneNumberConfirmed) + .Ignore(x => x.EmailConfirmed); + + CreateMap() + .Ignore(x => x.ExtraProperties); + } + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorModule.cs b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorModule.cs new file mode 100644 index 0000000000..c0917dd8f7 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorModule.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.Account.Blazor +{ + [DependsOn( + typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule), + typeof(AbpAutoMapperModule), + typeof(AbpAccountHttpApiClientModule) + )] + public class AbpAccountBlazorModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + options.MenuContributors.Add(new AbpAccountBlazorUserMenuContributor()); + }); + + Configure(options => + { + options.AdditionalAssemblies.Add(typeof(AbpAccountBlazorModule).Assembly); + }); + } + } +} diff --git a/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs new file mode 100644 index 0000000000..3ceab0f735 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Volo.Abp.Account.Localization; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.Account.Blazor +{ + public class AbpAccountBlazorUserMenuContributor : IMenuContributor + { + public Task ConfigureMenuAsync(MenuConfigurationContext context) + { + if (context.Menu.Name != StandardMenus.User) + { + return Task.CompletedTask; + } + + var accountResource = context.GetLocalizer(); + + context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["ManageYourProfile"], url: "account/manage-profile", icon: "fa fa-cog")); + + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/FodyWeavers.xml b/modules/account/src/Volo.Abp.Account.Blazor/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/FodyWeavers.xsd b/modules/account/src/Volo.Abp.Account.Blazor/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/Manage.razor b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/Manage.razor new file mode 100644 index 0000000000..d8c9d063b8 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/Manage.razor @@ -0,0 +1,64 @@ +@page "/account/manage-profile" +@inherits AccountManageBase + + + + + @L["ProfileTab:Password"] + @L["ProfileTab:PersonalInfo"] + + + @if (ChangePasswordModel != null) + { + + + @L["DisplayName:CurrentPassword"] + + + + @L["DisplayName:NewPassword"] + + + + @L["DisplayName:NewPasswordConfirm"] + + + + + + + } + @if (PersonalInfoModel != null) + { + + + @L["DisplayName:UserName"] + + + + + @L["DisplayName:Name"] + + + + @L["DisplayName:Surname"] + + + + + @L["DisplayName:Email"] + + + + @L["DisplayName:PhoneNumber"] + + + + + + + } + + + + \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/Manage.razor.cs b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/Manage.razor.cs new file mode 100644 index 0000000000..77cf43327c --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/Manage.razor.cs @@ -0,0 +1,117 @@ +using System.Threading.Tasks; +using Localization.Resources.AbpUi; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Localization; +using Volo.Abp.Account.Localization; +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.Identity; +using Volo.Abp.ObjectMapping; + +namespace Volo.Abp.Account.Blazor.Pages.Account +{ + public class AccountManageBase : OwningComponentBase + { + [Inject] protected IAccountAppService AccountAppService { get; set; } + [Inject] protected IProfileAppService ProfileAppService { get; set; } + + [Inject] protected IObjectMapper ObjectMapper { get; set; } + + [Inject] protected IUiMessageService UiMessageService { get; set; } + + [Inject] protected IStringLocalizer UiLocalizer { get; set; } + + [Inject] protected IStringLocalizer L { get; set; } + + protected string SelectedTab = "Password"; + + protected ChangePasswordModel ChangePasswordModel; + + protected PersonalInfoModel PersonalInfoModel; + + protected override async Task OnInitializedAsync() + { + await GetUserInformations(); + } + + protected async Task GetUserInformations() + { + var user = await ProfileAppService.GetAsync(); + + ChangePasswordModel = new ChangePasswordModel + { + HideOldPasswordInput = !user.HasPassword + }; + + PersonalInfoModel = ObjectMapper.Map(user); + } + + protected async Task ChangePasswordAsync() + { + if (string.IsNullOrWhiteSpace(ChangePasswordModel.CurrentPassword)) + { + return; + } + + if (ChangePasswordModel.NewPassword != ChangePasswordModel.NewPasswordConfirm) + { + await UiMessageService.WarnAsync(L["NewPasswordConfirmFailed"]); + return; + } + + if (!await UiMessageService.ConfirmAsync(UiLocalizer["AreYouSure"])) + { + return; + } + + await ProfileAppService.ChangePasswordAsync(new ChangePasswordInput + { + CurrentPassword = ChangePasswordModel.CurrentPassword, + NewPassword = ChangePasswordModel.NewPassword + }); + + await UiMessageService.SuccessAsync(L["PasswordChanged"]); + } + + protected async Task UpdatePersonalInfoAsync() + { + if (!await UiMessageService.ConfirmAsync(UiLocalizer["AreYouSure"])) + { + return; + } + + await ProfileAppService.UpdateAsync( + ObjectMapper.Map(PersonalInfoModel) + ); + + await UiMessageService.SuccessAsync(L["PersonalSettingsSaved"]); + } + } + + public class ChangePasswordModel + { + public string CurrentPassword { get; set; } + + public string NewPassword { get; set; } + + public string NewPasswordConfirm { get; set; } + + public bool HideOldPasswordInput { get; set; } + } + + public class PersonalInfoModel + { + public string UserName { get; set; } + + public string Email { get; set; } + + public string Name { get; set; } + + public string Surname { get; set; } + + public string PhoneNumber { get; set; } + + public bool PhoneNumberConfirmed { get; set; } + + public bool EmailConfirmed { get; set; } + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.csproj b/modules/account/src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.csproj new file mode 100644 index 0000000000..5707bc86a4 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/Volo.Abp.Account.Blazor.csproj @@ -0,0 +1,27 @@ + + + + + + + netstandard2.1 + 3.0 + Volo.Abp.Account.Blazor + + + + + + + + + + + + + + true + + + + diff --git a/modules/account/src/Volo.Abp.Account.Blazor/_Imports.razor b/modules/account/src/Volo.Abp.Account.Blazor/_Imports.razor new file mode 100644 index 0000000000..4685ac9893 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Blazor/_Imports.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 \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebAutomapperProfile.cs b/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebAutomapperProfile.cs index ab7ea41269..6204c20582 100644 --- a/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebAutomapperProfile.cs +++ b/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebAutomapperProfile.cs @@ -1,6 +1,7 @@ using Volo.Abp.Account.Web.Pages.Account; using Volo.Abp.Identity; using AutoMapper; +using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo; namespace Volo.Abp.Account.Web { @@ -8,7 +9,7 @@ namespace Volo.Abp.Account.Web { public AbpAccountWebAutoMapperProfile() { - CreateMap(); + CreateMap(); } } } diff --git a/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs b/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs index 10886e4c17..303963d24f 100644 --- a/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs +++ b/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs @@ -1,7 +1,10 @@ using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Account.Web.ProfileManagement; using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; using Volo.Abp.AutoMapper; @@ -50,16 +53,38 @@ namespace Volo.Abp.Account.Web options.Contributors.Add(new AccountModuleToolbarContributor()); }); + ConfigureProfileManagementPage(); + + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.AddProfile(validate: true); + }); + } + + private void ConfigureProfileManagementPage() + { Configure(options => { options.Conventions.AuthorizePage("/Account/Manage"); }); - context.Services.AddAutoMapperObjectMapper(); - Configure(options => + Configure(options => { - options.AddProfile(validate: true); + options.Contributors.Add(new AccountProfileManagementPageContributor()); }); + + Configure(options => + { + options.ScriptBundles + .Configure(typeof(ManageModel).FullName, + configuration => + { + configuration.AddFiles("/Pages/Account/Components/ProfileManagementGroup/Password/Default.js"); + configuration.AddFiles("/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js"); + }); + }); + } } } diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/AccountProfilePasswordManagementGroupViewComponent.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/AccountProfilePasswordManagementGroupViewComponent.cs new file mode 100644 index 0000000000..7a0df6878b --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/AccountProfilePasswordManagementGroupViewComponent.cs @@ -0,0 +1,59 @@ +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Auditing; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.Password +{ + public class AccountProfilePasswordManagementGroupViewComponent : AbpViewComponent + { + private readonly IProfileAppService _profileAppService; + + public AccountProfilePasswordManagementGroupViewComponent( + IProfileAppService profileAppService) + { + _profileAppService = profileAppService; + } + + public async Task InvokeAsync() + { + var user = await _profileAppService.GetAsync(); + + var model = new ChangePasswordInfoModel + { + HideOldPasswordInput = !user.HasPassword + }; + + return View("~/Pages/Account/Components/ProfileManagementGroup/Password/Default.cshtml", model); + } + + public class ChangePasswordInfoModel + { + [Required] + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))] + [Display(Name = "DisplayName:CurrentPassword")] + [DataType(DataType.Password)] + [DisableAuditing] + public string CurrentPassword { get; set; } + + [Required] + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))] + [Display(Name = "DisplayName:NewPassword")] + [DataType(DataType.Password)] + [DisableAuditing] + public string NewPassword { get; set; } + + [Required] + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))] + [Display(Name = "DisplayName:NewPasswordConfirm")] + [DataType(DataType.Password)] + [DisableAuditing] + public string NewPasswordConfirm { get; set; } + + public bool HideOldPasswordInput { get; set; } + } + } +} diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/Default.cshtml b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/Default.cshtml new file mode 100644 index 0000000000..febab6d081 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/Default.cshtml @@ -0,0 +1,17 @@ +@using Volo.Abp.Account.Localization +@using Volo.Abp.Users +@using Microsoft.AspNetCore.Mvc.Localization +@inject IHtmlLocalizer L +@inject ICurrentUser CurrentUser +@model Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.Password.AccountProfilePasswordManagementGroupViewComponent.ChangePasswordInfoModel + +

@L["ChangePassword"]


+
+ @if (!Model.HideOldPasswordInput) + { + + } + + + + diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/Default.js b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/Default.js new file mode 100644 index 0000000000..ef38f68466 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/Default.js @@ -0,0 +1,31 @@ +(function ($) { + $(function () { + var l = abp.localization.getResource("AbpAccount"); + + $('#ChangePasswordForm').submit(function (e) { + e.preventDefault(); + + if (!$('#ChangePasswordForm').valid()) { + return false; + } + + var input = $('#ChangePasswordForm').serializeFormToObject(); + + if ( + input.newPassword != input.newPasswordConfirm || + input.newPassword == '' + ) { + abp.message.error(l('NewPasswordConfirmFailed')); + return; + } + + if (input.currentPassword && input.currentPassword == ''){ + return; + } + + volo.abp.identity.profile.changePassword(input).then(function (result) { + abp.message.success(l('PasswordChanged')); + }); + }); + }); +})(jQuery); diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/AccountProfilePersonalInfoManagementGroupViewComponent.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/AccountProfilePersonalInfoManagementGroupViewComponent.cs new file mode 100644 index 0000000000..512d646ff2 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/AccountProfilePersonalInfoManagementGroupViewComponent.cs @@ -0,0 +1,56 @@ +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo +{ + public class AccountProfilePersonalInfoManagementGroupViewComponent : AbpViewComponent + { + private readonly IProfileAppService _profileAppService; + + public AccountProfilePersonalInfoManagementGroupViewComponent( + IProfileAppService profileAppService) + { + _profileAppService = profileAppService; + + ObjectMapperContext = typeof(AbpAccountWebModule); + } + + public async Task InvokeAsync() + { + var user = await _profileAppService.GetAsync(); + + var model = ObjectMapper.Map(user); + + return View("~/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml", model); + } + + public class PersonalInfoModel + { + [Required] + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))] + [Display(Name = "DisplayName:UserName")] + public string UserName { get; set; } + + [Required] + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))] + [Display(Name = "DisplayName:Email")] + public string Email { get; set; } + + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxNameLength))] + [Display(Name = "DisplayName:Name")] + public string Name { get; set; } + + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxSurnameLength))] + [Display(Name = "DisplayName:Surname")] + public string Surname { get; set; } + + [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))] + [Display(Name = "DisplayName:PhoneNumber")] + public string PhoneNumber { get; set; } + } + } +} diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml new file mode 100644 index 0000000000..33ca670b0c --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml @@ -0,0 +1,39 @@ +@using Volo.Abp.Account.Localization +@using Volo.Abp.Users +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using Volo.Abp.Identity.Settings +@using Volo.Abp.Settings +@inject IHtmlLocalizer L +@inject ICurrentUser CurrentUser +@inject ISettingProvider SettingManager +@inject IThemeManager ThemeManager +@model Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo.AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel +@{ + var isUserNameUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled), "true", + StringComparison.OrdinalIgnoreCase); + + var isEmailUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled), "true", + StringComparison.OrdinalIgnoreCase); +} + +

@L["PersonalSettings"]


+
+ + + + + + + + + + + + + + + + + + diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js new file mode 100644 index 0000000000..6f5642d07d --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js @@ -0,0 +1,19 @@ +(function ($) { + $(function () { + var l = abp.localization.getResource("AbpAccount"); + + $('#PersonalSettingsForm').submit(function (e) { + e.preventDefault(); + + if (!$('#PersonalSettingsForm').valid()) { + return false; + } + + var input = $('#PersonalSettingsForm').serializeFormToObject(); + + volo.abp.identity.profile.update(input).then(function (result) { + abp.notify.success(l('PersonalSettingsSaved')); + }); + }); + }); +})(jQuery); diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml index 23350442b2..ff6262f3ec 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml @@ -2,66 +2,33 @@ @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.Account.Localization @using Volo.Abp.Account.Web.Pages.Account -@using Volo.Abp.Identity.Settings -@using Volo.Abp.Settings @using Volo.Abp.AspNetCore.Mvc.UI.Theming -@inject ISettingProvider SettingManager @inject IThemeManager ThemeManager @inject IHtmlLocalizer L @model ManageModel @{ Layout = ThemeManager.CurrentTheme.GetApplicationLayout(); - var isUserNameUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled), "true", - StringComparison.OrdinalIgnoreCase); - - var isEmailUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled), "true", - StringComparison.OrdinalIgnoreCase); } @section scripts { - - - + } - - - - @if (!Model.DisablePasswordChange) - { - -

@L["ChangePassword"].Value


-
- @if (!Model.HideOldPasswordInput) - { - - } - - - - -
- } - -

@L["PersonalSettings"].Value


-
- - - - - - - - - - - - - - - - - -
-
-
-
+
+ + + + @foreach (var group in Model.ProfileManagementPageCreationContext.Groups) + { + +

@group.DisplayName

+
+ @await Component.InvokeAsync(group.ComponentType, new + { + parameter = group.Parameter + }) +
+ } +
+
+
+
diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml.cs index db51f9890c..f7b08eb6c4 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml.cs @@ -2,35 +2,31 @@ using System.Threading.Tasks; using Volo.Abp.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.Account.Web.ProfileManagement; using Volo.Abp.Validation; namespace Volo.Abp.Account.Web.Pages.Account { public class ManageModel : AccountPageModel { - public ChangePasswordInfoModel ChangePasswordInfoModel { get; set; } + public ProfileManagementPageCreationContext ProfileManagementPageCreationContext { get; private set; } - public PersonalSettingsInfoModel PersonalSettingsInfoModel { get; set; } + protected ProfileManagementPageOptions Options { get; } - public bool DisablePasswordChange { get; set; } - - public bool HideOldPasswordInput { get; set; } - - protected IProfileAppService ProfileAppService { get; } - - public ManageModel(IProfileAppService profileAppService) + public ManageModel(IOptions options) { - ProfileAppService = profileAppService; + Options = options.Value; } public virtual async Task OnGetAsync() { - var user = await ProfileAppService.GetAsync(); - - PersonalSettingsInfoModel = ObjectMapper.Map(user); + ProfileManagementPageCreationContext = new ProfileManagementPageCreationContext(ServiceProvider); - DisablePasswordChange = user.IsExternal; - HideOldPasswordInput = !user.HasPassword; + foreach (var contributor in Options.Contributors) + { + await contributor.ConfigureAsync(ProfileManagementPageCreationContext); + } return Page(); } @@ -40,50 +36,4 @@ namespace Volo.Abp.Account.Web.Pages.Account return Task.FromResult(Page()); } } - - public class ChangePasswordInfoModel - { - [Required] - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))] - [Display(Name = "DisplayName:CurrentPassword")] - [DataType(DataType.Password)] - public string CurrentPassword { get; set; } - - [Required] - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))] - [Display(Name = "DisplayName:NewPassword")] - [DataType(DataType.Password)] - public string NewPassword { get; set; } - - [Required] - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))] - [Display(Name = "DisplayName:NewPasswordConfirm")] - [DataType(DataType.Password)] - public string NewPasswordConfirm { get; set; } - } - - public class PersonalSettingsInfoModel - { - [Required] - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))] - [Display(Name = "DisplayName:UserName")] - public string UserName { get; set; } - - [Required] - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))] - [Display(Name = "DisplayName:Email")] - public string Email { get; set; } - - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxNameLength))] - [Display(Name = "DisplayName:Name")] - public string Name { get; set; } - - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxSurnameLength))] - [Display(Name = "DisplayName:Surname")] - public string Surname { get; set; } - - [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))] - [Display(Name = "DisplayName:PhoneNumber")] - public string PhoneNumber { get; set; } - } } diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.js b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.js deleted file mode 100644 index 3c7c4148e8..0000000000 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.js +++ /dev/null @@ -1,47 +0,0 @@ -(function ($) { - var l = abp.localization.getResource('AbpAccount'); - - var _profileService = volo.abp.identity.profile; - - $('#ChangePasswordForm').submit(function (e) { - e.preventDefault(); - - if (!$('#ChangePasswordForm').valid()) { - return false; - } - - var input = $('#ChangePasswordForm').serializeFormToObject() - .changePasswordInfoModel; - - if ( - input.newPassword != input.newPasswordConfirm || - input.newPassword == '' - ) { - abp.message.error(l('NewPasswordConfirmFailed')); - return; - } - - if (input.currentPassword && input.currentPassword == ''){ - return; - } - - _profileService.changePassword(input).then(function (result) { - abp.message.success(l('PasswordChanged')); - }); - }); - - $('#PersonalSettingsForm').submit(function (e) { - e.preventDefault(); - - if (!$('#PersonalSettingsForm').valid()) { - return false; - } - - var input = $('#PersonalSettingsForm').serializeFormToObject() - .personalSettingsInfoModel; - - _profileService.update(input).then(function (result) { - abp.notify.success(l('PersonalSettingsSaved')); - }); - }); -})(jQuery); diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs index a8ec942084..0560197cd3 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs @@ -18,7 +18,6 @@ namespace Volo.Abp.Account.Web.Pages.Account { public class RegisterModel : AccountPageModel { - protected IAccountAppService AccountAppService { get; } [BindProperty(SupportsGet = true)] public string ReturnUrl { get; set; } diff --git a/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/AccountProfileManagementPageContributor.cs b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/AccountProfileManagementPageContributor.cs new file mode 100644 index 0000000000..3f2a11ac86 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/AccountProfileManagementPageContributor.cs @@ -0,0 +1,48 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.Password; +using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo; +using Volo.Abp.Identity; +using Volo.Abp.Users; + +namespace Volo.Abp.Account.Web.ProfileManagement +{ + public class AccountProfileManagementPageContributor : IProfileManagementPageContributor + { + public async Task ConfigureAsync(ProfileManagementPageCreationContext context) + { + var l = context.ServiceProvider.GetRequiredService>(); + + if (await IsPasswordChangeEnabled(context)) + { + context.Groups.Add( + new ProfileManagementPageGroup( + "Volo.Abp.Account.Password", + l["ProfileTab:Password"], + typeof(AccountProfilePasswordManagementGroupViewComponent) + ) + ); + } + + context.Groups.Add( + new ProfileManagementPageGroup( + "Volo.Abp.Account.PersonalInfo", + l["ProfileTab:PersonalInfo"], + typeof(AccountProfilePersonalInfoManagementGroupViewComponent) + ) + ); + } + + protected virtual async Task IsPasswordChangeEnabled(ProfileManagementPageCreationContext context) + { + var userManager = context.ServiceProvider.GetRequiredService(); + var currentUser = context.ServiceProvider.GetRequiredService(); + + var user = await userManager.GetByIdAsync(currentUser.GetId()); + + return !user.IsExternal; + } + } +} diff --git a/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/IProfileManagementPageContributor.cs b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/IProfileManagementPageContributor.cs new file mode 100644 index 0000000000..d65cc1fb0d --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/IProfileManagementPageContributor.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + + namespace Volo.Abp.Account.Web.ProfileManagement +{ + public interface IProfileManagementPageContributor + { + Task ConfigureAsync(ProfileManagementPageCreationContext context); + } +} diff --git a/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageCreationContext.cs b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageCreationContext.cs new file mode 100644 index 0000000000..f3a9a80de7 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageCreationContext.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.Account.Web.ProfileManagement +{ + public class ProfileManagementPageCreationContext + { + public IServiceProvider ServiceProvider { get; } + + public List Groups { get; } + + public ProfileManagementPageCreationContext(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + + Groups = new List(); + } + } +} diff --git a/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageGroup.cs b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageGroup.cs new file mode 100644 index 0000000000..ff491107aa --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageGroup.cs @@ -0,0 +1,39 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.Account.Web.ProfileManagement +{ + public class ProfileManagementPageGroup + { + public string Id + { + get => _id; + set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id)); + } + private string _id; + + public string DisplayName + { + get => _displayName; + set => _displayName = Check.NotNullOrWhiteSpace(value, nameof(DisplayName)); + } + private string _displayName; + + public Type ComponentType + { + get => _componentType; + set => _componentType = Check.NotNull(value, nameof(ComponentType)); + } + private Type _componentType; + + public object Parameter { get; set; } + + public ProfileManagementPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null) + { + Id = id; + DisplayName = displayName; + ComponentType = componentType; + Parameter = parameter; + } + } +} diff --git a/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageOptions.cs b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageOptions.cs new file mode 100644 index 0000000000..91cf0ab0c1 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageOptions.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + + namespace Volo.Abp.Account.Web.ProfileManagement +{ + public class ProfileManagementPageOptions + { + public List Contributors { get; } + + public ProfileManagementPageOptions() + { + Contributors = new List(); + } + } +} diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs index 5cac32faae..a8d213a81f 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.AuditLogging.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Abp.AuditLogging.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } -} \ No newline at end of file +} diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs index 07be76b792..a7ec1ad65f 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.BackgroundJobs.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Abp.BackgroundJobs.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } -} \ No newline at end of file +} diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/MongoDB/BlobStoringDatabaseMongoDbTestModule.cs b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/MongoDB/BlobStoringDatabaseMongoDbTestModule.cs index 03eb96f6d3..12cb8b0de3 100644 --- a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/MongoDB/BlobStoringDatabaseMongoDbTestModule.cs +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/MongoDB/BlobStoringDatabaseMongoDbTestModule.cs @@ -1,25 +1,31 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.BlobStoring.Database.MongoDB { [DependsOn( typeof(BlobStoringDatabaseTestBaseModule), typeof(BlobStoringDatabaseMongoDbModule) - )] + )] public class BlobStoringDatabaseMongoDbTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } -} \ No newline at end of file +} diff --git a/modules/blogging/app/Volo.BloggingTestApp/package.json b/modules/blogging/app/Volo.BloggingTestApp/package.json index f608db303b..bf5ad9c093 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/package.json +++ b/modules/blogging/app/Volo.BloggingTestApp/package.json @@ -3,7 +3,7 @@ "name": "volo.blogtestapp", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3", - "@abp/blogging": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2", + "@abp/blogging": "^3.1.2" } } \ No newline at end of file diff --git a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock index c69f117723..2064046256 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock +++ b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock @@ -2,37 +2,37 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -41,213 +41,213 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/blogging@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-3.1.0-rc.3.tgz#5c21c1dc57d832de35e89621fd81653599e676ad" - integrity sha512-8iAe29fzdCH4YAp3+8JSMrT0E0/OfUSQ9sIxGXrlV4GyEX2iGZrszRyKsKA+bgQmBOQdnT36RrmSOl0K/A+Mxw== +"@abp/blogging@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-3.1.2.tgz#7adde6ee9cccfcc3b7c0715491d4856daaff02db" + integrity sha512-4QKq5uvGxXAJlu5Vb6D5Njap0Llb4VhqqV1LFvgR14ARb8n5BguqL66Pt+Ke5nPXxaZJz5VbyUl1P3Gp+iqS8w== dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - "@abp/owl.carousel" "~3.1.0-rc.3" - "@abp/prismjs" "~3.1.0-rc.3" - "@abp/tui-editor" "~3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + "@abp/owl.carousel" "~3.1.2" + "@abp/prismjs" "~3.1.2" + "@abp/tui-editor" "~3.1.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/clipboard@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-3.1.0-rc.3.tgz#40f0a95298cf9d7097d8e7f96e42c181e5a9907b" - integrity sha512-efCjrAHN3d7zmq4eVzlT4H/s6K11I9K7hv4fIJP6fbZKDoXi5hzTv2+dt9JRDWAra+s87PdBJq7AEWNs6ONiGg== +"@abp/clipboard@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-3.1.2.tgz#ee561db080c6b0836fd77628543cc3c31cd687c8" + integrity sha512-ybx3E1eLsfrPhPDb8f/KQJrH8G9+E5+WNsmYopKkQP2v3Un/9QGme7CslT7oytExJ7P++Y3LZ2ZhfBwQLicxxQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" clipboard "^2.0.6" -"@abp/codemirror@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-3.1.0-rc.3.tgz#db68462bc6618734daa30f928feb65e0cca8cf53" - integrity sha512-TJz21MreoVePouWjnQKQ6gD9cXWQkS7xTl4V93i69C6m9f/ozoaoJvm3Va3GGGZMKf6u2B8G+XX7d6QGz406hg== +"@abp/codemirror@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-3.1.2.tgz#63701fd6eb30bd45d4251cca2d5bbd75b8491f6b" + integrity sha512-BxW3y/Ps7iiczlmctyvn3gjTnpGJnDfQtKVfeZ0TYKRbbs4B5z3ZHPhYAxH+t6eULJcyzIWBxl3UgrgjTaadgA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" codemirror "^5.54.0" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/highlight.js@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-3.1.0-rc.3.tgz#d1e92b44ebd6cc6fc49a18cf350bf24b12be2792" - integrity sha512-rb9/ryoEK2krMh3DLYQcqTyvSaI7BYlOd6+awDYl5iWXu8TK+M1NP9zSM8ZoYr0kkLoD1dGHsF4ondCfCYjxPQ== +"@abp/highlight.js@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-3.1.2.tgz#24f22bbd762532d82af8f3dcbbbc48bd05d0c716" + integrity sha512-GAEKizLly5U8XlKJ+pogiNLRnLo8hocpMpUNr61FR+y1crROS0g2pSCe0Iuq+BNuBX+npJKpUpv1GIQwY3cQqQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/markdown-it@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-3.1.0-rc.3.tgz#74a1e2c20654988159f332a01790a74d7ffb6b92" - integrity sha512-6k5e+WRfE4I0vp4KmV44FLQXvT8u+UUtdzPJOotWERWePuCVLJqM0u0hht0s5uEoTOhfCONIYwqQoGjzfP/8lg== +"@abp/markdown-it@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-3.1.2.tgz#8437038687cabb9679ab81c2e995d4ff3823f22f" + integrity sha512-hoxIO05mf3WNiT2l5iQNjvJQO3p8F6nkVyW9b4ZOHcZoGFQb8DWPp3ONBJk/ZRVYpYfo+/n3sB4ADsUi2oin3w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" markdown-it "^11.0.0" -"@abp/owl.carousel@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-3.1.0-rc.3.tgz#c419eccaeb18150dab5b7fdd2da102a26a6d6013" - integrity sha512-lLJuhCJ5/879juIHqLPrNos+zOyBb7cuvpzAF+IE+6/Jb9yP5Xn9O8004F2ELXRag0bHZVzCgCbtPmDDF+LkNQ== +"@abp/owl.carousel@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-3.1.2.tgz#86e272d3f88d34a201cdea2220f6eb415a4ed85f" + integrity sha512-/zIB15W6HFq9ssq9YWHWrikV/fH6gID4X2gkJWeuz89MUg/dtJlPWLMfiN8zAKgG6Uf7rbBmJ4C2/ilI5IoEgA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" owl.carousel "^2.3.4" -"@abp/prismjs@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-3.1.0-rc.3.tgz#d13885bf613871f6cd003f58ae01ee4587ad15ad" - integrity sha512-gaKxJ3d78oR1wGZhnPzM5EJIAsibh3VT9MFithFt/YAQdrMMOqS1fEdGsm1zO/A7Veyho9Ba/144RmPkFXH5gQ== +"@abp/prismjs@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-3.1.2.tgz#884011843c44d85a80d4fd85648bc94ef119bbd6" + integrity sha512-UQAOc/FgISgvTi1irPQjehJ42pLEaA1m5K1JileFTCWwUji/t5Vb8RSQe4cjIKPwRpb6p7CEJLI9SFxCtUEF8g== dependencies: - "@abp/clipboard" "~3.1.0-rc.3" - "@abp/core" "~3.1.0-rc.3" + "@abp/clipboard" "~3.1.2" + "@abp/core" "~3.1.2" prismjs "^1.20.0" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/tui-editor@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-3.1.0-rc.3.tgz#31c66f06b938ec416276907e539f51da389be01c" - integrity sha512-V3drpSK2l+WwfHWnK+9BFB33Ww+ruo6GFuOhyzDXjmXhOOMeiM2c/r205v+Bm/uEB0GaCW1m/r3yfogFfMipIw== +"@abp/tui-editor@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-3.1.2.tgz#8796a2518d7d43babf19018ae4deaf347046a93b" + integrity sha512-CH1yixb6C+3tRcKu6lrXOToj+jxca5IvVMO0Hfa8xeoGt+FZdS9ATMEiBB09TVhNL/jxAAb7qT4YaXNzk1BOtg== dependencies: - "@abp/codemirror" "~3.1.0-rc.3" - "@abp/highlight.js" "~3.1.0-rc.3" - "@abp/jquery" "~3.1.0-rc.3" - "@abp/markdown-it" "~3.1.0-rc.3" + "@abp/codemirror" "~3.1.2" + "@abp/highlight.js" "~3.1.2" + "@abp/jquery" "~3.1.2" + "@abp/markdown-it" "~3.1.2" tui-editor "^1.4.10" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs index 1e68cebf21..f66922cfcd 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Blogging.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Blogging.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } -} \ No newline at end of file +} diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json index ba93a68173..9305044f86 100644 --- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json +++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json @@ -3,6 +3,6 @@ "name": "client-simulation-web", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2" } } \ No newline at end of file diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock index c2b1f9abfe..be010610b3 100644 --- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock +++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock @@ -2,37 +2,37 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -41,144 +41,144 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/modules/cms-kit/angular/package.json b/modules/cms-kit/angular/package.json index 85a81a84fe..01bac82422 100644 --- a/modules/cms-kit/angular/package.json +++ b/modules/cms-kit/angular/package.json @@ -15,11 +15,11 @@ }, "private": true, "dependencies": { - "@abp/ng.account": "~3.1.0-rc.3", - "@abp/ng.identity": "~3.1.0-rc.3", - "@abp/ng.setting-management": "~3.1.0-rc.3", - "@abp/ng.tenant-management": "~3.1.0-rc.3", - "@abp/ng.theme.basic": "~3.1.0-rc.3", + "@abp/ng.account": "~3.1.2", + "@abp/ng.identity": "~3.1.2", + "@abp/ng.setting-management": "~3.1.2", + "@abp/ng.tenant-management": "~3.1.2", + "@abp/ng.theme.basic": "~3.1.2", "@angular/animations": "~10.0.0", "@angular/common": "~10.0.0", "@angular/compiler": "~10.0.0", diff --git a/modules/cms-kit/angular/projects/cms-kit/package.json b/modules/cms-kit/angular/projects/cms-kit/package.json index ea7a45336c..e527f269d4 100644 --- a/modules/cms-kit/angular/projects/cms-kit/package.json +++ b/modules/cms-kit/angular/projects/cms-kit/package.json @@ -4,8 +4,8 @@ "peerDependencies": { "@angular/common": "^9.1.11", "@angular/core": "^9.1.11", - "@abp/ng.core": ">=3.1.0-rc.3", - "@abp/ng.theme.shared": ">=3.1.0-rc.3" + "@abp/ng.core": ">=3.1.2", + "@abp/ng.theme.shared": ">=3.1.2" }, "dependencies": { "tslib": "^2.0.0" diff --git a/modules/cms-kit/common.props b/modules/cms-kit/common.props index 0e2bf35066..420d9c492c 100644 --- a/modules/cms-kit/common.props +++ b/modules/cms-kit/common.props @@ -2,7 +2,7 @@ latest 0.1.0 - $(NoWarn);CS1591 + $(NoWarn);CS1591;CS0436 module diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs index f1a9b8568f..fe9df5d7b6 100644 --- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Security.Claims; using IdentityModel; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.DataProtection; @@ -108,12 +109,12 @@ namespace Volo.CmsKit AbpClaimTypes.Role = JwtClaimTypes.Role; AbpClaimTypes.Email = JwtClaimTypes.Email; - context.Services.AddAuthentication("Bearer") - .AddIdentityServerAuthentication(options => + context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => { options.Authority = configuration["AuthServer:Authority"]; options.RequireHttpsMetadata = false; - options.ApiName = "CmsKit"; + options.Audience = "CmsKit"; }); Configure(options => diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj index 9fa7c4be20..99b2d0f1c0 100644 --- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj @@ -13,7 +13,8 @@ - + + diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs index b9afe934a3..5fbff7cfeb 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/CmsKitIdentityServerModule.cs @@ -123,11 +123,11 @@ namespace Volo.CmsKit }); context.Services.AddAuthentication() - .AddIdentityServerAuthentication(options => + .AddJwtBearer(options => { options.Authority = configuration["AuthServer:Authority"]; options.RequireHttpsMetadata = false; - options.ApiName = configuration["AuthServer:ApiName"]; + options.Audience = configuration["AuthServer:ApiName"]; }); Configure(options => diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/Volo.CmsKit.IdentityServer.csproj b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/Volo.CmsKit.IdentityServer.csproj index b26c2bbe06..a32a6c2dc3 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/Volo.CmsKit.IdentityServer.csproj +++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/Volo.CmsKit.IdentityServer.csproj @@ -11,7 +11,6 @@ - diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json index 726d61c566..526fb222ef 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json +++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json @@ -3,6 +3,6 @@ "name": "my-app-identityserver", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2" } } \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock index 46ec79f40e..2e73b4cb6f 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock @@ -2,37 +2,37 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -41,144 +41,144 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json index f53cfbaa36..aa8511a4d3 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json @@ -3,6 +3,6 @@ "name": "my-app", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2" } } \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock index 56e0030b46..ecbaee6414 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock @@ -2,37 +2,37 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -41,144 +41,144 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs index 08dadb3dd6..e5d9f23c05 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Linq; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200826063729_CmsRatings_Added.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200826063729_CmsRatings_Added.Designer.cs new file mode 100644 index 0000000000..00e1003584 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200826063729_CmsRatings_Added.Designer.cs @@ -0,0 +1,1235 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20200826063729_CmsRatings_Added")] + partial class CmsRatings_Added + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("ProductVersion", "3.1.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasColumnName("ApplicationName") + .HasColumnType("nvarchar(96)") + .HasMaxLength(96); + + b.Property("BrowserInfo") + .HasColumnName("BrowserInfo") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("ClientId") + .HasColumnName("ClientId") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ClientIpAddress") + .HasColumnName("ClientIpAddress") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ClientName") + .HasColumnName("ClientName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("Comments") + .HasColumnName("Comments") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CorrelationId") + .HasColumnName("CorrelationId") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Exceptions") + .HasColumnName("Exceptions") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("ExecutionDuration") + .HasColumnName("ExecutionDuration") + .HasColumnType("int"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("HttpMethod") + .HasColumnName("HttpMethod") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("HttpStatusCode") + .HasColumnName("HttpStatusCode") + .HasColumnType("int"); + + b.Property("ImpersonatorTenantId") + .HasColumnName("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("ImpersonatorUserId") + .HasColumnName("ImpersonatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasColumnName("Url") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("UserId") + .HasColumnName("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnName("AuditLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ExecutionDuration") + .HasColumnName("ExecutionDuration") + .HasColumnType("int"); + + b.Property("ExecutionTime") + .HasColumnName("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("MethodName") + .HasColumnName("MethodName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("Parameters") + .HasColumnName("Parameters") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("ServiceName") + .HasColumnName("ServiceName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnName("AuditLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ChangeTime") + .HasColumnName("ChangeTime") + .HasColumnType("datetime2"); + + b.Property("ChangeType") + .HasColumnName("ChangeType") + .HasColumnType("tinyint"); + + b.Property("EntityId") + .IsRequired() + .HasColumnName("EntityId") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasColumnName("EntityTypeFullName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasColumnName("NewValue") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("OriginalValue") + .HasColumnName("OriginalValue") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PropertyName") + .IsRequired() + .HasColumnName("PropertyName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasColumnName("PropertyTypeFullName") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("Description") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("Regex") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("RegexDescription") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDefault") + .HasColumnName("IsDefault") + .HasColumnType("bit"); + + b.Property("IsPublic") + .HasColumnName("IsPublic") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnName("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(1024)") + .HasMaxLength(1024); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnName("AccessFailedCount") + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnName("DeleterId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasColumnName("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("uniqueidentifier"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("LockoutEnabled") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasColumnName("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("NormalizedEmail") + .IsRequired() + .HasColumnName("NormalizedEmail") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .IsRequired() + .HasColumnName("NormalizedUserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnName("PasswordHash") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("SecurityStamp") + .IsRequired() + .HasColumnName("SecurityStamp") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("Surname") + .HasColumnName("Surname") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("TwoFactorEnabled") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(1024)") + .HasMaxLength(1024); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasColumnType("nvarchar(196)") + .HasMaxLength(196); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Name") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnName("Code") + .HasColumnType("nvarchar(95)") + .HasMaxLength(95); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnName("DeleterId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnName("DisplayName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("uniqueidentifier"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProviderName") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2048)") + .HasMaxLength(2048); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnName("DeleterId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(1024)") + .HasMaxLength(1024); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Text") + .IsRequired() + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ReactionName") + .IsRequired() + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("Email") + .IsRequired() + .HasColumnName("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnName("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Surname") + .HasColumnName("Surname") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200826063729_CmsRatings_Added.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200826063729_CmsRatings_Added.cs new file mode 100644 index 0000000000..d753d65865 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200826063729_CmsRatings_Added.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class CmsRatings_Added : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CmsRatings", + columns: table => new + { + Id = table.Column(nullable: false), + TenantId = table.Column(nullable: true), + EntityType = table.Column(maxLength: 64, nullable: false), + EntityId = table.Column(maxLength: 64, nullable: false), + StarCount = table.Column(nullable: false), + CreatorId = table.Column(nullable: false), + CreationTime = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsRatings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_CmsRatings_TenantId_EntityType_EntityId", + table: "CmsRatings", + columns: new[] { "TenantId", "EntityType", "EntityId" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CmsRatings"); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 931ed2b852..43d834479a 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1,1196 +1,1233 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Volo.Abp.EntityFrameworkCore; -using Volo.CmsKit.EntityFrameworkCore; - -namespace Volo.CmsKit.Migrations -{ - [DbContext(typeof(UnifiedDbContext))] - partial class UnifiedDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "3.1.6") - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ApplicationName") - .HasColumnName("ApplicationName") - .HasColumnType("nvarchar(96)") - .HasMaxLength(96); - - b.Property("BrowserInfo") - .HasColumnName("BrowserInfo") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("ClientId") - .HasColumnName("ClientId") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("ClientIpAddress") - .HasColumnName("ClientIpAddress") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("ClientName") - .HasColumnName("ClientName") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("Comments") - .HasColumnName("Comments") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("CorrelationId") - .HasColumnName("CorrelationId") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("Exceptions") - .HasColumnName("Exceptions") - .HasColumnType("nvarchar(4000)") - .HasMaxLength(4000); - - b.Property("ExecutionDuration") - .HasColumnName("ExecutionDuration") - .HasColumnType("int"); - - b.Property("ExecutionTime") - .HasColumnType("datetime2"); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("HttpMethod") - .HasColumnName("HttpMethod") - .HasColumnType("nvarchar(16)") - .HasMaxLength(16); - - b.Property("HttpStatusCode") - .HasColumnName("HttpStatusCode") - .HasColumnType("int"); - - b.Property("ImpersonatorTenantId") - .HasColumnName("ImpersonatorTenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("ImpersonatorUserId") - .HasColumnName("ImpersonatorUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantName") - .HasColumnType("nvarchar(max)"); - - b.Property("Url") - .HasColumnName("Url") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("UserId") - .HasColumnName("UserId") - .HasColumnType("uniqueidentifier"); - - b.Property("UserName") - .HasColumnName("UserName") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("TenantId", "ExecutionTime"); - - b.HasIndex("TenantId", "UserId", "ExecutionTime"); - - b.ToTable("AbpAuditLogs"); - }); - - modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AuditLogId") - .HasColumnName("AuditLogId") - .HasColumnType("uniqueidentifier"); - - b.Property("ExecutionDuration") - .HasColumnName("ExecutionDuration") - .HasColumnType("int"); - - b.Property("ExecutionTime") - .HasColumnName("ExecutionTime") - .HasColumnType("datetime2"); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("MethodName") - .HasColumnName("MethodName") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("Parameters") - .HasColumnName("Parameters") - .HasColumnType("nvarchar(2000)") - .HasMaxLength(2000); - - b.Property("ServiceName") - .HasColumnName("ServiceName") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("AuditLogId"); - - b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); - - b.ToTable("AbpAuditLogActions"); - }); - - modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AuditLogId") - .HasColumnName("AuditLogId") - .HasColumnType("uniqueidentifier"); - - b.Property("ChangeTime") - .HasColumnName("ChangeTime") - .HasColumnType("datetime2"); - - b.Property("ChangeType") - .HasColumnName("ChangeType") - .HasColumnType("tinyint"); - - b.Property("EntityId") - .IsRequired() - .HasColumnName("EntityId") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("EntityTenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("EntityTypeFullName") - .IsRequired() - .HasColumnName("EntityTypeFullName") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("AuditLogId"); - - b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); - - b.ToTable("AbpEntityChanges"); - }); - - modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("EntityChangeId") - .HasColumnType("uniqueidentifier"); - - b.Property("NewValue") - .HasColumnName("NewValue") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("OriginalValue") - .HasColumnName("OriginalValue") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("PropertyName") - .IsRequired() - .HasColumnName("PropertyName") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("PropertyTypeFullName") - .IsRequired() - .HasColumnName("PropertyTypeFullName") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("EntityChangeId"); - - b.ToTable("AbpEntityPropertyChanges"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("Description") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("IsStatic") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("Regex") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("RegexDescription") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("Required") - .HasColumnType("bit"); - - b.Property("ValueType") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.ToTable("AbpClaimTypes"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDefault") - .HasColumnName("IsDefault") - .HasColumnType("bit"); - - b.Property("IsPublic") - .HasColumnName("IsPublic") - .HasColumnType("bit"); - - b.Property("IsStatic") - .HasColumnName("IsStatic") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("NormalizedName") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName"); - - b.ToTable("AbpRoles"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("ClaimType") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(1024)") - .HasMaxLength(1024); - - b.Property("RoleId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AbpRoleClaims"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AccessFailedCount") - .ValueGeneratedOnAdd() - .HasColumnName("AccessFailedCount") - .HasColumnType("int") - .HasDefaultValue(0); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeleterId") - .HasColumnName("DeleterId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeletionTime") - .HasColumnName("DeletionTime") - .HasColumnType("datetime2"); - - b.Property("Email") - .IsRequired() - .HasColumnName("Email") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("EmailConfirmed") - .ValueGeneratedOnAdd() - .HasColumnName("EmailConfirmed") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnName("IsDeleted") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("LastModificationTime") - .HasColumnName("LastModificationTime") - .HasColumnType("datetime2"); - - b.Property("LastModifierId") - .HasColumnName("LastModifierId") - .HasColumnType("uniqueidentifier"); - - b.Property("LockoutEnabled") - .ValueGeneratedOnAdd() - .HasColumnName("LockoutEnabled") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("Name") - .HasColumnName("Name") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("NormalizedEmail") - .IsRequired() - .HasColumnName("NormalizedEmail") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("NormalizedUserName") - .IsRequired() - .HasColumnName("NormalizedUserName") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("PasswordHash") - .HasColumnName("PasswordHash") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("PhoneNumber") - .HasColumnName("PhoneNumber") - .HasColumnType("nvarchar(16)") - .HasMaxLength(16); - - b.Property("PhoneNumberConfirmed") - .ValueGeneratedOnAdd() - .HasColumnName("PhoneNumberConfirmed") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("SecurityStamp") - .IsRequired() - .HasColumnName("SecurityStamp") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("Surname") - .HasColumnName("Surname") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("TwoFactorEnabled") - .ValueGeneratedOnAdd() - .HasColumnName("TwoFactorEnabled") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("UserName") - .IsRequired() - .HasColumnName("UserName") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("Email"); - - b.HasIndex("NormalizedEmail"); - - b.HasIndex("NormalizedUserName"); - - b.HasIndex("UserName"); - - b.ToTable("AbpUsers"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("ClaimType") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(1024)") - .HasMaxLength(1024); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AbpUserClaims"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => - { - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("ProviderKey") - .IsRequired() - .HasColumnType("nvarchar(196)") - .HasMaxLength(196); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("UserId", "LoginProvider"); - - b.HasIndex("LoginProvider", "ProviderKey"); - - b.ToTable("AbpUserLogins"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => - { - b.Property("OrganizationUnitId") - .HasColumnType("uniqueidentifier"); - - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("OrganizationUnitId", "UserId"); - - b.HasIndex("UserId", "OrganizationUnitId"); - - b.ToTable("AbpUserOrganizationUnits"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.Property("RoleId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId", "UserId"); - - b.ToTable("AbpUserRoles"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("Name") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AbpUserTokens"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Code") - .IsRequired() - .HasColumnName("Code") - .HasColumnType("nvarchar(95)") - .HasMaxLength(95); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeleterId") - .HasColumnName("DeleterId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeletionTime") - .HasColumnName("DeletionTime") - .HasColumnType("datetime2"); - - b.Property("DisplayName") - .IsRequired() - .HasColumnName("DisplayName") - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnName("IsDeleted") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("LastModificationTime") - .HasColumnName("LastModificationTime") - .HasColumnType("datetime2"); - - b.Property("LastModifierId") - .HasColumnName("LastModifierId") - .HasColumnType("uniqueidentifier"); - - b.Property("ParentId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("Code"); - - b.HasIndex("ParentId"); - - b.ToTable("AbpOrganizationUnits"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => - { - b.Property("OrganizationUnitId") - .HasColumnType("uniqueidentifier"); - - b.Property("RoleId") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("OrganizationUnitId", "RoleId"); - - b.HasIndex("RoleId", "OrganizationUnitId"); - - b.ToTable("AbpOrganizationUnitRoles"); - }); - - modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("ProviderKey") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("ProviderName") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("Name", "ProviderName", "ProviderKey"); - - b.ToTable("AbpPermissionGrants"); - }); - - modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(128)") - .HasMaxLength(128); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("ProviderName") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("Value") - .IsRequired() - .HasColumnType("nvarchar(2048)") - .HasMaxLength(2048); - - b.HasKey("Id"); - - b.HasIndex("Name", "ProviderName", "ProviderKey"); - - b.ToTable("AbpSettings"); - }); - - modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeleterId") - .HasColumnName("DeleterId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeletionTime") - .HasColumnName("DeletionTime") - .HasColumnType("datetime2"); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnName("IsDeleted") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("LastModificationTime") - .HasColumnName("LastModificationTime") - .HasColumnType("datetime2"); - - b.Property("LastModifierId") - .HasColumnName("LastModifierId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.HasKey("Id"); - - b.HasIndex("Name"); - - b.ToTable("AbpTenants"); - }); - - modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => - { - b.Property("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("Value") - .IsRequired() - .HasColumnType("nvarchar(1024)") - .HasMaxLength(1024); - - b.HasKey("TenantId", "Name"); - - b.ToTable("AbpTenantConnectionStrings"); - }); - - modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("EntityId") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("EntityType") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("RepliedCommentId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("Text") - .IsRequired() - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.HasKey("Id"); - - b.HasIndex("TenantId", "RepliedCommentId"); - - b.HasIndex("TenantId", "EntityType", "EntityId"); - - b.ToTable("CmsComments"); - }); - - modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnName("CreationTime") - .HasColumnType("datetime2"); - - b.Property("CreatorId") - .HasColumnName("CreatorId") - .HasColumnType("uniqueidentifier"); - - b.Property("EntityId") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("EntityType") - .IsRequired() - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("ReactionName") - .IsRequired() - .HasColumnType("nvarchar(32)") - .HasMaxLength(32); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); - - b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); - - b.ToTable("CmsUserReactions"); - }); - - modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnName("ConcurrencyStamp") - .HasColumnType("nvarchar(40)") - .HasMaxLength(40); - - b.Property("Email") - .IsRequired() - .HasColumnName("Email") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("EmailConfirmed") - .ValueGeneratedOnAdd() - .HasColumnName("EmailConfirmed") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("ExtraProperties") - .HasColumnName("ExtraProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasColumnName("Name") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("PhoneNumber") - .HasColumnName("PhoneNumber") - .HasColumnType("nvarchar(16)") - .HasMaxLength(16); - - b.Property("PhoneNumberConfirmed") - .ValueGeneratedOnAdd() - .HasColumnName("PhoneNumberConfirmed") - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("Surname") - .HasColumnName("Surname") - .HasColumnType("nvarchar(64)") - .HasMaxLength(64); - - b.Property("TenantId") - .HasColumnName("TenantId") - .HasColumnType("uniqueidentifier"); - - b.Property("UserName") - .IsRequired() - .HasColumnName("UserName") - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("TenantId", "Email"); - - b.HasIndex("TenantId", "UserName"); - - b.ToTable("CmsUsers"); - }); - - modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => - { - b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) - .WithMany("Actions") - .HasForeignKey("AuditLogId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => - { - b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) - .WithMany("EntityChanges") - .HasForeignKey("AuditLogId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => - { - b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) - .WithMany("PropertyChanges") - .HasForeignKey("EntityChangeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => - { - b.HasOne("Volo.Abp.Identity.IdentityRole", null) - .WithMany("Claims") - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => - { - b.HasOne("Volo.Abp.Identity.IdentityUser", null) - .WithMany("Claims") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => - { - b.HasOne("Volo.Abp.Identity.IdentityUser", null) - .WithMany("Logins") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => - { - b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) - .WithMany() - .HasForeignKey("OrganizationUnitId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Volo.Abp.Identity.IdentityUser", null) - .WithMany("OrganizationUnits") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => - { - b.HasOne("Volo.Abp.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Volo.Abp.Identity.IdentityUser", null) - .WithMany("Roles") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => - { - b.HasOne("Volo.Abp.Identity.IdentityUser", null) - .WithMany("Tokens") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => - { - b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) - .WithMany() - .HasForeignKey("ParentId"); - }); - - modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => - { - b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) - .WithMany("Roles") - .HasForeignKey("OrganizationUnitId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Volo.Abp.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => - { - b.HasOne("Volo.Abp.TenantManagement.Tenant", null) - .WithMany("ConnectionStrings") - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + partial class UnifiedDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("ProductVersion", "3.1.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasColumnName("ApplicationName") + .HasColumnType("nvarchar(96)") + .HasMaxLength(96); + + b.Property("BrowserInfo") + .HasColumnName("BrowserInfo") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("ClientId") + .HasColumnName("ClientId") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ClientIpAddress") + .HasColumnName("ClientIpAddress") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ClientName") + .HasColumnName("ClientName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("Comments") + .HasColumnName("Comments") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CorrelationId") + .HasColumnName("CorrelationId") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Exceptions") + .HasColumnName("Exceptions") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("ExecutionDuration") + .HasColumnName("ExecutionDuration") + .HasColumnType("int"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("HttpMethod") + .HasColumnName("HttpMethod") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("HttpStatusCode") + .HasColumnName("HttpStatusCode") + .HasColumnType("int"); + + b.Property("ImpersonatorTenantId") + .HasColumnName("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("ImpersonatorUserId") + .HasColumnName("ImpersonatorUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasColumnName("Url") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("UserId") + .HasColumnName("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnName("AuditLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ExecutionDuration") + .HasColumnName("ExecutionDuration") + .HasColumnType("int"); + + b.Property("ExecutionTime") + .HasColumnName("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("MethodName") + .HasColumnName("MethodName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("Parameters") + .HasColumnName("Parameters") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("ServiceName") + .HasColumnName("ServiceName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnName("AuditLogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ChangeTime") + .HasColumnName("ChangeTime") + .HasColumnType("datetime2"); + + b.Property("ChangeType") + .HasColumnName("ChangeType") + .HasColumnType("tinyint"); + + b.Property("EntityId") + .IsRequired() + .HasColumnName("EntityId") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasColumnName("EntityTypeFullName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasColumnName("NewValue") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("OriginalValue") + .HasColumnName("OriginalValue") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PropertyName") + .IsRequired() + .HasColumnName("PropertyName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasColumnName("PropertyTypeFullName") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("Description") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("Regex") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("RegexDescription") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDefault") + .HasColumnName("IsDefault") + .HasColumnType("bit"); + + b.Property("IsPublic") + .HasColumnName("IsPublic") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnName("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(1024)") + .HasMaxLength(1024); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnName("AccessFailedCount") + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnName("DeleterId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasColumnName("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("uniqueidentifier"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("LockoutEnabled") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasColumnName("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("NormalizedEmail") + .IsRequired() + .HasColumnName("NormalizedEmail") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .IsRequired() + .HasColumnName("NormalizedUserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnName("PasswordHash") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("SecurityStamp") + .IsRequired() + .HasColumnName("SecurityStamp") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("Surname") + .HasColumnName("Surname") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("TwoFactorEnabled") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(1024)") + .HasMaxLength(1024); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasColumnType("nvarchar(196)") + .HasMaxLength(196); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Name") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnName("Code") + .HasColumnType("nvarchar(95)") + .HasMaxLength(95); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnName("DeleterId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnName("DisplayName") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("uniqueidentifier"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProviderName") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2048)") + .HasMaxLength(2048); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnName("DeleterId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeletionTime") + .HasColumnName("DeletionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnName("IsDeleted") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime2"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(1024)") + .HasMaxLength(1024); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Text") + .IsRequired() + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ReactionName") + .IsRequired() + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("Email") + .IsRequired() + .HasColumnName("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnName("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Surname") + .HasColumnName("Surname") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml index 95faf6c6ee..c33377a8cc 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml @@ -5,6 +5,7 @@ @using Volo.CmsKit.GlobalFeatures @using Volo.CmsKit.Pages @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection @model IndexModel @inject IStringLocalizer Localizer @@ -41,6 +42,12 @@ +
+@if (GlobalFeatureManager.Instance.IsEnabled()) +{ + @await Component.InvokeAsync(typeof(RatingViewComponent), new { entityType = "quote", entityId = "2" }) +} +
@if (GlobalFeatureManager.Instance.IsEnabled()) { @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new { entityType = "quote", entityId = "2" }) @@ -49,4 +56,4 @@ { @await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "quote", entityId = "2" }) } -
\ No newline at end of file +
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json index f53cfbaa36..aa8511a4d3 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json @@ -3,6 +3,6 @@ "name": "my-app", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2" } } \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/star-rating-svg/css/star-rating-svg.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/star-rating-svg/css/star-rating-svg.css new file mode 100644 index 0000000000..2c0114687f --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/star-rating-svg/css/star-rating-svg.css @@ -0,0 +1,37 @@ +.jq-stars { + display: inline-block; +} + +.jq-rating-label { + font-size: 22px; + display: inline-block; + position: relative; + vertical-align: top; + font-family: helvetica, arial, verdana; +} + +.jq-star { + width: 100px; + height: 100px; + display: inline-block; + cursor: pointer; +} + +.jq-star-svg { + width: 100%; + height: 100% ; +} + +.jq-star:hover .fs-star-svg polygon { +} + +.jq-star-svg polygon { + stroke: #000; + stroke-linejoin: round; +} + +/* un-used */ +.jq-shadow { + -webkit-filter: drop-shadow( -2px -2px 2px #888 ); + filter: drop-shadow( -2px -2px 2px #888 ); +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/star-rating-svg/js/jquery.star-rating-svg.min.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/star-rating-svg/js/jquery.star-rating-svg.min.js new file mode 100644 index 0000000000..df947cfe2b --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/star-rating-svg/js/jquery.star-rating-svg.min.js @@ -0,0 +1 @@ +!function(a){"use strict";var b="starRating",c=function(){},d={totalStars:5,useFullStars:!1,emptyColor:"lightgray",hoverColor:"orange",activeColor:"gold",useGradient:!0,readOnly:!1,disableAfterRate:!0,starGradient:{start:"#FEF7CD",end:"#FF9511"},strokeWidth:0,strokeColor:"black",initialRating:0,starSize:40,callback:c,onHover:c,onLeave:c},e=function(c,e){var f;this.element=c,this.$el=a(c),this.settings=a.extend({},d,e),f=this.$el.data("rating")||this.settings.initialRating,this._state={rating:(Math.round(2*f)/2).toFixed(1)},this._uid=Math.floor(999*Math.random()),e.starGradient||this.settings.useGradient||(this.settings.starGradient.start=this.settings.starGradient.end=this.settings.activeColor),this._defaults=d,this._name=b,this.init()},f={init:function(){this.renderMarkup(),this.addListeners(),this.initRating()},addListeners:function(){this.settings.readOnly||(this.$stars.on("mouseover",this.hoverRating.bind(this)),this.$stars.on("mouseout",this.restoreState.bind(this)),this.$stars.on("click",this.handleRating.bind(this)))},hoverRating:function(a){var b=this.getIndex(a);this.paintStars(b,"hovered"),this.settings.onHover(b+1,this._state.rating,this.$el)},handleRating:function(a){var b=this.getIndex(a),c=b+1;this.applyRating(c,this.$el),this.executeCallback(c,this.$el),this.settings.disableAfterRate&&this.$stars.off()},applyRating:function(a){var b=a-1;this.paintStars(b,"active"),this._state.rating=b+1},restoreState:function(a){var b=this.getIndex(a),c=this._state.rating||-1;this.paintStars(c-1,"active"),this.settings.onLeave(b+1,this._state.rating,this.$el)},getIndex:function(b){var c=a(b.currentTarget),d=c.width(),e=a(b.target).attr("data-side");e=e?e:this.getOffsetByPixel(b,c,d),e=this.settings.useFullStars?"right":e;var f=c.index()-("left"===e?.5:0);return f=.5>f&&b.offsetX=d&&!this.settings.useFullStars?"left":"right"},initRating:function(){this.paintStars(this._state.rating-1,"active")},paintStars:function(b,c){var d,e,f,g;a.each(this.$stars,function(h,i){d=a(i).find('polygon[data-side="left"]'),e=a(i).find('polygon[data-side="right"]'),f=g=b>=h?c:"empty",f=h-b===.5?c:f,d.attr("class","svg-"+f+"-"+this._uid),e.attr("class","svg-"+g+"-"+this._uid)}.bind(this))},renderMarkup:function(){for(var a='
"+this.getLinearGradient(this._uid+"_SVGID_1_",this.settings.emptyColor,this.settings.emptyColor)+this.getLinearGradient(this._uid+"_SVGID_2_",this.settings.hoverColor,this.settings.hoverColor)+this.getLinearGradient(this._uid+"_SVGID_3_",this.settings.starGradient.start,this.settings.starGradient.end)+'
',b="",c=0;c '},executeCallback:function(a,b){var c=this.settings.callback;c(a,b)}},g={unload:function(){var c="plugin_"+b,d=a(this),e=d.data(c).$stars;e.off(),d.removeData(c).remove()},setRating:function(c,d){var e="plugin_"+b,f=a(this),g=f.data(e);c>g.settings.totalStars||0>c||(d&&(c=Math.round(c)),g.applyRating(c))},getRating:function(){var c="plugin_"+b,d=a(this),e=d.data(c);return e._state.rating}};a.extend(e.prototype,f),a.fn[b]=function(c){if(!a.isPlainObject(c)){if(g.hasOwnProperty(c))return g[c].apply(this,Array.prototype.slice.call(arguments,1));a.error("Method "+c+" does not exist on "+b+".js")}return this.each(function(){a.data(this,"plugin_"+b)||a.data(this,"plugin_"+b,new e(this,c))})}}(jQuery,window,document); \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock index 27339975b7..7473b4ed5f 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock @@ -2,37 +2,37 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -41,144 +41,144 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs index 646a91ef4f..bb7694262b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs @@ -11,11 +11,14 @@ namespace Volo.CmsKit.GlobalFeatures public CommentsFeature Comments => GetFeature(); + public RatingsFeature Ratings => GetFeature(); + public GlobalCmsKitFeatures([NotNull] GlobalFeatureManager featureManager) : base(featureManager) { AddFeature(new ReactionsFeature(this)); AddFeature(new CommentsFeature(this)); + AddFeature(new RatingsFeature(this)); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/RatingsFeature.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/RatingsFeature.cs new file mode 100644 index 0000000000..b982d6cebb --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/RatingsFeature.cs @@ -0,0 +1,18 @@ +using JetBrains.Annotations; +using Volo.Abp.GlobalFeatures; + +namespace Volo.CmsKit.GlobalFeatures +{ + [GlobalFeatureName(Name)] + public class RatingsFeature : GlobalFeature + { + public const string Name = "CmsKit.Ratings"; + + internal RatingsFeature( + [NotNull] GlobalCmsKitFeatures cmsKit + ) : base(cmsKit) + { + + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 3e16a17a47..73fd2d52b6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -13,6 +13,10 @@ "LoginToAddComment": "Login to add comment", "LoginToReply": "Login to reply", "MessageDeletionConfirmationMessage": "This comment will be deleted completely.", - "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display." + "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", + "Undo": "Undo", + "RatingUndoMessage": "Your rating will be undo.", + "LoginToRate": "Login to rate", + "Star": "Star" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index c1664f9122..777e89c979 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -13,6 +13,10 @@ "LoginToAddComment": "Yorum yapmak için giriş yap", "LoginToReply": "Cevap vermek için giriş yap", "MessageDeletionConfirmationMessage": "Bu yorum tamamen silinecektir", - "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir." + "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.", + "Undo": "Geri al", + "RatingUndoMessage": "Oylamanız geri alınacak.", + "LoginToRate": "Oylamak için giriş yapın", + "Star": "Yıldız" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Ratings/RatingConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Ratings/RatingConsts.cs new file mode 100644 index 0000000000..e3bf6c399d --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Ratings/RatingConsts.cs @@ -0,0 +1,15 @@ +using Volo.CmsKit.Entities; + +namespace Volo.CmsKit.Ratings +{ + public static class RatingConsts + { + public static int MaxEntityTypeLength { get; set; } = CmsEntityConsts.MaxEntityTypeLength; + + public static int MaxEntityIdLength { get; set; } = CmsEntityConsts.MaxEntityIdLength; + + public static int MaxStarCount { get; set; } = 5; + + public static int MinStarCount { get; set; } = 1; + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/IRatingRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/IRatingRepository.cs new file mode 100644 index 0000000000..a9f71b0dfb --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/IRatingRepository.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Domain.Repositories; + +namespace Volo.CmsKit.Ratings +{ + public interface IRatingRepository : IBasicRepository + { + Task GetCurrentUserRatingAsync( + [NotNull] string entityType, + [NotNull] string entityId, + Guid userId, + CancellationToken cancellationToken = default + ); + + Task> GetGroupedStarCountsAsync( + [NotNull] string entityType, + [NotNull] string entityId, + CancellationToken cancellationToken = default + ); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/Rating.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/Rating.cs new file mode 100644 index 0000000000..a3575cf0b4 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/Rating.cs @@ -0,0 +1,57 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace Volo.CmsKit.Ratings +{ + public class Rating : BasicAggregateRoot, IHasCreationTime, IMustHaveCreator + { + public virtual Guid? TenantId { get; protected set; } + + public virtual string EntityType { get; protected set; } + + public virtual string EntityId { get; protected set; } + + public virtual short StarCount { get; protected set; } + + public virtual Guid CreatorId { get; set; } + + public virtual DateTime CreationTime { get; set; } + + protected Rating() + { + + } + + public Rating( + Guid id, + [NotNull] string entityType, + [NotNull] string entityId, + short starCount, + Guid creatorId, + Guid? tenantId = null + ) + : base(id) + { + EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType), RatingConsts.MaxEntityTypeLength); + EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId), RatingConsts.MaxEntityIdLength); + SetStarCount(starCount); + CreatorId = creatorId; + TenantId = tenantId; + } + + public virtual void SetStarCount(short starCount) + { + if(starCount <= RatingConsts.MaxStarCount && starCount >= RatingConsts.MinStarCount) + { + StarCount = starCount; + } + else + { + throw new ArgumentOutOfRangeException($"Choosen star must between {RatingConsts.MinStarCount} and {RatingConsts.MaxStarCount}"); + } + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/RatingWithStarCountQueryResultItem.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/RatingWithStarCountQueryResultItem.cs new file mode 100644 index 0000000000..5f53074b97 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Ratings/RatingWithStarCountQueryResultItem.cs @@ -0,0 +1,9 @@ +namespace Volo.CmsKit.Ratings +{ + public class RatingWithStarCountQueryResultItem + { + public short StarCount { get; set; } + + public int Count { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index a26b22883e..adda59c3e2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -8,6 +8,7 @@ using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; using Volo.Abp.Users.EntityFrameworkCore; using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Ratings; namespace Volo.CmsKit.EntityFrameworkCore { @@ -71,6 +72,22 @@ namespace Volo.CmsKit.EntityFrameworkCore b.HasIndex(x => new { x.TenantId, x.RepliedCommentId }); }); } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + builder.Entity(r => + { + r.ToTable(options.TablePrefix + "Ratings", options.Schema); + + r.ConfigureByConvention(); + + r.Property(x => x.StarCount).IsRequired(); + r.Property(x => x.EntityType).IsRequired().HasMaxLength(RatingConsts.MaxEntityTypeLength); + r.Property(x => x.EntityId).IsRequired().HasMaxLength(RatingConsts.MaxEntityIdLength); + + r.HasIndex(x => new {x.TenantId, x.EntityType, x.EntityId, x.CreatorId}); + }); + } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs index c528da7d5e..33e57cab37 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs @@ -3,6 +3,7 @@ using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; using Volo.Abp.Users.EntityFrameworkCore; using Volo.CmsKit.Comments; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; @@ -22,6 +23,7 @@ namespace Volo.CmsKit.EntityFrameworkCore options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Ratings/EfCoreRatingRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Ratings/EfCoreRatingRepository.cs new file mode 100644 index 0000000000..810335b4d6 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Ratings/EfCoreRatingRepository.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Volo.Abp; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Ratings +{ + public class EfCoreRatingRepository : EfCoreRepository, IRatingRepository + { + public EfCoreRatingRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public async Task GetCurrentUserRatingAsync(string entityType, string entityId, Guid userId, + CancellationToken cancellationToken = default) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + + var rating = await DbSet.FirstOrDefaultAsync( + r => r.EntityType == entityType && r.EntityId == entityId && r.CreatorId == userId, + GetCancellationToken(cancellationToken)); + + return rating; + } + + public async Task> GetGroupedStarCountsAsync(string entityType, + string entityId, CancellationToken cancellationToken = default) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + + var query = ( + from rating in DbSet + where rating.EntityType == entityType && rating.EntityId == entityId + group rating by rating.StarCount + into g + select new RatingWithStarCountQueryResultItem + { + StarCount = g.Key, + Count = g.Count() + } + ).OrderByDescending(r => r.StarCount); + + var ratings = await query.ToListAsync(GetCancellationToken(cancellationToken)); + + return ratings; + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs index 63bf48a14e..09053167f9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs @@ -2,6 +2,7 @@ using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; @@ -16,6 +17,8 @@ namespace Volo.CmsKit.MongoDB public IMongoCollection CmsUsers => Collection(); + public IMongoCollection Ratings => Collection(); + protected override void CreateModel(IMongoModelBuilder modelBuilder) { base.CreateModel(modelBuilder); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs index 568e136591..2dc4c55a71 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs @@ -2,6 +2,7 @@ using Volo.Abp; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; @@ -35,6 +36,11 @@ namespace Volo.CmsKit.MongoDB { x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Comments"; }); + + builder.Entity(x => + { + x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Ratings"; + }); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs index 736b30ada1..d479821b38 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs @@ -4,8 +4,10 @@ using Volo.Abp.MongoDB; using Volo.Abp.Users.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.MongoDB.Comments; +using Volo.CmsKit.MongoDB.Ratings; using Volo.CmsKit.MongoDB.Reactions; using Volo.CmsKit.MongoDB.Users; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; @@ -25,6 +27,7 @@ namespace Volo.CmsKit.MongoDB options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs index 16b72c8902..40914a9720 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs @@ -2,6 +2,7 @@ using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; @@ -15,5 +16,7 @@ namespace Volo.CmsKit.MongoDB IMongoCollection Comments { get; } IMongoCollection CmsUsers { get; } + + IMongoCollection Ratings { get; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Ratings/MongoRatingRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Ratings/MongoRatingRepository.cs new file mode 100644 index 0000000000..92f7f992da --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Ratings/MongoRatingRepository.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using Volo.Abp; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; +using Volo.CmsKit.Ratings; + +namespace Volo.CmsKit.MongoDB.Ratings +{ + public class MongoRatingRepository : MongoDbRepository, IRatingRepository + { + public MongoRatingRepository(IMongoDbContextProvider dbContextProvider) : base( + dbContextProvider) + { + } + + public async Task GetCurrentUserRatingAsync(string entityType, string entityId, Guid userId, + CancellationToken cancellationToken = default) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + + var rating = await GetMongoQueryable() + .FirstOrDefaultAsync(r => r.EntityType == entityType && r.EntityId == entityId && r.CreatorId == userId, + GetCancellationToken(cancellationToken)); + + return rating; + } + + public async Task> GetGroupedStarCountsAsync(string entityType, + string entityId, CancellationToken cancellationToken = default) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + + var query = ( + from rating in GetMongoQueryable() + where rating.EntityType == entityType && rating.EntityId == entityId + group rating by rating.StarCount + into g + select new RatingWithStarCountQueryResultItem + { + StarCount = g.Key, + Count = g.Count() + } + ).OrderByDescending(r => r.StarCount); + + var ratings = await query.ToListAsync(GetCancellationToken(cancellationToken)); + + return ratings; + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo.CmsKit.Public.Application.Contracts.csproj b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo.CmsKit.Public.Application.Contracts.csproj index f44c745740..8515d28e83 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo.CmsKit.Public.Application.Contracts.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo.CmsKit.Public.Application.Contracts.csproj @@ -1,15 +1,15 @@ - - - - - - - netstandard2.0 - - - - - - - - + + + + + + + netstandard2.0 + + + + + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/CreateUpdateRatingInput.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/CreateUpdateRatingInput.cs new file mode 100644 index 0000000000..0577a97a68 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/CreateUpdateRatingInput.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; +using Volo.CmsKit.Ratings; + +namespace Volo.CmsKit.Public.Ratings +{ + public class CreateUpdateRatingInput + { + [Required] + [DynamicRange(typeof(RatingConsts), typeof(int), nameof(RatingConsts.MinStarCount), nameof(RatingConsts.MaxStarCount))] + public short StarCount { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/IRatingPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/IRatingPublicAppService.cs new file mode 100644 index 0000000000..aa0aba48b4 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/IRatingPublicAppService.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Volo.CmsKit.Public.Ratings +{ + public interface IRatingPublicAppService : IApplicationService + { + Task CreateAsync(string entityType, string entityId, CreateUpdateRatingInput input); + + Task DeleteAsync(string entityType, string entityId); + + Task GetCurrentUserRatingAsync(string entityType, string entityId); + + Task> GetGroupedStarCountsAsync(string entityType, string entityId); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/RatingDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/RatingDto.cs new file mode 100644 index 0000000000..bf050465c9 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/RatingDto.cs @@ -0,0 +1,19 @@ +using System; + +namespace Volo.CmsKit.Public.Ratings +{ + public class RatingDto + { + public Guid Id { get; set; } + + public string EntityType { get; set; } + + public string EntityId { get; set; } + + public short StarCount { get; set; } + + public Guid CreatorId { get; set; } + + public DateTime CreationTime { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/RatingWithStarCountDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/RatingWithStarCountDto.cs new file mode 100644 index 0000000000..981ef2bd6e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Ratings/RatingWithStarCountDto.cs @@ -0,0 +1,11 @@ +namespace Volo.CmsKit.Public.Ratings +{ + public class RatingWithStarCountDto + { + public short StarCount { get; set; } + + public int Count { get; set; } + + public bool IsSelectedByCurrentUser { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj index a8a9613fbf..702523e3c6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj @@ -1,16 +1,16 @@ - - - - - - - netstandard2.0 - - - - - - - - - + + + + + + + netstandard2.0 + + + + + + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs index e0b64bb0e8..3ac2d1949b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs @@ -2,6 +2,8 @@ using Volo.Abp.AutoMapper; using Volo.CmsKit.Comments; using Volo.CmsKit.Public.Comments; +using Volo.CmsKit.Public.Ratings; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Users; namespace Volo.CmsKit.Public @@ -18,6 +20,8 @@ namespace Volo.CmsKit.Public CreateMap() .Ignore(x=> x.Replies) .Ignore(x=> x.Author); + + CreateMap(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs new file mode 100644 index 0000000000..848dbeda28 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Ratings/RatingPublicAppService.cs @@ -0,0 +1,104 @@ +using System; +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; +using Volo.CmsKit.Ratings; +using Volo.CmsKit.Users; + +namespace Volo.CmsKit.Public.Ratings +{ + public class RatingPublicAppService : ApplicationService, IRatingPublicAppService + { + protected IRatingRepository RatingRepository { get; } + public ICmsUserLookupService CmsUserLookupService { get; } + + public RatingPublicAppService(IRatingRepository ratingRepository, ICmsUserLookupService cmsUserLookupService) + { + RatingRepository = ratingRepository; + CmsUserLookupService = cmsUserLookupService; + } + + [Authorize] + public virtual async Task CreateAsync(string entityType, string entityId, + CreateUpdateRatingInput input) + { + var userId = CurrentUser.GetId(); + var user = await CmsUserLookupService.GetByIdAsync(userId); + + var currentUserRating = await RatingRepository.GetCurrentUserRatingAsync(entityType, entityId, userId); + + if (currentUserRating != null) + { + currentUserRating.SetStarCount(input.StarCount); + var updatedRating = await RatingRepository.UpdateAsync(currentUserRating); + + return ObjectMapper.Map(updatedRating); + } + + var rating = await RatingRepository.InsertAsync( + new Rating( + GuidGenerator.Create(), + entityType, + entityId, + input.StarCount, + user.Id, + CurrentTenant.Id + ) + ); + + return ObjectMapper.Map(rating); + } + + [Authorize] + public virtual async Task DeleteAsync(string entityType, string entityId) + { + var rating = await RatingRepository.GetCurrentUserRatingAsync(entityType, entityId, CurrentUser.GetId()); + + if (rating.CreatorId != CurrentUser.GetId()) + { + throw new AbpAuthorizationException(); + } + + await RatingRepository.DeleteAsync(rating.Id); + } + + [Authorize] + public virtual async Task GetCurrentUserRatingAsync(string entityType, string entityId) + { + var currentUserId = CurrentUser.GetId(); + + var rating = await RatingRepository.GetCurrentUserRatingAsync(entityType, entityId, currentUserId); + + return ObjectMapper.Map(rating); + } + + public virtual async Task> GetGroupedStarCountsAsync(string entityType, + string entityId) + { + var ratings = await RatingRepository.GetGroupedStarCountsAsync(entityType, entityId); + + var userRatingOrNull = CurrentUser.IsAuthenticated + ? await RatingRepository.GetCurrentUserRatingAsync(entityType, entityId, CurrentUser.GetId()) + : null; + + var ratingWithStarCountDto = new List(); + + foreach (var rating in ratings) + { + ratingWithStarCountDto.Add( + new RatingWithStarCountDto + { + StarCount = rating.StarCount, + Count = rating.Count, + IsSelectedByCurrentUser = userRatingOrNull != null && userRatingOrNull.StarCount == rating.StarCount + }); + } + + return ratingWithStarCountDto; + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo.CmsKit.Public.HttpApi.csproj b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo.CmsKit.Public.HttpApi.csproj index da54b3d2bf..ec87dac00f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo.CmsKit.Public.HttpApi.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo.CmsKit.Public.HttpApi.csproj @@ -1,16 +1,16 @@ - - - - - - - netcoreapp3.1 - - - - - - - - - + + + + + + + netcoreapp3.1 + + + + + + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Ratings/RatingPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Ratings/RatingPublicController.cs new file mode 100644 index 0000000000..e136c4564d --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Ratings/RatingPublicController.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; + +namespace Volo.CmsKit.Public.Ratings +{ + [RequiresGlobalFeature(typeof(RatingsFeature))] + [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Route("api/cms-kit-public/ratings")] + public class RatingPublicController : CmsKitPublicControllerBase, IRatingPublicAppService + { + protected IRatingPublicAppService RatingPublicAppService { get; } + + public RatingPublicController(IRatingPublicAppService ratingPublicAppService) + { + RatingPublicAppService = ratingPublicAppService; + } + + [HttpPut] + [Route("{entityType}/{entityId}")] + public virtual Task CreateAsync(string entityType, string entityId, CreateUpdateRatingInput input) + { + return RatingPublicAppService.CreateAsync(entityType, entityId, input); + } + + [HttpDelete] + [Route("{entityType}/{entityId}")] + public virtual Task DeleteAsync(string entityType, string entityId) + { + return RatingPublicAppService.DeleteAsync(entityType, entityId); + } + + [HttpGet] + [Route("{entityType}/{entityId}")] + public virtual Task GetCurrentUserRatingAsync(string entityType, string entityId) + { + return RatingPublicAppService.GetCurrentUserRatingAsync(entityType, entityId); + } + + [HttpGet] + [Route("{entityType}/{entityId}")] + public virtual Task> GetGroupedStarCountsAsync(string entityType, string entityId) + { + return RatingPublicAppService.GetGroupedStarCountsAsync(entityType, entityId); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs index c130ebefca..e0b1f9d6f3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting; +using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating; using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection; namespace Volo.CmsKit.Public.Web.Controllers @@ -16,5 +17,10 @@ namespace Volo.CmsKit.Public.Web.Controllers { return Task.FromResult((IActionResult)ViewComponent(typeof(CommentingViewComponent), new {entityType, entityId})); } + + public Task Rating(string entityType, string entityId) + { + return Task.FromResult((IActionResult) ViewComponent(typeof(RatingViewComponent), new {entityType, entityId})); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index ab7fc9805b..f988dd29e7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -175,7 +175,7 @@ } - @if (comment.Replies.Count >= 5) + @if (comment.Replies.Count >= 3) {
@if (CurrentUser.IsAuthenticated) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/Default.cshtml new file mode 100644 index 0000000000..82397e49c4 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/Default.cshtml @@ -0,0 +1,46 @@ +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Users +@using Volo.CmsKit.Localization +@inject ICurrentUser CurrentUser +@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating.RatingViewModel +@inject IHtmlLocalizer L + +
+ @if (CurrentUser.IsAuthenticated) + { +
+ + @(Model.CurrentRating != null ? Model.CurrentRating + " | " : 0 + "") + @if (Model.CurrentRating != null) + { + + @L["Undo"] + + } +
+ if (Model.Ratings != null) + { +
+ @foreach (var rating in Model.Ratings) + { +
+
@rating.StarCount @L["Star"]
+
+
+
+
+
+
+
+
@rating.Count
+
+ } +
+ } + } + else + { +
"> + + } +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingScriptBundleContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingScriptBundleContributor.cs new file mode 100644 index 0000000000..4340cea485 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingScriptBundleContributor.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.StarRatingSvg; +using Volo.Abp.Modularity; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating +{ + [DependsOn(typeof(StarRatingSvgScriptContributor))] + public class RatingScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/Pages/CmsKit/Shared/Components/Rating/default.js"); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingStyleBundleContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingStyleBundleContributor.cs new file mode 100644 index 0000000000..bd017f9d1e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingStyleBundleContributor.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.StarRatingSvg; +using Volo.Abp.Modularity; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating +{ + [DependsOn(typeof(StarRatingSvgStyleContributor))] + public class RatingStyleBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/Pages/CmsKit/Shared/Components/Rating/default.css"); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingViewComponent.cs new file mode 100644 index 0000000000..cae050ea40 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/RatingViewComponent.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; +using Volo.Abp.Users; +using Volo.CmsKit.Public.Ratings; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating +{ + [ViewComponent(Name = "CmsRating")] + [Widget( + StyleTypes = new[] {typeof(RatingStyleBundleContributor)}, + ScriptTypes = new[] {typeof(RatingScriptBundleContributor)}, + RefreshUrl = "/CmsKitPublicWidgets/Rating" + )] + public class RatingViewComponent : AbpViewComponent + { + public IRatingPublicAppService RatingPublicAppService { get; } + public AbpMvcUiOptions AbpMvcUiOptions { get; } + public ICurrentUser CurrentUser { get; } + + public RatingViewComponent(IRatingPublicAppService ratingPublicAppService, IOptions options, ICurrentUser currentUser) + { + RatingPublicAppService = ratingPublicAppService; + AbpMvcUiOptions = options.Value; + CurrentUser = currentUser; + } + + public virtual async Task InvokeAsync(string entityType, string entityId) + { + var ratings = await RatingPublicAppService.GetGroupedStarCountsAsync(entityType, entityId); + var totalRating = ratings.Sum(x => x.Count); + + short? currentUserRating = null; + if (CurrentUser.IsAuthenticated) + { + currentUserRating = ratings.Find(x => x.IsSelectedByCurrentUser)?.StarCount; + } + + var loginUrl = + $"{AbpMvcUiOptions.LoginUrl}?returnUrl={HttpContext.Request.Path.ToString()}&returnUrlHash=#cms-rating_{entityType}_{entityId}"; + + var viewModel = new RatingViewModel + { + EntityId = entityId, + EntityType = entityType, + LoginUrl = loginUrl, + Ratings = ratings, + CurrentRating = currentUserRating, + TotalRating = totalRating + }; + + return View("~/Pages/CmsKit/Shared/Components/Rating/Default.cshtml", viewModel); + } + } + + public class RatingViewModel + { + public string EntityType { get; set; } + + public string EntityId { get; set; } + + public string LoginUrl { get; set; } + + public List Ratings { get; set; } + + public short? CurrentRating { get; set; } + + public int TotalRating { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/default.css b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/default.css new file mode 100644 index 0000000000..c38f44cace --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/default.css @@ -0,0 +1,44 @@ +.side { + width: 15%; + margin-top:10px; +} + +.middle { + float: left; + width: 70%; + margin-top:10px; + padding-top: 4px; +} + +.row:after { + content: ""; + display: table; + clear: both; +} + +.bar-container { + width: 100%; + background-color: #f1f1f1; + text-align: center; + color: white; +} + +.bar { + height: 18px; +} + +/* Individual bars */ +.bar-5 { background-color: #173F5F; } +.bar-4 { background-color: #20639B; } +.bar-3 { background-color: #3CAEA3; } +.bar-2 { background-color: #F6D55C; } +.bar-1 { background-color: #ED553B; } + +@media (max-width: 400px) { + .side, .middle { + width: 100%; + } + .right { + display: none; + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/default.js b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/default.js new file mode 100644 index 0000000000..431fd7884b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Rating/default.js @@ -0,0 +1,87 @@ +(function () { + var l = abp.localization.getResource("CmsKit"); + + $(document).ready(function () { + abp.widgets.CmsRating = function ($widget) { + var widgetManager = $widget.data("abp-widget-manager"); + var $ratingArea = $widget.find(".cms-rating-area"); + + function getFilters() { + return { + entityType: $ratingArea.attr("data-entity-type"), + entityId: $ratingArea.attr("data-entity-id") + }; + } + + function registerCreateOfNewRating() { + $widget.find(".my-rating-5").each(function () { + var authenticated = $(this).attr("data-authenticated"); + + $(this).starRating({ + initialRating: 0, + disableAfterRate: true, + useFullStars: true, + readOnly: authenticated === "True", + onHover: function (currentIndex, currentRating, $el) { + $widget.find(".live-rating").text(currentIndex); + }, + onLeave: function (currentIndex, currentRating, $el) { + $widget.find(".live-rating").text(currentRating); + }, + callback: function (currentRating, $el) { + volo.cmsKit.public.ratings.ratingPublic.create( + $ratingArea.attr("data-entity-type"), + $ratingArea.attr("data-entity-id"), + { + starCount: parseInt(currentRating) + } + ).then(function () { + widgetManager.refresh($widget); + }) + } + }); + } + ); + } + + function registerUndoLink() { + $widget.find(".rating-undo-link").each(function () { + $(this).on('click', '', function (e) { + e.preventDefault(); + + abp.message.confirm(l("RatingUndoMessage"), function (ok) { + if (ok) { + volo.cmsKit.public.ratings.ratingPublic.delete( + $ratingArea.attr("data-entity-type"), + $ratingArea.attr("data-entity-id") + ).then(function () { + widgetManager.refresh($widget); + }); + } + }) + }); + }); + } + + function init() { + registerCreateOfNewRating(); + registerUndoLink(); + } + + return { + init: init, + getFilters: getFilters + } + }; + + $('.abp-widget-wrapper[data-widget-name="CmsRating"]') + .each(function () { + var widgetManager = new abp.WidgetManager({ + wrapper: $(this), + }); + + widgetManager.init($(this)); + }); + }); +}) +(jQuery); \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Ratings/RatingPublicAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Ratings/RatingPublicAppService_Tests.cs new file mode 100644 index 0000000000..c8f2acd950 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Ratings/RatingPublicAppService_Tests.cs @@ -0,0 +1,137 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using Shouldly; +using Volo.Abp.Users; +using Volo.CmsKit.Public.Ratings; +using Xunit; + +namespace Volo.CmsKit.Ratings +{ + public class RatingPublicAppService_Tests : CmsKitApplicationTestBase + { + private readonly IRatingPublicAppService _ratingAppService; + private ICurrentUser _currentUser; + private readonly CmsKitTestData _cmsKitTestData; + + public RatingPublicAppService_Tests() + { + _ratingAppService = GetRequiredService(); + _cmsKitTestData = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + _currentUser = Substitute.For(); + services.AddSingleton(_currentUser); + } + + [Fact] + public async Task CreateAsync() + { + _currentUser.Id.Returns(_cmsKitTestData.User1Id); + + var newRating = await _ratingAppService.CreateAsync( + _cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId2, + new CreateUpdateRatingInput + { + StarCount = 4 + }); + + UsingDbContext(context => + { + var ratings = context.Set().Where(x => + x.EntityId == _cmsKitTestData.EntityId1 && x.EntityType == _cmsKitTestData.EntityType1).ToList(); + + ratings + .Any(c => c.Id == newRating.Id && c.CreatorId == newRating.CreatorId && + c.StarCount == newRating.StarCount) + .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); + + var updatedEntity = await _ratingAppService.CreateAsync( + _cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1, + new CreateUpdateRatingInput + { + 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().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() + { + _currentUser.Id.Returns(_cmsKitTestData.User1Id); + + var ratings = await _ratingAppService.GetGroupedStarCountsAsync( + _cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1 + ); + + ratings.ShouldNotBeNull(); + ratings.Count.ShouldBeGreaterThan(0); + } + + [Fact] + public async Task DeleteAsync() + { + _currentUser.Id.Returns(_cmsKitTestData.User1Id); + + var rating = await _ratingAppService.CreateAsync( + _cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1, + new CreateUpdateRatingInput + { + StarCount = 4 + }); + + await _ratingAppService.DeleteAsync(_cmsKitTestData.EntityType1, _cmsKitTestData.EntityId1); + + UsingDbContext(context => + { + var deletedComment = context.Set().FirstOrDefault(x => x.Id == rating.Id); + + deletedComment.ShouldBeNull(); + }); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Reactions/ReactionPublicAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Reactions/ReactionPublicAppService_Tests.cs index 3872861ef7..9bf0e0b881 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Reactions/ReactionPublicAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Reactions/ReactionPublicAppService_Tests.cs @@ -60,14 +60,14 @@ namespace Volo.CmsKit.Reactions await _reactionPublicAppService.CreateAsync( _cmsKitTestData.EntityType2, _cmsKitTestData.EntityId2, - StandardReactions.Hooray + StandardReactions.Eyes ); UsingDbContext(context => { var reaction = context.Set().FirstOrDefault(x => x.CreatorId == _cmsKitTestData.User1Id && - x.ReactionName == StandardReactions.Hooray && + x.ReactionName == StandardReactions.Eyes && x.EntityId == _cmsKitTestData.EntityId2 && x.EntityType == _cmsKitTestData.EntityType2); diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Ratings/RatingRepository_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Ratings/RatingRepository_Tests.cs new file mode 100644 index 0000000000..390ddd1cb3 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Ratings/RatingRepository_Tests.cs @@ -0,0 +1,9 @@ +using Volo.CmsKit.Ratings; + +namespace Volo.CmsKit.EntityFrameworkCore.Ratings +{ + public class RatingRepository_Tests : RatingRepository_Tests + { + + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/CmsKitMongoDbTestModule.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/CmsKitMongoDbTestModule.cs index 125ec8dbd4..521b93cc8c 100644 --- a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/CmsKitMongoDbTestModule.cs +++ b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/CmsKitMongoDbTestModule.cs @@ -1,25 +1,31 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.CmsKit.MongoDB { [DependsOn( typeof(CmsKitTestBaseModule), typeof(CmsKitMongoDbModule) - )] + )] public class CmsKitMongoDbTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } -} \ No newline at end of file +} diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Ratings/RatingRepository_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Ratings/RatingRepository_Tests.cs new file mode 100644 index 0000000000..c0814253e6 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Ratings/RatingRepository_Tests.cs @@ -0,0 +1,11 @@ +using Volo.CmsKit.Ratings; +using Xunit; + +namespace Volo.CmsKit.MongoDB.Ratings +{ + [Collection(MongoTestCollection.Name)] + public class RatingRepository_Tests : RatingRepository_Tests + { + + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 12c6255623..f91e79fb84 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -4,6 +4,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.Users; using Volo.CmsKit.Comments; +using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; @@ -16,19 +17,22 @@ namespace Volo.CmsKit private readonly CmsKitTestData _cmsKitTestData; private readonly ICommentRepository _commentRepository; private readonly ReactionManager _reactionManager; + private readonly IRatingRepository _ratingRepository; public CmsKitDataSeedContributor( IGuidGenerator guidGenerator, ICmsUserRepository cmsUserRepository, CmsKitTestData cmsKitTestData, ICommentRepository commentRepository, - ReactionManager reactionManager) + ReactionManager reactionManager, + IRatingRepository ratingRepository) { _guidGenerator = guidGenerator; _cmsUserRepository = cmsUserRepository; _cmsKitTestData = cmsKitTestData; _commentRepository = commentRepository; _reactionManager = reactionManager; + _ratingRepository = ratingRepository; } public async Task SeedAsync(DataSeedContext context) @@ -38,13 +42,17 @@ namespace Volo.CmsKit await SeedCommentsAsync(); await SeedReactionsAsync(); + + await SeedRatingsAsync(); } private async Task SeedUsersAsync() { - await _cmsUserRepository.InsertAsync(new CmsUser(new UserData(_cmsKitTestData.User1Id, "user1", "user1@volo.com", + await _cmsUserRepository.InsertAsync(new CmsUser(new UserData(_cmsKitTestData.User1Id, "user1", + "user1@volo.com", "user", "1"))); - await _cmsUserRepository.InsertAsync(new CmsUser(new UserData(_cmsKitTestData.User2Id, "user2", "user2@volo.com", + await _cmsUserRepository.InsertAsync(new CmsUser(new UserData(_cmsKitTestData.User2Id, "user2", + "user2@volo.com", "user", "2"))); } @@ -131,5 +139,36 @@ namespace Volo.CmsKit _cmsKitTestData.EntityId1, StandardReactions.ThumbsUp); } + + private async Task SeedRatingsAsync() + { + await _ratingRepository.InsertAsync(new Rating(_guidGenerator.Create(), + _cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1, + 4, + _cmsKitTestData.User1Id + )); + + await _ratingRepository.InsertAsync(new Rating(_guidGenerator.Create(), + _cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1, + 5, + _cmsKitTestData.User1Id + )); + + await _ratingRepository.InsertAsync(new Rating(_guidGenerator.Create(), + _cmsKitTestData.EntityType2, + _cmsKitTestData.EntityId2, + 5, + _cmsKitTestData.User2Id + )); + + await _ratingRepository.InsertAsync(new Rating(_guidGenerator.Create(), + _cmsKitTestData.EntityType2, + _cmsKitTestData.EntityId2, + 1, + _cmsKitTestData.User2Id + )); + } } -} +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Ratings/RatingRepository_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Ratings/RatingRepository_Tests.cs new file mode 100644 index 0000000000..19da73cf50 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Ratings/RatingRepository_Tests.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.CmsKit.Ratings +{ + public abstract class RatingRepository_Tests : CmsKitTestBase + where TStartupModule : IAbpModule + { + private readonly CmsKitTestData _cmsKitTestData; + private readonly IRatingRepository _ratingRepository; + + public RatingRepository_Tests() + { + _cmsKitTestData = GetRequiredService(); + _ratingRepository = GetRequiredService(); + } + + [Fact] + public async Task GetCurrentUserRatingAsync() + { + var userRating = await _ratingRepository.GetCurrentUserRatingAsync(_cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1, _cmsKitTestData.User1Id); + + userRating.ShouldNotBeNull(); + userRating.EntityId.ShouldBe(_cmsKitTestData.EntityId1); + userRating.EntityType.ShouldBe(_cmsKitTestData.EntityType1); + userRating.CreatorId.ShouldBe(_cmsKitTestData.User1Id); + } + + [Fact] + public async Task GetGroupedStarCountsAsync() + { + var list = await _ratingRepository.GetGroupedStarCountsAsync(_cmsKitTestData.EntityType1, + _cmsKitTestData.EntityId1); + + list.ShouldNotBeNull(); + } + } +} \ No newline at end of file diff --git a/modules/docs/app/VoloDocs.Web/package.json b/modules/docs/app/VoloDocs.Web/package.json index b3e3660c63..6d35d0ecfd 100644 --- a/modules/docs/app/VoloDocs.Web/package.json +++ b/modules/docs/app/VoloDocs.Web/package.json @@ -3,7 +3,7 @@ "name": "volo.docstestapp", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.0-rc.3", - "@abp/docs": "^3.1.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2", + "@abp/docs": "^3.1.2" } } diff --git a/modules/docs/app/VoloDocs.Web/yarn.lock b/modules/docs/app/VoloDocs.Web/yarn.lock index 66321e210a..388d48a35f 100644 --- a/modules/docs/app/VoloDocs.Web/yarn.lock +++ b/modules/docs/app/VoloDocs.Web/yarn.lock @@ -2,45 +2,45 @@ # yarn lockfile v1 -"@abp/anchor-js@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/anchor-js/-/anchor-js-3.1.0-rc.3.tgz#839562d155fe9d026328da64a14e354c00090856" - integrity sha512-5NhcK1wZQlfE9gJ679DD3KsnYOigCHCqSGdwOQZn7gzGWNKnhCnzsnjAyh32lL9tNHTHMKkydVr6kJ5LU6Yr1Q== +"@abp/anchor-js@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/anchor-js/-/anchor-js-3.1.2.tgz#eb1f5043fad84622b7f3567963d5d94b5f8c60b3" + integrity sha512-cELNHIZA3mePvATpvQ/yVbu4gk36dESNxWkCB31nigRXo5mnjOv1YcDpyJzp8PjSk+oXJlwz5inFbiYMtQfaFQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" anchor-js "^4.2.2" -"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.0-rc.3.tgz#d7e3ad928a72efb7c76a585ef051fce860efb7bf" - integrity sha512-cc2Wp/6hr1j89Ap/474HlH54WhAIgCya1buuXxrxXSMdYqDKNxK61aMYC/mnYGMiyPqoz6TWWUJB2h2dZeTgzQ== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.0-rc.3.tgz#54a92d673f5158ee222d0d95ebfbca6c63b20a4f" - integrity sha512-czS+8+wuNxuNIogI3FI/T72dCumpbsXp9Fke9pwQEzkCZZCG11cJdOCr1pLJKT1G54x+zfgwVVFIL36sFcq50A== - dependencies: - "@abp/aspnetcore.mvc.ui" "~3.1.0-rc.3" - "@abp/bootstrap" "~3.1.0-rc.3" - "@abp/bootstrap-datepicker" "~3.1.0-rc.3" - "@abp/datatables.net-bs4" "~3.1.0-rc.3" - "@abp/font-awesome" "~3.1.0-rc.3" - "@abp/jquery-form" "~3.1.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~3.1.0-rc.3" - "@abp/lodash" "~3.1.0-rc.3" - "@abp/luxon" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/select2" "~3.1.0-rc.3" - "@abp/sweetalert" "~3.1.0-rc.3" - "@abp/timeago" "~3.1.0-rc.3" - "@abp/toastr" "~3.1.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.0-rc.3.tgz#e26f8ff9d7beaedf2050b9d6319e6368c990c373" - integrity sha512-qglA2lW0eQFzZlGeAev+vGuWsHNFmDeSCGAHPhd4Z07zjnphPnIOXSa+rXhb+4y6DevQP7OY/KSMQdX6ZMU3RQ== +"@abp/aspnetcore.mvc.ui.theme.basic@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-3.1.2.tgz#202b33837a470079c1bd44fbf4a645c071ad4a00" + integrity sha512-gvU9CJnEMBjNrRlpHGqlLK00xTdxcUe0z9ZRHucT9bPS3V4+Xe1c9cnpMM9oDpsMo5oha0suxTx695/G1t/jaA== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~3.1.2" + +"@abp/aspnetcore.mvc.ui.theme.shared@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-3.1.2.tgz#88ea020b1d26f3e551ff81b96a848c700bed97ca" + integrity sha512-CjqinzcmES96dJ+IzEDSYO+uJE3Z3k3CZ5jGfgg97N0rYCTkt9LzYpuFHGeX4W+qI2qMurr5jstgsuLQY0cCzg== + dependencies: + "@abp/aspnetcore.mvc.ui" "~3.1.2" + "@abp/bootstrap" "~3.1.2" + "@abp/bootstrap-datepicker" "~3.1.2" + "@abp/datatables.net-bs4" "~3.1.2" + "@abp/font-awesome" "~3.1.2" + "@abp/jquery-form" "~3.1.2" + "@abp/jquery-validation-unobtrusive" "~3.1.2" + "@abp/lodash" "~3.1.2" + "@abp/luxon" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/select2" "~3.1.2" + "@abp/sweetalert" "~3.1.2" + "@abp/timeago" "~3.1.2" + "@abp/toastr" "~3.1.2" + +"@abp/aspnetcore.mvc.ui@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-3.1.2.tgz#4689ff7e4b722803f2133856f2fb39171bbfd752" + integrity sha512-jlBR+IgKuNGCerHbx6BEn2f1Xf9Vi9Dgge1/5VYzqu2MVk7dHRXHE7WYkZqpJuQKZtGMxF3c8ul2/u6uGlkmqw== dependencies: ansi-colors "^4.1.1" extend-object "^1.0.0" @@ -49,180 +49,180 @@ path "^0.12.7" rimraf "^3.0.2" -"@abp/bootstrap-datepicker@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.0-rc.3.tgz#279d9603cd916a884bac125cb525ee44fb809762" - integrity sha512-qZolOk2Pw+IvXh6Ko7wJddzMVPbS8silGecBZMYe0DVRNovg0515Px8zR3GJ16wcVQuvG6ByBn4fdeKFmYfokQ== +"@abp/bootstrap-datepicker@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-3.1.2.tgz#90ed84f4345bf8e47c0a05511fab9c63a5a3424c" + integrity sha512-sY9jXReDXCNzuSoNCiSkUD9cbdj9W/AR/glOsCb29zC7GX3XLEykuT42b8W6Kl6prS5NgfmXaX2pZOuyv0KBeQ== dependencies: bootstrap-datepicker "^1.9.0" -"@abp/bootstrap@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.0-rc.3.tgz#a1368df757995f52c19dd76ef1846d19a067def6" - integrity sha512-r8XRTYJBEa33FVxF+Mg0ALYNhmTjVBw1NQIQY8Ub5ZR+HIZoaDqA0X5zfAKvGQlmfXLiZJDkvCV5EIQWsIgnrA== +"@abp/bootstrap@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-3.1.2.tgz#d80e14d0cfa0b3213fafecf275520eddd9b846e2" + integrity sha512-neI766oMxwrwrsQc477koPXaT2/yy1mG4djGvnC+g2DgLeqxU7ye6dt6Lf/rKmQuZD9jtz28920wPN3N4N/HrQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" bootstrap "^4.5.0" bootstrap-v4-rtl "4.4.1-2" -"@abp/clipboard@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-3.1.0-rc.3.tgz#40f0a95298cf9d7097d8e7f96e42c181e5a9907b" - integrity sha512-efCjrAHN3d7zmq4eVzlT4H/s6K11I9K7hv4fIJP6fbZKDoXi5hzTv2+dt9JRDWAra+s87PdBJq7AEWNs6ONiGg== +"@abp/clipboard@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-3.1.2.tgz#ee561db080c6b0836fd77628543cc3c31cd687c8" + integrity sha512-ybx3E1eLsfrPhPDb8f/KQJrH8G9+E5+WNsmYopKkQP2v3Un/9QGme7CslT7oytExJ7P++Y3LZ2ZhfBwQLicxxQ== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" clipboard "^2.0.6" -"@abp/core@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.0-rc.3.tgz#7e1bd9ac9aaecfc66863e8e319975358885a3ca2" - integrity sha512-wIvm4l8ZDQ+eiNN1a+v07EjUhngrxwPWvfDf9bPQpepfnIKiAktJziihh0oBJAbqXNqmI7f6FGN76spvNop/EA== +"@abp/core@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-3.1.2.tgz#1d204b2f6eb3c04e036a30b416ecf77d5ce51a47" + integrity sha512-Tb/E8VHTESFoioj0gO1PB5AxZB5aIZSgAS4/V5GFne4Z399DPwkX8+XJIIRtQVzlFySAdoA37Emml/7eHCvMMQ== dependencies: - "@abp/utils" "^3.1.0-rc.3" + "@abp/utils" "^3.1.2" -"@abp/datatables.net-bs4@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.0-rc.3.tgz#f46c4474635918c16ca7edbe4930c07317930592" - integrity sha512-FeN53p5U2hIyYyM3G3AuGSwBZFBGbx4yHb/ymW/DEGtJ6XtynHlsFPz00/PktLe0OKOjUxOUf2LQLqKJi83WQQ== +"@abp/datatables.net-bs4@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs4/-/datatables.net-bs4-3.1.2.tgz#23530f20d01776c34669c7d15df5ecd19beb6c95" + integrity sha512-dbJOTSkiyYHMW3Og9kQFqcSONNE+ElEHgfO/sfIT4Aj9hFpNHkGBTnaDTYXJ22ViFcSMWOTynvg6u+I3ZHe8qw== dependencies: - "@abp/datatables.net" "~3.1.0-rc.3" + "@abp/datatables.net" "~3.1.2" datatables.net-bs4 "^1.10.21" -"@abp/datatables.net@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.0-rc.3.tgz#c3a8f81d5ee571445b01d2db0e05ed555b1459b8" - integrity sha512-sOWuVwvSoQlXqC9CC9HGH6HzdHb5vVX8CbqzIUYBJEzY4NBRUqeclFJQrA/thjMNtefdLD2AiVwPFmAdGBeDSg== +"@abp/datatables.net@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-3.1.2.tgz#34a0718bdac6802336484c4011067cf665cdd413" + integrity sha512-TJWp/+sMZIQqEy1F7Zb4/kSvrUQoC3AfG5qrSFIRmKyZMEsuUzTLugtfYWUi0BKEHdc454ErWrGuD1MCMIzEsQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" datatables.net "^1.10.21" -"@abp/docs@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/docs/-/docs-3.1.0-rc.3.tgz#b5bab272c4094de8f38c04015cf7219f0931c8c5" - integrity sha512-o1R9Kvw2VKqyjHYmNXYGUhiJue1FaqgRIJmmR6z0ncND7swsz4Qb/2gQvws4bHo/dIl28yrzJeKNzXbE74hHgQ== +"@abp/docs@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/docs/-/docs-3.1.2.tgz#6c4e283c80cc502cf6e04ac3448265a8f02bad35" + integrity sha512-YnC+IiMLQuZsp8Lc/MC6uB4xAWSG5CVdCsxJdGOBtmPS2SlaE2+2nAM0TtBK7i7190zoCHda4PZRRjjAwtbvAQ== dependencies: - "@abp/anchor-js" "~3.1.0-rc.3" - "@abp/clipboard" "~3.1.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~3.1.0-rc.3" - "@abp/popper.js" "~3.1.0-rc.3" - "@abp/prismjs" "~3.1.0-rc.3" + "@abp/anchor-js" "~3.1.2" + "@abp/clipboard" "~3.1.2" + "@abp/malihu-custom-scrollbar-plugin" "~3.1.2" + "@abp/popper.js" "~3.1.2" + "@abp/prismjs" "~3.1.2" -"@abp/font-awesome@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.0-rc.3.tgz#38f63ad4fadc4986a73116fa29d5ef56812c483c" - integrity sha512-BnrI9XaKxEvI0d6Fa9tbw1J/VAsVUqTyAHva4WTUUa+neB9gaK62ZUjgDdF8Eo6gj7UOO8DYvsXehzpVpZKlPQ== +"@abp/font-awesome@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-3.1.2.tgz#1b14dc64cfe5f903bbcc25a4d2c88df54b561e87" + integrity sha512-33C0lAioBWcIs5wU+M7+SF06+Yvoq9BKVDjPx1R8TndphOfXU6IRneZvHDCLig76EY/BNcEYEREbv33Wqnie9Q== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" "@fortawesome/fontawesome-free" "^5.13.0" -"@abp/jquery-form@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.0-rc.3.tgz#7b74828f32a641c0b1ef1fd8b0389bf994a09e16" - integrity sha512-G+YRnDRZe5Mw81NAEnnr8scGjupndcu9xZ1dw+hCFGg30yypiUIfHtrMR4iR94y7M198fAgQP+0k7RvDqnALiw== +"@abp/jquery-form@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-3.1.2.tgz#8d516356e443e0ae8f1367ce3090e84a5afc2867" + integrity sha512-UCWZLnu7qETSeX69Wui0VtMpEiPrRv2+JsoJKsS3XcqXehNGJktMc5H5sNCDgPaQXzE5SY6hWnfLBj88014T6g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-form "^4.3.0" -"@abp/jquery-validation-unobtrusive@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.0-rc.3.tgz#aef83e8f11791ae7be449eab6655a73075f98b45" - integrity sha512-uWu6qdZasSZEFJC1IhEtj8NZq5kXX8W/zlK2tVpFhjxE/QYiJlPj8pVy2I7cuEIBghzAO2omwI+5En8TSagrGA== +"@abp/jquery-validation-unobtrusive@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.1.2.tgz#64e6c2f287c21a4a569f4152936e84afa4a66c50" + integrity sha512-soZjLE2ygApecWs9DqKh7hRkf067esvLXSQOwUvw5WdeHOWccgAu/GxzAeFzwNA3CpfjFGoHqNNeSnETLLVEUQ== dependencies: - "@abp/jquery-validation" "~3.1.0-rc.3" + "@abp/jquery-validation" "~3.1.2" jquery-validation-unobtrusive "^3.2.11" -"@abp/jquery-validation@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.0-rc.3.tgz#40dcb28ce5a3a87fc69972053e48a456c84e3225" - integrity sha512-uaL+ZS/NTf103Hq3ehayFT1qvq/Y2T5PAFY9ijBvX+7phCtPwGiIPfUvyuwYnKbdTa15odC275e7pY2CssHWIA== +"@abp/jquery-validation@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-3.1.2.tgz#a34fea85a67e2552d9ee278ecc22b5740bbcc5eb" + integrity sha512-RrzdY3nay9/OHpd58DyJ9oYnwr3++6gJoI135QMYz+otlJnUjrM6bFfqSeWQaetvbiCVy7nOVYVyqIFO7KgQUw== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" jquery-validation "^1.19.2" -"@abp/jquery@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.0-rc.3.tgz#8c35b9e7de888516e2acc5227092ca2fed991475" - integrity sha512-DT2uBNfW3+Xc1Bz62WHdIC3JfAb2Qcc4p86LyDG5pNRAd3FpImA1VnRPsMRX9Mig7HYRjMYiuYXTeovM6YS0fg== +"@abp/jquery@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-3.1.2.tgz#f890d872d2d0287e7c195801f8c51c88c64602a0" + integrity sha512-Pk3Ybx/S88rFThDUlziiKIq7uKwiu2J1xYuzJTlP+xc1IgIcJNkBONl07KFdoHvctOtFtdf4mVN7SGYmNePK4g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" jquery "~3.5.1" -"@abp/lodash@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.0-rc.3.tgz#a312975824fa3bebc00f5eca35cededc5ec3af4b" - integrity sha512-siv5cMWlUHEX2RtvKCGoX2cEh4h1hniluKlFgmVmYY4hdGYdAG4T2d9QQAbPODwdzrJ8jzI36hXT/P4IrzhWZw== +"@abp/lodash@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-3.1.2.tgz#07ab3001e463f1c452865ff98e051251322c7061" + integrity sha512-0XMWCKQJyPVpn22OVEYlQR7+zEn1yz4sTb5ilUFhLOSTHXEOJXNVzxEYlGYCPUjxGZFvZH+vdeurSjXdIOOB5w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" lodash "^4.17.15" -"@abp/luxon@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.0-rc.3.tgz#9b9d5c9827a0c661458094134cafd80f35537a69" - integrity sha512-cKj/irXJhTJ6WiSyjzcZcsDjKFji1Q/0nV7IYhY9e2wzpg3qEB8Z8k8fDLPDAUriUKxBoI6mQ/CVC0ah7eg/LA== +"@abp/luxon@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-3.1.2.tgz#ed3adfd1e7e46939c2ac456d44d9987b0d923334" + integrity sha512-fZj3yIT1H+I6vcRxMONw9VRYLWfvzdzLeDZ1xlkXsC4NqI7cK6vchYNTqZlTg4zH6DNYNg6+WOoxQ8ao8a00QA== dependencies: luxon "^1.24.1" -"@abp/malihu-custom-scrollbar-plugin@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.0-rc.3.tgz#218eb620532af8bdde6a46388a3d5349974fab44" - integrity sha512-z3IzgSYtpZ2FlWNmM2A1wbP3CHB3P5a8k/JR0JSWwtl+D/LiYC348VQIXen+pIJoEjMlY48iSi5XNyBIz4X9hw== +"@abp/malihu-custom-scrollbar-plugin@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.2.tgz#3556912136a85289b0b237e5bb7368b08f5efac8" + integrity sha512-b0uU/PwNOQaAurEkEZ4e4103pGomeKduo3Rg0hsyN7eeUrTzNw2tq1AQlgGRxw2v1pzyOvzNd0v14jyERE947g== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/popper.js@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-3.1.0-rc.3.tgz#7b12694e65866edeaa8e8543a23ef238682f34cb" - integrity sha512-QyoRm8y4bjemPGwqTHHO30H5/g+uJ4vsX6eB+lxiqPYBW/2OCTccjWkRwPl1YXKdMMyS2IMARDtYDtrNoQ8Z5g== +"@abp/popper.js@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-3.1.2.tgz#e611547c2981d3d12fa0da119403131fb07495f8" + integrity sha512-OtjNi1B44HUZ9vn5W9LZrrXNmGWLL+Ds96vVJ0GHo7DAi+xAMtalCqlhUyR0NT7uTOrKucE48rZvnJ/SxOiuOw== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" popper.js "^1.16.0" -"@abp/prismjs@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-3.1.0-rc.3.tgz#d13885bf613871f6cd003f58ae01ee4587ad15ad" - integrity sha512-gaKxJ3d78oR1wGZhnPzM5EJIAsibh3VT9MFithFt/YAQdrMMOqS1fEdGsm1zO/A7Veyho9Ba/144RmPkFXH5gQ== +"@abp/prismjs@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-3.1.2.tgz#884011843c44d85a80d4fd85648bc94ef119bbd6" + integrity sha512-UQAOc/FgISgvTi1irPQjehJ42pLEaA1m5K1JileFTCWwUji/t5Vb8RSQe4cjIKPwRpb6p7CEJLI9SFxCtUEF8g== dependencies: - "@abp/clipboard" "~3.1.0-rc.3" - "@abp/core" "~3.1.0-rc.3" + "@abp/clipboard" "~3.1.2" + "@abp/core" "~3.1.2" prismjs "^1.20.0" -"@abp/select2@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.0-rc.3.tgz#493afc27f29da1c9926ee02e8f7b641e8ee4b67e" - integrity sha512-fym9GmQbl34CyTCVzfo4jGe77nSeDuRPYMzAYO8p0uKdDB8t9jNZNqhYJ9Ee5KQXJyg4lmFFPkLcRZF14E+cWw== +"@abp/select2@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-3.1.2.tgz#05997301b2800249ed560c4d24c9bfcfee68f99a" + integrity sha512-PyIiCGkvRUEfSyVF4M7p4BzHgaUG7lysYPop0R1tGiJcEVSxkXvhCJnEODPYiqvVjdFFKVz8Ni1R+xpEIEL/2w== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" select2 "^4.0.13" -"@abp/sweetalert@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.0-rc.3.tgz#1c1421e2baaa57cc24e0f9334a5173836819cc24" - integrity sha512-WrYRutXM2f6VRECEkWhjfqtQXlnEw88MCkYicAhyMH7ZYYWg7r9xVg9TRJJI4UwGMLSyR3EB+ZdTmnD8aSC0yQ== +"@abp/sweetalert@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/sweetalert/-/sweetalert-3.1.2.tgz#18b062b0d5c5d5c78b4f8d13186587ab87d46464" + integrity sha512-MJXLyrqPgxiy5NViyVvo6iasDoO3Jfdb3+4Jf+5PFlR7pZd1MmhmvNWn/rc5yFcCwOKvJkXVaWYaT9UsvZPxIA== dependencies: - "@abp/core" "~3.1.0-rc.3" + "@abp/core" "~3.1.2" sweetalert "^2.1.2" -"@abp/timeago@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.0-rc.3.tgz#0a7a369ba29633f00b19206b257c6f1f59f182a4" - integrity sha512-FDgaQCJmwWplCcdJYa9kyCcMxJFrKf+zDEFzT5hWfhMzq+sYJYX7QDQtbF5OJnMSWuPyI0/RU0bocuGaJ584VQ== +"@abp/timeago@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-3.1.2.tgz#120cdd99a9dde1fbd1276571fdc5f415eee2941e" + integrity sha512-C3d1RLMEUBctPA/ASpqt9+gumsziYu0De7PWdmCmkPC7q23JpZaOmvWffaTpP2QoInyQXUPo51obOmEaC23InQ== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" timeago "^1.6.7" -"@abp/toastr@~3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.0-rc.3.tgz#89af6aa864a9aac76bc9bf21b7f9bc6763ca7573" - integrity sha512-AeKH5imy8W9yMAlzRv9VdkRHApySpR2BKfrQYk3q9LubgwaxLvOFc/l38aIEKuyosN7dHTMFBQlEwLxWFwaoPA== +"@abp/toastr@~3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-3.1.2.tgz#3f8838423559482b8791cd7ce5bb6ff3a8f3722a" + integrity sha512-Omb/7Mkv73hRunVfWbRJxlNoTC3cqKJACB+pAcB5rb+rCTiR3c9HaSf1C7ljlofpxY/AKMN+JfJZP9VmgH2e4g== dependencies: - "@abp/jquery" "~3.1.0-rc.3" + "@abp/jquery" "~3.1.2" toastr "^2.1.4" -"@abp/utils@^3.1.0-rc.3": - version "3.1.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.0-rc.3.tgz#3cbc50c1f8fdf6592d66f8ea4b5a9c4249a5e46a" - integrity sha512-45KXx5zlxm5gK2EFwzM+hMjT8q8pD3PejyNfVP6HBbGE2N36LGKYtI59s6vFm5yV2qFxQyVPrk4mi3Y+neqlBw== +"@abp/utils@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-3.1.2.tgz#e9bca8f6133dc2af587c45825e734d2accabcd96" + integrity sha512-wnbHGQDGkQYazez1YSXAZ0ZDbsIZZr2ZN8V4LtOSAfzmYhPhFZ5qftoM0xoxlbmsuLLX6QtiPvxU35kEmlZPyg== dependencies: just-compare "^1.3.0" diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index bd76814461..afbb5fcf5b 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -295,7 +295,7 @@
- @if (Model.DocumentLanguageIsDifferent) + @if (Model.DocumentLanguageCode != Model.LanguageCode) { @L["DocumentNotFoundInSelectedLanguage"] diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 4568e574a5..777875660a 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -64,7 +64,7 @@ namespace Volo.Docs.Pages.Documents.Project public bool ShowProjectsCombobox { get; set; } - public bool DocumentLanguageIsDifferent { get; set; } + public string DocumentLanguageCode { get; set; } public DocumentParametersDto DocumentPreferences { get; set; } @@ -393,7 +393,7 @@ namespace Volo.Docs.Pages.Documents.Project return RemoveVersionPrefix(Document.Version) == LatestVersionInfo.Version ? DocsAppConsts.Latest : - Document.Version; + RemoveVersionPrefix(Document.Version); } private async Task SetDocumentAsync() @@ -403,6 +403,7 @@ namespace Volo.Docs.Pages.Documents.Project try { Document = await GetSpecificDocumentOrDefaultAsync(LanguageCode); + DocumentLanguageCode = LanguageCode; } catch (DocumentNotFoundException) { @@ -410,7 +411,7 @@ namespace Volo.Docs.Pages.Documents.Project { Document = await GetSpecificDocumentOrDefaultAsync(DefaultLanguageCode); - DocumentLanguageIsDifferent = true; + DocumentLanguageCode = DefaultLanguageCode; } else { @@ -500,7 +501,7 @@ namespace Volo.Docs.Pages.Documents.Project { var content = (await _documentAppService.GetAsync(new GetDocumentInput { - LanguageCode = LanguageCode, + LanguageCode = DocumentLanguageCode, Name = partialTemplate.Path, ProjectId = Project.Id, Version = Version @@ -518,7 +519,7 @@ namespace Volo.Docs.Pages.Documents.Project private void SetUserPreferences() { - UserPreferences.Add("Document_Language_Code", LanguageCode); + UserPreferences.Add("Document_Language_Code", DocumentLanguageCode); UserPreferences.Add("Document_Version", Version); var cookie = Request.Cookies["AbpDocsPreferences"]; @@ -608,7 +609,7 @@ namespace Volo.Docs.Pages.Documents.Project new GetParametersDocumentInput { ProjectId = Project.Id, - LanguageCode = LanguageCode, + LanguageCode = DocumentLanguageCode, Version = Version }); diff --git a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs index b31f9b5acd..d00f25b533 100644 --- a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs +++ b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Docs.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Docs.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/modules/feature-management/Volo.Abp.FeatureManagement.sln b/modules/feature-management/Volo.Abp.FeatureManagement.sln index 34f0c84aa5..7f1c6ae1e0 100644 --- a/modules/feature-management/Volo.Abp.FeatureManagement.sln +++ b/modules/feature-management/Volo.Abp.FeatureManagement.sln @@ -35,6 +35,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.FeatureManagement. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.FeatureManagement.Application.Tests", "test\Volo.Abp.FeatureManagement.Application.Tests\Volo.Abp.FeatureManagement.Application.Tests.csproj", "{13A9EAD6-F3A4-4357-BA4A-A7E8FEB4A264}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.FeatureManagement.Blazor", "src\Volo.Abp.FeatureManagement.Blazor\Volo.Abp.FeatureManagement.Blazor.csproj", "{0F34FFD5-E98F-4F77-AE0B-A790BD5810D5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,6 +99,10 @@ Global {13A9EAD6-F3A4-4357-BA4A-A7E8FEB4A264}.Debug|Any CPU.Build.0 = Debug|Any CPU {13A9EAD6-F3A4-4357-BA4A-A7E8FEB4A264}.Release|Any CPU.ActiveCfg = Release|Any CPU {13A9EAD6-F3A4-4357-BA4A-A7E8FEB4A264}.Release|Any CPU.Build.0 = Release|Any CPU + {0F34FFD5-E98F-4F77-AE0B-A790BD5810D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F34FFD5-E98F-4F77-AE0B-A790BD5810D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F34FFD5-E98F-4F77-AE0B-A790BD5810D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F34FFD5-E98F-4F77-AE0B-A790BD5810D5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -116,6 +122,7 @@ Global {E5906DE1-B2F5-472E-BE1B-1D96A68B834D} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} {AA783A34-86E4-41A5-AE21-5D9FBD98D858} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} {13A9EAD6-F3A4-4357-BA4A-A7E8FEB4A264} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {0F34FFD5-E98F-4F77-AE0B-A790BD5810D5} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureGroupDto.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureGroupDto.cs new file mode 100644 index 0000000000..dea10fd298 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureGroupDto.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace Volo.Abp.FeatureManagement +{ + public class FeatureGroupDto + { + public string Name { get; set; } + + public string DisplayName { get; set; } + + public List Features { get; set; } + + public string GetNormalizedGroupName() + { + return Name.Replace(".", "_"); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureListDto.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureListDto.cs deleted file mode 100644 index ee7bad8d5c..0000000000 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureListDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace Volo.Abp.FeatureManagement -{ - public class FeatureListDto - { - public List Features { get; set; } - } -} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementPermissions.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementPermissions.cs new file mode 100644 index 0000000000..86772c0a7b --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementPermissions.cs @@ -0,0 +1,16 @@ +using Volo.Abp.Reflection; + +namespace Volo.Abp.FeatureManagement +{ + public class FeatureManagementPermissions + { + public const string GroupName = "FeatureManagement"; + + public const string ManageHostFeatures = GroupName + ".ManageHostFeatures"; + + public static string[] GetAll() + { + return ReflectionHelper.GetPublicConstantsRecursively(typeof(FeatureManagementPermissions)); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeaturePermissionDefinitionProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeaturePermissionDefinitionProvider.cs new file mode 100644 index 0000000000..27e159ee8a --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeaturePermissionDefinitionProvider.cs @@ -0,0 +1,28 @@ +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.FeatureManagement.Localization; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.FeatureManagement +{ + public class FeaturePermissionDefinitionProvider : PermissionDefinitionProvider + { + public override void Define(IPermissionDefinitionContext context) + { + var featureManagementGroup = context.AddGroup( + FeatureManagementPermissions.GroupName, + L("Permission:FeatureManagement"), + multiTenancySide: MultiTenancySides.Host); + + featureManagementGroup.AddPermission( + FeatureManagementPermissions.ManageHostFeatures, + L("Permission:FeatureManagement.ManageHostFeatures"), + multiTenancySide: MultiTenancySides.Host); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/GetFeatureListResultDto.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/GetFeatureListResultDto.cs new file mode 100644 index 0000000000..86329598cc --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/GetFeatureListResultDto.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Volo.Abp.FeatureManagement +{ + public class GetFeatureListResultDto + { + public List Groups { get; set; } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs index 2c337f1b2a..9ddddc7401 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs @@ -6,8 +6,8 @@ namespace Volo.Abp.FeatureManagement { public interface IFeatureAppService : IApplicationService { - Task GetAsync([NotNull] string providerName, [NotNull] string providerKey); + Task GetAsync([NotNull] string providerName, string providerKey); - Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdateFeaturesDto input); + Task UpdateAsync([NotNull] string providerName, string providerKey, UpdateFeaturesDto input); } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs index f0c310650d..bfb6e65ea8 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Options; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Features; namespace Volo.Abp.FeatureManagement @@ -24,40 +26,62 @@ namespace Volo.Abp.FeatureManagement Options = options.Value; } - public virtual async Task GetAsync([NotNull] string providerName, [NotNull] string providerKey) + public virtual async Task GetAsync([NotNull] string providerName, string providerKey) { - await CheckProviderPolicy(providerName); + await CheckProviderPolicy(providerName, providerKey); - var featureDefinitions = FeatureDefinitionManager.GetAll(); - var features = new List(); + var result = new GetFeatureListResultDto + { + Groups = new List() + }; - foreach (var featureDefinition in featureDefinitions) + foreach (var group in FeatureDefinitionManager.GetGroups()) { - var feature = await FeatureManager.GetOrNullWithProviderAsync(featureDefinition.Name, providerName, providerKey); - features.Add(new FeatureDto + var groupDto = new FeatureGroupDto + { + Name = group.Name, + DisplayName = group.DisplayName.Localize(StringLocalizerFactory), + Features = new List() + }; + + foreach (var featureDefinition in group.GetFeaturesWithChildren()) { - Name = featureDefinition.Name, - DisplayName = featureDefinition.DisplayName?.Localize(StringLocalizerFactory), - ValueType = featureDefinition.ValueType, - Description = featureDefinition.Description?.Localize(StringLocalizerFactory), - ParentName = featureDefinition.Parent?.Name, - Value = feature.Value, - Provider = new FeatureProviderDto + if (providerName == TenantFeatureValueProvider.ProviderName && + CurrentTenant.Id == null && + providerKey == null && + !featureDefinition.IsAvailableToHost) { - Name = feature.Provider?.Name, - Key = feature.Provider?.Key + continue; } - }); - } - SetFeatureDepth(features, providerName, providerKey); + var feature = await FeatureManager.GetOrNullWithProviderAsync(featureDefinition.Name, providerName, providerKey); + groupDto.Features.Add(new FeatureDto + { + Name = featureDefinition.Name, + DisplayName = featureDefinition.DisplayName?.Localize(StringLocalizerFactory), + ValueType = featureDefinition.ValueType, + Description = featureDefinition.Description?.Localize(StringLocalizerFactory), + ParentName = featureDefinition.Parent?.Name, + Value = feature.Value, + Provider = new FeatureProviderDto + { + Name = feature.Provider?.Name, + Key = feature.Provider?.Key + } + }); + } + + SetFeatureDepth(groupDto.Features, providerName, providerKey); - return new FeatureListDto { Features = features }; + result.Groups.Add(groupDto); + } + + return result; } - public virtual async Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdateFeaturesDto input) + public virtual async Task UpdateAsync([NotNull] string providerName, string providerKey, UpdateFeaturesDto input) { - await CheckProviderPolicy(providerName); + await CheckProviderPolicy(providerName, providerKey); foreach (var feature in input.Features) { @@ -78,12 +102,20 @@ namespace Volo.Abp.FeatureManagement } } - protected virtual async Task CheckProviderPolicy(string providerName) + protected virtual async Task CheckProviderPolicy(string providerName, string providerKey) { - var policyName = Options.ProviderPolicies.GetOrDefault(providerName); - if (policyName.IsNullOrEmpty()) + string policyName; + if (providerName == TenantFeatureValueProvider.ProviderName && CurrentTenant.Id == null && providerKey == null ) + { + policyName = "FeatureManagement.ManageHostFeatures"; + } + else { - throw new AbpException($"No policy defined to get/set permissions for the provider '{policyName}'. Use {nameof(FeatureManagementOptions)} to map the policy."); + policyName = Options.ProviderPolicies.GetOrDefault(providerName); + if (policyName.IsNullOrEmpty()) + { + throw new AbpException($"No policy defined to get/set permissions for the provider '{policyName}'. Use {nameof(FeatureManagementOptions)} to map the policy."); + } } await AuthorizationService.CheckAsync(policyName); diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/AbpFeatureManagementBlazorModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/AbpFeatureManagementBlazorModule.cs new file mode 100644 index 0000000000..497d7553da --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/AbpFeatureManagementBlazorModule.cs @@ -0,0 +1,16 @@ +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace Volo.Abp.FeatureManagement.Blazor +{ + [DependsOn( + typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule), + typeof(AbpAutoMapperModule), + typeof(AbpFeatureManagementHttpApiClientModule) + )] + public class AbpFeatureManagementBlazorModule : AbpModule + { + + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor new file mode 100644 index 0000000000..f59eea6d57 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor @@ -0,0 +1,85 @@ +@using Microsoft.Extensions.Localization +@using Volo.Abp.FeatureManagement.Localization +@using Volo.Abp.Validation.StringValues +@inject IStringLocalizer L + + + + + + @L["Features"] + + + + @if (_groups == null) + { + @L["NoFeatureFoundMessage"] + } + else + { + + + @foreach (var group in _groups) + { + + @group.DisplayName + + } + + + @foreach (var group in _groups) + { + +

@group.DisplayName

+ + @foreach (var feature in group.Features) + { + var disabled = IsDisabled(feature.Provider.Name); + + if (feature.ValueType is FreeTextStringValueType) + { + + @feature.DisplayName + + @if (feature.Description != null) + { + @feature.Description + } + + } + + if (feature.ValueType is SelectionStringValueType) + { + var items = ((SelectionStringValueType) feature.ValueType).ItemSource.Items; + + + @feature.DisplayName + + + } + + if (feature.ValueType is ToggleStringValueType) + { + + @feature.DisplayName + + } + } + +
+ } +
+
+ } +
+ + + + +
+
\ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor.cs new file mode 100644 index 0000000000..40aba610eb --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Blazorise; +using Microsoft.AspNetCore.Components; +using Volo.Abp.Features; +using Volo.Abp.Validation.StringValues; + +namespace Volo.Abp.FeatureManagement.Blazor.Components +{ + public partial class FeatureManagementModal + { + [Inject] private IFeatureAppService FeatureAppService { get; set; } + + private Modal _modal; + + private string _providerName; + private string _providerKey; + + private List _groups { get; set; } + + private Dictionary ToggleValues; + + public async Task OpenAsync(string providerName, string providerKey) + { + _providerName = providerName; + _providerKey = providerKey; + + _groups = (await FeatureAppService.GetAsync(_providerName, _providerKey)).Groups; + + ToggleValues = _groups + .SelectMany(x => x.Features) + .Where(x => x.ValueType is ToggleStringValueType) + .ToDictionary(x => x.Name, x => bool.Parse(x.Value)); + + _modal.Show(); + } + + private void CloseModal() + { + _modal.Hide(); + } + + private async Task SaveAsync() + { + var features = new UpdateFeaturesDto + { + Features = _groups.SelectMany(g => g.Features).Select(f => new UpdateFeatureDto + { + Name = f.Name, + Value = f.ValueType is ToggleStringValueType ? ToggleValues[f.Name].ToString() : f.Value + }).ToList() + }; + + await FeatureAppService.UpdateAsync(_providerName, _providerKey, features); + + _modal.Hide(); + } + + public string GetNormalizedGroupName(string name) + { + return "FeatureGroup_" + name.Replace(".", "_"); + } + + public virtual bool IsDisabled(string providerName) + { + return providerName != _providerName && providerName != DefaultValueFeatureValueProvider.ProviderName; + } + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/FodyWeavers.xml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/FodyWeavers.xsd b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Volo.Abp.FeatureManagement.Blazor.csproj b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Volo.Abp.FeatureManagement.Blazor.csproj new file mode 100644 index 0000000000..8769a86e79 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Volo.Abp.FeatureManagement.Blazor.csproj @@ -0,0 +1,29 @@ + + + + + + + netstandard2.1 + 3.0 + + + + + + + + + + + + + + true + + + true + + + + diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/_Imports.razor b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/_Imports.razor new file mode 100644 index 0000000000..b52766daad --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/_Imports.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 \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs index 0c9a2e0f26..04edbfbbc2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs @@ -1,5 +1,6 @@ using Volo.Abp.FeatureManagement.Localization; using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; using Volo.Abp.Validation; using Volo.Abp.Validation.Localization; @@ -27,6 +28,11 @@ namespace Volo.Abp.FeatureManagement typeof(AbpValidationResource) ).AddVirtualJson("Volo/Abp/FeatureManagement/Localization/Domain"); }); + + Configure(options => + { + options.MapCodeNamespace("Volo.Abp.FeatureManagement", typeof(AbpFeatureManagementResource)); + }); } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs index 010c64efbb..9bcfd3290e 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs @@ -1,7 +1,9 @@ -namespace Volo.Abp.FeatureManagement +using System; + +namespace Volo.Abp.FeatureManagement { public static class FeatureManagementDomainErrorCodes { - + public const string FeatureValueInvalid = "Volo.Abp.FeatureManagement:InvalidFeatureValue"; } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs new file mode 100644 index 0000000000..d003295239 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Volo.Abp.FeatureManagement +{ + [Serializable] + public class FeatureValueInvalidException : BusinessException + { + public FeatureValueInvalidException(string name) : + base(FeatureManagementDomainErrorCodes.FeatureValueInvalid) + { + WithData("0", name); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json index fcc347b9e3..cc5fae2dff 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json @@ -2,6 +2,7 @@ "culture": "ar", "texts": { "Features": "المميزات", - "NoFeatureFoundMessage": "لا توجد أي ميزة متاحة." + "NoFeatureFoundMessage": "لا توجد أي ميزة متاحة.", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0} قيمة الميزة غير صالحة!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json index 12a4e1aef0..c6d4bb1d07 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json @@ -2,6 +2,7 @@ "culture": "de", "texts": { "Features": "Funktionen", - "NoFeatureFoundMessage": "Es ist keine Funktion verfügbar." + "NoFeatureFoundMessage": "Es ist keine Funktion verfügbar.", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "Der {0} -Feature-Wert ist ungültig!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json index e5a2406aaf..c5194de6c7 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json @@ -2,6 +2,9 @@ "culture": "en", "texts": { "Features": "Features", - "NoFeatureFoundMessage": "There isn't any available feature." + "NoFeatureFoundMessage": "There isn't any available feature.", + "Permission:FeatureManagement": "Feature management", + "Permission:FeatureManagement.ManageHostFeatures": "Manage Host features", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0} feature value is not valid!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json index 3945762269..d232c20060 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json @@ -2,6 +2,7 @@ "culture": "ru", "texts": { "Features": "Функциональные возможности", - "NoFeatureFoundMessage": "Нет доступных функциональных возможностей." + "NoFeatureFoundMessage": "Нет доступных функциональных возможностей.", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "Недопустимое значение функции {0}!" } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json index b566f654ca..b69674a620 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json @@ -2,6 +2,9 @@ "culture": "tr", "texts": { "Features": "Özellikler", - "NoFeatureFoundMessage": "Hiç özellik yok." + "NoFeatureFoundMessage": "Hiç özellik yok.", + "Permission:FeatureManagement": "Özellik yönetimi", + "Permission:FeatureManagement.ManageHostFeatures": "Host özelliklerini düzenle", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0} özellik değeri geçerli değil!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json index 69b8ca89b1..473f581b34 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json @@ -2,6 +2,9 @@ "culture": "zh-Hans", "texts": { "Features": "功能", - "NoFeatureFoundMessage": "没有可用的功能." + "NoFeatureFoundMessage": "没有可用的功能.", + "Permission:FeatureManagement": "特性管理", + "Permission:FeatureManagement.ManageHostFeatures": "管理Host特性", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0}功能的值无效!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json index bc4dbf268f..dc84e7c104 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json @@ -2,6 +2,9 @@ "culture": "zh-Hant", "texts": { "Features": "功能", - "NoFeatureFoundMessage": "沒有可用的功能." + "NoFeatureFoundMessage": "沒有可用的功能.", + "Permission:FeatureManagement": "功能管理", + "Permission:FeatureManagement.ManageHostFeatures": "管理Host功能", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0}功能的值無效!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs index e8e961d3b4..38a2fa3c56 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs @@ -1,10 +1,8 @@ using Volo.Abp.Caching; using Volo.Abp.FeatureManagement.Localization; using Volo.Abp.Features; -using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; -using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.FeatureManagement { diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs index 454ade5476..38c61cc743 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; @@ -14,15 +15,18 @@ namespace Volo.Abp.FeatureManagement protected IFeatureDefinitionManager FeatureDefinitionManager { get; } protected List Providers => _lazyProviders.Value; protected FeatureManagementOptions Options { get; } + protected IStringLocalizerFactory StringLocalizerFactory { get; } private readonly Lazy> _lazyProviders; public FeatureManager( IOptions options, IServiceProvider serviceProvider, - IFeatureDefinitionManager featureDefinitionManager) + IFeatureDefinitionManager featureDefinitionManager, + IStringLocalizerFactory stringLocalizerFactory) { FeatureDefinitionManager = featureDefinitionManager; + StringLocalizerFactory = stringLocalizerFactory; Options = options.Value; //TODO: Instead, use IHybridServiceScopeFactory and create a scope..? @@ -57,7 +61,8 @@ namespace Volo.Abp.FeatureManagement .Select(x => new FeatureNameValue(x.Name, x.Value)).ToList(); } - public async Task GetOrNullWithProviderAsync(string name, string providerName, string providerKey, bool fallback = true) + public async Task GetOrNullWithProviderAsync(string name, + string providerName, string providerKey, bool fallback = true) { Check.NotNull(name, nameof(name)); Check.NotNull(providerName, nameof(providerName)); @@ -65,7 +70,8 @@ namespace Volo.Abp.FeatureManagement return await GetOrNullInternalAsync(name, providerName, providerKey, fallback); } - public async Task> GetAllWithProviderAsync(string providerName, string providerKey, bool fallback = true) + public async Task> GetAllWithProviderAsync(string providerName, + string providerKey, bool fallback = true) { Check.NotNull(providerName, nameof(providerName)); @@ -128,6 +134,11 @@ namespace Volo.Abp.FeatureManagement var feature = FeatureDefinitionManager.Get(name); + if (!feature.ValueType.Validator.IsValid(value)) + { + throw new FeatureValueInvalidException(feature.DisplayName.Localize(StringLocalizerFactory)); + } + var providers = Enumerable .Reverse(Providers) .SkipWhile(p => p.Name != providerName) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs index 0ae78ed03f..c7dff4d8a3 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.FeatureManagement } [HttpGet] - public virtual Task GetAsync(string providerName, string providerKey) + public virtual Task GetAsync(string providerName, string providerKey) { return FeatureAppService.GetAsync(providerName, providerKey); } @@ -28,4 +28,4 @@ namespace Volo.Abp.FeatureManagement return FeatureAppService.UpdateAsync(providerName, providerKey, input); } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml index f5adbf79d4..a5592c2f28 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml @@ -1,65 +1,113 @@ -@page +@page @using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.Extensions.Options @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.FeatureManagement.Localization @using Volo.Abp.Validation.StringValues @using Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement -@using Volo.Abp.Features +@using Volo.Abp.Localization @model FeatureManagementModal @inject IHtmlLocalizer L +@inject IHtmlLocalizerFactory HtmlLocalizerFactory +@inject IOptions LocalizationOptions @{ Layout = null; + + IHtmlLocalizer CreateHtmlLocalizer(string resourceName) + { + var resource = LocalizationOptions.Value.Resources.Values.FirstOrDefault(x => x.ResourceName == resourceName); + return HtmlLocalizerFactory.Create(resource != null ? resource.ResourceType : LocalizationOptions.Value.DefaultResourceType); + } }
- @if (Model.FeatureListDto?.Features != null && Model.FeatureListDto.Features.Any()) + @if (Model.FeatureListResultDto != null && Model.FeatureListResultDto.Groups.Any()) { + var featureGroups = Model.FeatureListResultDto.Groups; + - - - @for (var i = 0; i < Model.FeatureListDto.Features.Count; i++) - { - var feature = Model.FeatureListDto.Features[i]; - var disabled = Model.IsDisabled(feature.Provider.Name); -
+ + + + @for (var i = 0; i < featureGroups.Count; i++) + { + +

@featureGroups[i].DisplayName

+
+
+
+ @for (var j = 0; j < featureGroups[i].Features.Count; j++) + { + var feature = featureGroups[i].Features[j]; + var disabled = Model.IsDisabled(feature.Provider.Name); +
- @feature.DisplayName @(disabled ? $"({feature.Provider.Name})" : "") + + - - - @if (feature.ValueType is FreeTextStringValueType) - { - - - } - @if (feature.ValueType is SelectionStringValueType) - { - - + @foreach (var item in selectType.ItemSource.Items) + { + if (item.Value == feature.Value) + { + + } + else + { + + } + } + +
+ } + + +
} - } - - } - @if (feature.ValueType is ToggleStringValueType) - { - - - } -
- } +
+
+ + } + + - + } else { @@ -69,4 +117,3 @@ } - diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs index e46d686e69..367268019c 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs @@ -16,15 +16,14 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement [BindProperty(SupportsGet = true)] public string ProviderName { get; set; } - [Required] [HiddenInput] [BindProperty(SupportsGet = true)] public string ProviderKey { get; set; } [BindProperty] - public List Features { get; set; } + public List FeatureGroups { get; set; } - public FeatureListDto FeatureListDto { get; set; } + public GetFeatureListResultDto FeatureListResultDto { get; set; } protected IFeatureAppService FeatureAppService { get; } @@ -35,16 +34,20 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement FeatureAppService = featureAppService; } - public virtual async Task OnGetAsync() + public virtual async Task OnGetAsync() { - FeatureListDto = await FeatureAppService.GetAsync(ProviderName, ProviderKey); + ValidateModel(); + + FeatureListResultDto = await FeatureAppService.GetAsync(ProviderName, ProviderKey); + + return Page(); } public virtual async Task OnPostAsync() { var features = new UpdateFeaturesDto { - Features = Features.Select(f => new UpdateFeatureDto + Features = FeatureGroups.SelectMany(g => g.Features).Select(f => new UpdateFeatureDto { Name = f.Name, Value = f.Type == nameof(ToggleStringValueType) ? f.BoolValue.ToString() : f.Value @@ -68,14 +71,17 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement public string ProviderKey { get; set; } } + public class FeatureGroupViewModel + { + public List Features { get; set; } + } + public class FeatureViewModel { public string Name { get; set; } public string Value { get; set; } - public string ProviderName { get; set; } - public bool BoolValue { get; set; } public string Type { get; set; } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js index 7e4960999c..f9ec7e11fa 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js @@ -3,12 +3,75 @@ abp.modals = abp.modals || {}; abp.modals.FeatureManagement = function () { - $('.FeatureValueCheckbox').change(function () { - if (this.checked) { - $(this).val('true'); - } else { - $(this).val('false'); + function checkParents($tab, $element, className) { + var parentName = $element + .closest(className) + .attr('data-parent-name'); + + if (!parentName) { + return; + } + + $tab.find('.custom-checkbox') + .filter('[data-feature-name="' + parentName + '"]') + .find('input[type="checkbox"]') + .each(function () { + var $parent = $(this); + $parent.prop('checked', true); + checkParents($tab, $parent, className); + }); + } + + function uncheckChildren($tab, $checkBox) { + var featureName = $checkBox + .closest('.custom-checkbox') + .attr('data-feature-name'); + if (!featureName) { + return; } - }); + + $tab.find('.custom-checkbox') + .filter('[data-parent-name="' + featureName + '"]') + .find('input[type="checkbox"]') + .each(function () { + var $child = $(this); + $child.prop('checked', false); + uncheckChildren($tab, $child); + }); + } + + this.initDom = function ($el) { + $el.find('.tab-pane').each(function () { + var $tab = $(this); + $tab.find('input[type="checkbox"]') + .each(function () { + var $checkBox = $(this); + $checkBox.change(function () { + if ($checkBox.is(':checked')) { + checkParents($tab, $checkBox, '.custom-checkbox') + } else { + uncheckChildren($tab, $checkBox); + } + }); + }); + + $tab.find('.form-control') + .each(function () { + var $element = $(this); + $element.change(function () { + checkParents($tab, $element, '.form-group') + }); + }); + }); + + $(function () { + $('.custom-scroll-content').mCustomScrollbar({ + theme: 'minimal-dark', + }); + $('.custom-scroll-container > .col-4').mCustomScrollbar({ + theme: 'minimal-dark', + }); + }); + }; }; })(jQuery); diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs index b257f873cd..2f904a46d2 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs @@ -41,7 +41,7 @@ namespace Volo.Abp.FeatureManagement TestEditionIds.Regular.ToString()); featureList.ShouldNotBeNull(); - featureList.Features.ShouldContain(feature => feature.Name == TestFeatureDefinitionProvider.SocialLogins); + featureList.Groups.SelectMany(g =>g .Features).ShouldContain(feature => feature.Name == TestFeatureDefinitionProvider.SocialLogins); } [Fact] @@ -63,7 +63,7 @@ namespace Volo.Abp.FeatureManagement }); (await _featureAppService.GetAsync(EditionFeatureValueProvider.ProviderName, - TestEditionIds.Regular.ToString())).Features.Any(x => + TestEditionIds.Regular.ToString())).Groups.SelectMany(g => g.Features).Any(x => x.Name == TestFeatureDefinitionProvider.SocialLogins && x.Value == false.ToString().ToLowerInvariant()) .ShouldBeTrue(); diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs index 528e0de5e8..1b7553b773 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs @@ -20,38 +20,46 @@ namespace Volo.Abp.FeatureManagement [Fact] public void Should_Serialize_And_Deserialize() { - var featureListDto = new FeatureListDto + var featureListDto = new GetFeatureListResultDto { - Features = new List + Groups = new List { - new FeatureDto + new FeatureGroupDto { - ValueType = new FreeTextStringValueType + Name = "MyGroup", + DisplayName = "MyGroup", + Features = new List { - Validator = new BooleanValueValidator() - } - }, - new FeatureDto - { - ValueType = new SelectionStringValueType - { - ItemSource = new StaticSelectionStringValueItemSource( - new LocalizableSelectionStringValueItem + new FeatureDto + { + ValueType = new FreeTextStringValueType { - Value = "TestValue", - DisplayText = new LocalizableStringInfo("TestResourceName", "TestName") - }), - Validator = new AlwaysValidValueValidator() - } - }, - new FeatureDto - { - ValueType = new ToggleStringValueType - { - Validator = new NumericValueValidator + Validator = new BooleanValueValidator() + } + }, + new FeatureDto { - MaxValue = 1000, - MinValue = 10 + ValueType = new SelectionStringValueType + { + ItemSource = new StaticSelectionStringValueItemSource( + new LocalizableSelectionStringValueItem + { + Value = "TestValue", + DisplayText = new LocalizableStringInfo("TestResourceName", "TestName") + }), + Validator = new AlwaysValidValueValidator() + } + }, + new FeatureDto + { + ValueType = new ToggleStringValueType + { + Validator = new NumericValueValidator + { + MaxValue = 1000, + MinValue = 10 + } + } } } } @@ -59,22 +67,22 @@ namespace Volo.Abp.FeatureManagement }; var serialized = _jsonSerializer.Serialize(featureListDto, indented: true); - var featureListDto2 = _jsonSerializer.Deserialize(serialized); + var featureListDto2 = _jsonSerializer.Deserialize(serialized); - featureListDto2.Features[0].ValueType.ShouldBeOfType(); - featureListDto2.Features[0].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Groups[0].Features[0].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[0].ValueType.Validator.ShouldBeOfType(); - featureListDto2.Features[1].ValueType.ShouldBeOfType(); - featureListDto2.Features[1].ValueType.Validator.ShouldBeOfType(); - featureListDto2.Features[1].ValueType.As().ItemSource.Items.ShouldBeOfType(); - featureListDto2.Features[1].ValueType.As().ItemSource.Items.ShouldContain(x => + featureListDto2.Groups[0].Features[1].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[1].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Groups[0].Features[1].ValueType.As().ItemSource.Items.ShouldBeOfType(); + featureListDto2.Groups[0].Features[1].ValueType.As().ItemSource.Items.ShouldContain(x => x.Value == "TestValue" && x.DisplayText.ResourceName == "TestResourceName" && x.DisplayText.Name == "TestName"); - featureListDto2.Features[2].ValueType.ShouldBeOfType(); - featureListDto2.Features[2].ValueType.Validator.ShouldBeOfType(); - featureListDto2.Features[2].ValueType.Validator.As().MaxValue.ShouldBe(1000); - featureListDto2.Features[2].ValueType.Validator.As().MinValue.ShouldBe(10); + featureListDto2.Groups[0].Features[2].ValueType.ShouldBeOfType(); + featureListDto2.Groups[0].Features[2].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Groups[0].Features[2].ValueType.Validator.As().MaxValue.ShouldBe(1000); + featureListDto2.Groups[0].Features[2].ValueType.Validator.As().MinValue.ShouldBe(10); } } } diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs index 04d4ac916f..fdafebef51 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.FeatureManagement.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Abp.FeatureManagement.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } -} \ No newline at end of file +} diff --git a/modules/identity/.gitignore b/modules/identity/.gitignore new file mode 100644 index 0000000000..dcd876a3c7 --- /dev/null +++ b/modules/identity/.gitignore @@ -0,0 +1,4 @@ +src/Volo.Abp.Identity.HttpApi/Properties/launchSettings.json +src/Volo.Abp.Identity.Web/Properties/launchSettings.json +test/Volo.Abp.Identity.AspNetCore.Tests/Properties/launchSettings.json +src/Volo.Abp.Identity.AspNetCore/Properties/launchSettings.json diff --git a/modules/identity/Volo.Abp.Identity.sln b/modules/identity/Volo.Abp.Identity.sln index 388cd0c555..23336bdc02 100644 --- a/modules/identity/Volo.Abp.Identity.sln +++ b/modules/identity/Volo.Abp.Identity.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27428.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30413.136 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AADC5A0A-F100-4511-87DE-B74E55F5B69B}" EndProject @@ -37,9 +37,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Domain.Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.AspNetCore", "src\Volo.Abp.Identity.AspNetCore\Volo.Abp.Identity.AspNetCore.csproj", "{D5EFC912-75A0-4856-9B8D-DFDD4CD66BAB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.PermissionManagement.Domain.Identity", "src\Volo.Abp.PermissionManagement.Domain.Identity\Volo.Abp.PermissionManagement.Domain.Identity.csproj", "{736F91E7-8A70-441B-89DE-0E29A348E718}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.PermissionManagement.Domain.Identity", "src\Volo.Abp.PermissionManagement.Domain.Identity\Volo.Abp.PermissionManagement.Domain.Identity.csproj", "{736F91E7-8A70-441B-89DE-0E29A348E718}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Identity.AspNetCore.Tests", "test\Volo.Abp.Identity.AspNetCore.Tests\Volo.Abp.Identity.AspNetCore.Tests.csproj", "{89C094EB-D80A-4976-9C10-7CE3EBEEE877}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.AspNetCore.Tests", "test\Volo.Abp.Identity.AspNetCore.Tests\Volo.Abp.Identity.AspNetCore.Tests.csproj", "{89C094EB-D80A-4976-9C10-7CE3EBEEE877}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Identity.Blazor", "src\Volo.Abp.Identity.Blazor\Volo.Abp.Identity.Blazor.csproj", "{3F7BB653-3F3A-4889-B73C-E463F239099A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -115,6 +117,10 @@ Global {89C094EB-D80A-4976-9C10-7CE3EBEEE877}.Debug|Any CPU.Build.0 = Debug|Any CPU {89C094EB-D80A-4976-9C10-7CE3EBEEE877}.Release|Any CPU.ActiveCfg = Release|Any CPU {89C094EB-D80A-4976-9C10-7CE3EBEEE877}.Release|Any CPU.Build.0 = Release|Any CPU + {3F7BB653-3F3A-4889-B73C-E463F239099A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F7BB653-3F3A-4889-B73C-E463F239099A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F7BB653-3F3A-4889-B73C-E463F239099A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F7BB653-3F3A-4889-B73C-E463F239099A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -137,6 +143,7 @@ Global {D5EFC912-75A0-4856-9B8D-DFDD4CD66BAB} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} {736F91E7-8A70-441B-89DE-0E29A348E718} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} {89C094EB-D80A-4976-9C10-7CE3EBEEE877} = {9FACAF96-A681-4B36-A938-A37DCA0B7EC1} + {3F7BB653-3F3A-4889-B73C-E463F239099A} = {AADC5A0A-F100-4511-87DE-B74E55F5B69B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {05740D37-83CF-4041-9C2A-D89F1B3DB5A4} diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs index 36f483d0e6..24969c1ed5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs @@ -5,18 +5,14 @@ using Volo.Abp.Application.Services; namespace Volo.Abp.Identity { - public interface IIdentityRoleAppService : IApplicationService + public interface IIdentityRoleAppService + : ICrudAppService< + IdentityRoleDto, + Guid, + PagedAndSortedResultRequestDto, + IdentityRoleCreateDto, + IdentityRoleUpdateDto> { Task> GetAllListAsync(); - - Task> GetListAsync(PagedAndSortedResultRequestDto input); - - Task CreateAsync(IdentityRoleCreateDto input); - - Task GetAsync(Guid id); - - Task UpdateAsync(Guid id, IdentityRoleUpdateDto input); - - Task DeleteAsync(Guid id); } } diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs index a184226117..97f443f3b6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs @@ -5,7 +5,13 @@ using Volo.Abp.Application.Services; namespace Volo.Abp.Identity { - public interface IIdentityUserAppService : ICrudAppService + public interface IIdentityUserAppService + : ICrudAppService< + IdentityUserDto, + Guid, + GetIdentityUsersInput, + IdentityUserCreateDto, + IdentityUserUpdateDto> { Task> GetRolesAsync(Guid id); diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorAutoMapperProfile.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorAutoMapperProfile.cs new file mode 100644 index 0000000000..bbe57e91fd --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorAutoMapperProfile.cs @@ -0,0 +1,24 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; + +namespace Volo.Abp.Identity.Blazor +{ + public class AbpIdentityBlazorAutoMapperProfile : Profile + { + public AbpIdentityBlazorAutoMapperProfile() + { + CreateMap() + .MapExtraProperties() + .Ignore(x => x.Password) + .Ignore(x => x.RoleNames); + + CreateMap() + .MapExtraProperties(); + + CreateMap() + .Ignore(x => x.Password) + .Ignore(x => x.RoleNames) + .MapExtraProperties(); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs new file mode 100644 index 0000000000..cebde068c3 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.Blazor; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.Identity.Blazor +{ + [DependsOn( + typeof(AbpIdentityHttpApiClientModule), + typeof(AbpAutoMapperModule), + typeof(AbpPermissionManagementBlazorModule) + )] + public class AbpIdentityBlazorModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + options.MenuContributors.Add(new AbpIdentityWebMainMenuContributor()); + }); + + Configure(options => + { + options.AdditionalAssemblies.Add(typeof(AbpIdentityBlazorModule).Assembly); + }); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs new file mode 100644 index 0000000000..17c956f0c7 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs @@ -0,0 +1,40 @@ +using System.Threading.Tasks; +using Volo.Abp.Identity.Localization; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.Identity.Blazor +{ + public class AbpIdentityWebMainMenuContributor : IMenuContributor + { + public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context) + { + if (context.Menu.Name != StandardMenus.Main) + { + return; + } + + var hasRolePermission = await context.IsGrantedAsync(IdentityPermissions.Roles.Default); + var hasUserPermission = await context.IsGrantedAsync(IdentityPermissions.Users.Default); + + if (hasRolePermission || hasUserPermission) + { + var administrationMenu = context.Menu.GetAdministration(); + + var l = context.GetLocalizer(); + + var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o"); + administrationMenu.AddItem(identityMenuItem); + + if (hasRolePermission) + { + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "/identity/roles")); + } + + if (hasUserPermission) + { + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "/identity/users")); + } + } + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/FodyWeavers.xml b/modules/identity/src/Volo.Abp.Identity.Blazor/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/FodyWeavers.xsd b/modules/identity/src/Volo.Abp.Identity.Blazor/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/IdentityMenuNames.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/IdentityMenuNames.cs new file mode 100644 index 0000000000..9cd5b1dc37 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/IdentityMenuNames.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.Identity.Blazor +{ + public class IdentityMenuNames + { + public const string GroupName = "AbpIdentity"; + + public const string Roles = GroupName + ".Roles"; + public const string Users = GroupName + ".Users"; + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor new file mode 100644 index 0000000000..fca4cf1913 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor @@ -0,0 +1,112 @@ +@page "/identity/roles" +@attribute [Authorize] +@using Volo.Abp.Identity +@using Microsoft.AspNetCore.Authorization +@using Microsoft.Extensions.Localization +@using Volo.Abp.Identity.Localization +@using Volo.Abp.PermissionManagement.Blazor.Components +@inherits RoleManagementBase +@inject IStringLocalizer L +@* ************************* PAGE HEADER ************************* *@ + + +

@L["Roles"]

+
+ + + + + +
+ +@* ************************* DATA GRID ************************* *@ + + + + + + + @L["Actions"] + + + @L["Edit"] + @L["Permissions"] + + @L["Delete"] + + + + + + + @(context.As().Name) + @if (context.As().IsDefault) + { + @L["DisplayName:IsDefault"] + } + @if (context.As().IsPublic) + { + @L["DisplayName:IsPublic"] + } + + + + + +@* ************************* CREATE MODAL ************************* *@ + + + + + @L["NewRole"] + + + + + @L["DisplayName:RoleName"] + + + + @L["DisplayName:IsDefault"] + @L["DisplayName:IsPublic"] + + + + + + + + + +@* ************************* EDIT MODAL ************************* *@ + + + + + Edit role + + + + + + @L["DisplayName:RoleName"] + + + + @L["DisplayName:IsDefault"] + @L["DisplayName:IsPublic"] + + + + + + + + + + diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs new file mode 100644 index 0000000000..ddbf9164b8 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs @@ -0,0 +1,19 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.BlazoriseUI; +using Volo.Abp.PermissionManagement.Blazor.Components; + +namespace Volo.Abp.Identity.Blazor.Pages.Identity +{ + public class RoleManagementBase : BlazoriseCrudPageBase + { + protected const string PermissionProviderName = "R"; + + protected PermissionManagementModal PermissionManagementModal; + + public RoleManagementBase() + { + ObjectMapperContext = typeof(AbpIdentityBlazorModule); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor new file mode 100644 index 0000000000..ca813229c3 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor @@ -0,0 +1,204 @@ +@page "/identity/users" +@attribute [Authorize] +@using Microsoft.AspNetCore.Authorization +@using Microsoft.Extensions.Localization +@using Volo.Abp.Application.Dtos +@using Volo.Abp.Identity.Localization +@using Volo.Abp.PermissionManagement.Blazor.Components +@inherits UserManagementBase +@inject IStringLocalizer L + +@* ************************* PAGE HEADER ************************* *@ + + +

@L["Users"]

+
+ + + + + +
+ +@* ************************* DATA GRID ************************* *@ + + + + + + + @L["Actions"] + + + @L["Edit"] + @L["Permissions"] + + @L["Delete"] + + + + + + + @(context.As().UserName) + + + + + @(context.As().Email) + + + + + @(context.As().PhoneNumber) + + + + + +@* ************************* CREATE MODAL ************************* *@ + + + + + @L["NewUser"] + + + + + + @L["UserInformations"] + @L["Roles"] + + + + + @L["DisplayName:UserName"] + + + + @L["DisplayName:Name"] + + + + @L["DisplayName:Surname"] + + + + @L["DisplayName:Password"] + + + + @L["DisplayName:Email"] + + + + @L["DisplayName:PhoneNumber"] + + + + @L["DisplayName:LockoutEnabled"] + + + @L["DisplayName:TwoFactorEnabled"] + + + + @if (NewUserRoles != null) + { + @foreach (var role in NewUserRoles) + { + + + @role.Name + + } + } + + + + + + + + + + + +@* ************************* EDIT MODAL ************************* *@ + + + + + role + + + + + + + + @L["UserInformations"] + @L["Roles"] + + + + + @L["DisplayName:UserName"] + + + + @L["DisplayName:Name"] + + + + @L["DisplayName:Surname"] + + + + @L["DisplayName:Password"] + + + + @L["DisplayName:Email"] + + + + @L["DisplayName:PhoneNumber"] + + + + @L["DisplayName:LockoutEnabled"] + + + @L["DisplayName:TwoFactorEnabled"] + + + + @if (EditUserRoles != null) + { + @foreach (var role in EditUserRoles) + { + + + @role.Name + + } + } + + + + + + + + + + + + diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs new file mode 100644 index 0000000000..e39c9fe567 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.BlazoriseUI; +using Volo.Abp.PermissionManagement.Blazor.Components; +using Volo.Abp.Threading; + +namespace Volo.Abp.Identity.Blazor.Pages.Identity +{ + public class UserManagementBase : BlazoriseCrudPageBase + { + protected const string PermissionProviderName = "U"; + + protected const string DefaultSelectedTab = "UserInformations"; + + protected PermissionManagementModal PermissionManagementModal; + + protected IReadOnlyList Roles; + + protected AssignedRoleViewModel[] NewUserRoles; + + protected AssignedRoleViewModel[] EditUserRoles; + + protected string _createModalSelectedTab = DefaultSelectedTab; + + protected string _editModalSelectedTab = DefaultSelectedTab; + + public UserManagementBase() + { + ObjectMapperContext = typeof(AbpIdentityBlazorModule); + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + Roles = (await AppService.GetAssignableRolesAsync()).Items; + } + + protected override Task OpenCreateModalAsync() + { + _createModalSelectedTab = DefaultSelectedTab; + + NewUserRoles = Roles.Select(x => new AssignedRoleViewModel + { + Name = x.Name, + IsAssigned = x.IsDefault + }).ToArray(); + + return base.OpenCreateModalAsync(); + } + + protected override Task CreateEntityAsync() + { + NewEntity.RoleNames = NewUserRoles.Where(x => x.IsAssigned).Select(x => x.Name).ToArray(); + + return base.CreateEntityAsync(); + } + + protected override async Task OpenEditModalAsync(Guid id) + { + _editModalSelectedTab = DefaultSelectedTab; + + var userRoleNames = (await AppService.GetRolesAsync(id)).Items.Select(r => r.Name).ToList(); + + EditUserRoles = Roles.Select(x => new AssignedRoleViewModel + { + Name = x.Name, + IsAssigned = userRoleNames.Contains(x.Name) + }).ToArray(); + + await base.OpenEditModalAsync(id); + } + + protected override Task UpdateEntityAsync() + { + EditingEntity.RoleNames = EditUserRoles.Where(x => x.IsAssigned).Select(x => x.Name).ToArray(); + + return base.UpdateEntityAsync(); + } + } + + public class AssignedRoleViewModel + { + public string Name { get; set; } + + public bool IsAssigned { get; set; } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.csproj b/modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.csproj new file mode 100644 index 0000000000..19bfb3831c --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Volo.Abp.Identity.Blazor.csproj @@ -0,0 +1,20 @@ + + + + + + + netstandard2.1 + 3.0 + + + + + + + + + + + + diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/_Imports.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/_Imports.razor new file mode 100644 index 0000000000..4685ac9893 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/_Imports.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 \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj index 06cef29fc3..e1df61cbce 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo.Abp.Identity.Domain.Shared.csproj @@ -23,6 +23,7 @@ + diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs index 4bff33d58a..e14ce5e3f4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/AbpIdentityDomainSharedModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Identity.Localization; +using Volo.Abp.Features; +using Volo.Abp.Identity.Localization; using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; @@ -11,7 +12,8 @@ namespace Volo.Abp.Identity { [DependsOn( typeof(AbpUsersDomainSharedModule), - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(AbpFeaturesModule) )] public class AbpIdentityDomainSharedModule : AbpModule { diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeature.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeature.cs new file mode 100644 index 0000000000..a51a3c11f7 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeature.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Identity.Features +{ + public class IdentityFeature + { + public const string GroupName = "Identity"; + + public const string TwoFactor = GroupName + ".TwoFactor"; + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureDefinitionProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureDefinitionProvider.cs new file mode 100644 index 0000000000..d26cc17b92 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityFeatureDefinitionProvider.cs @@ -0,0 +1,51 @@ +using System; +using Volo.Abp.Features; +using Volo.Abp.Identity.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Validation.StringValues; + +namespace Volo.Abp.Identity.Features +{ + public class IdentityFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var group = context.AddGroup(IdentityFeature.GroupName, L("Feature:IdentityGroup")); + + group.AddFeature(IdentityFeature.TwoFactor, + IdentityTwoFactorBehaviour.Optional.ToString(), + L("Feature:TwoFactor"), + L("Feature:TwoFactorDescription"), + new SelectionStringValueType + { + ItemSource = new StaticSelectionStringValueItemSource( + new LocalizableSelectionStringValueItem + { + Value = IdentityTwoFactorBehaviour.Optional.ToString(), + DisplayText = GetTwoFactorBehaviourLocalizableStringInfo("Feature:TwoFactor.Optional") + }, + new LocalizableSelectionStringValueItem + { + Value = IdentityTwoFactorBehaviour.Disabled.ToString(), + DisplayText = GetTwoFactorBehaviourLocalizableStringInfo("Feature:TwoFactor.Disabled") + }, + new LocalizableSelectionStringValueItem + { + Value = IdentityTwoFactorBehaviour.Forced.ToString(), + DisplayText = GetTwoFactorBehaviourLocalizableStringInfo("Feature:TwoFactor.Forced") + } + ) + }); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + + private static LocalizableStringInfo GetTwoFactorBehaviourLocalizableStringInfo(string key) + { + return new LocalizableStringInfo(LocalizationResourceNameAttribute.GetName(typeof(IdentityResource)), key); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviour.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviour.cs new file mode 100644 index 0000000000..4e415a7cfb --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviour.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.Identity.Features +{ + public enum IdentityTwoFactorBehaviour + { + Optional, + + Disabled, + + Forced + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviourFeatureHelper.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviourFeatureHelper.cs new file mode 100644 index 0000000000..6d8d9f33a7 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Features/IdentityTwoFactorBehaviourFeatureHelper.cs @@ -0,0 +1,23 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Features; + +namespace Volo.Abp.Identity.Features +{ + public static class IdentityTwoFactorBehaviourFeatureHelper + { + public static async Task Get([NotNull] IFeatureChecker featureChecker) + { + Check.NotNull(featureChecker, nameof(featureChecker)); + + var value = await featureChecker.GetOrNullAsync(IdentityFeature.TwoFactor); + if (value.IsNullOrWhiteSpace() || !Enum.TryParse(value, out var behaviour)) + { + throw new AbpException($"{IdentityFeature.TwoFactor} feature value is invalid"); + } + + return behaviour; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs index d5e57a6953..1defe67eeb 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityErrorCodes.cs @@ -5,5 +5,8 @@ public const string UserSelfDeletion = "Volo.Abp.Identity:010001"; public const string MaxAllowedOuMembership = "Volo.Abp.Identity:010002"; public const string ExternalUserPasswordChange = "Volo.Abp.Identity:010003"; + public const string DuplicateOrganizationUnitDisplayName = "Volo.Abp.Identity:010004"; + public const string StaticRoleRenaming = "Volo.Abp.Identity:010005"; + public const string StaticRoleDeletion = "Volo.Abp.Identity:010006"; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json index 41ac73c1b3..906f2a98f6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "تأكيد كلمة المرور الجديدة", "PasswordChangedMessage": "تم تغيير كلمة مرورك بنجاح.", "PersonalSettingsSavedMessage": "تم حفظ إعداداتك الشخصية بنجاح.", - "Identity.DefaultError": "حدث خطأ.", - "Identity.ConcurrencyFailure": "فشل التزامن المتفائل ، تم تعديل الكائن.", - "Identity.DuplicateEmail": "البريد الإلكتروني '{0}' مستخدم بالفعل.", - "Identity.DuplicateRoleName": "اسم الدور '{0}' مأخوذ بالفعل.", - "Identity.DuplicateUserName": "اسم المستخدم '{0}' مأخوذ بالفعل.", - "Identity.InvalidEmail": "البريد الإلكتروني '{0}' غير صالح.", - "Identity.InvalidPasswordHasherCompatibilityMode": "وضع PasswordHasherCompatibilityMode غير صالح.", - "Identity.InvalidPasswordHasherIterationCount": "يجب أن يكون عدد التكرار عددًا صحيحًا موجبًا.", - "Identity.InvalidRoleName": "اسم الدور '{0}' غير صالح.", - "Identity.InvalidToken": "غير صالح token.", - "Identity.InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.", - "Identity.LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.", - "Identity.PasswordMismatch": "كلمة مرور غير صحيحة.", - "Identity.PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').", - "Identity.PasswordRequiresLower": "يجب أن تحتوي كلمات المرور على حرف صغير واحد على الأقل ('a' - 'z').", - "Identity.PasswordRequiresNonAlphanumeric": "يجب أن تحتوي كلمات المرور على حرف واحد غير أبجدي رقمي على الأقل.", - "Identity.PasswordRequiresUpper": "يجب أن تحتوي كلمات المرور على حرف كبير واحد على الأقل ('A' - 'Z').", - "Identity.PasswordTooShort": "يجب أن تتكون كلمات المرور من {0} حرف على الأقل.", - "Identity.RoleNotFound": "الدور {0} غير موجود.", - "Identity.UserAlreadyHasPassword": "لدى المستخدم بالفعل مجموعة كلمات مرور.", - "Identity.UserAlreadyInRole": "المستخدم بالفعل في الدور '{0}'.", - "Identity.UserLockedOut": "المستخدم مغلق.", - "Identity.UserLockoutNotEnabled": "التأمين غير ممكّن لهذا المستخدم.", - "Identity.UserNameNotFound": "المستخدم {0} غير موجود.", - "Identity.UserNotInRole": "المستخدم ليس في الدور '{0}'.", - "Identity.PasswordConfirmationFailed": "كلمة المرور لا تتطابق مع كلمة مرور التأكيد.", - "Identity.StaticRoleRenamingErrorMessage": "لا يمكن إعادة تسمية الأدوار الثابتة.", - "Identity.StaticRoleDeletionErrorMessage": "لا يمكن حذف الأدوار الثابتة.", + "Volo.Abp.Identity:DefaultError": "حدث خطأ.", + "Volo.Abp.Identity:ConcurrencyFailure": "فشل التزامن المتفائل ، تم تعديل الكائن.", + "Volo.Abp.Identity:DuplicateEmail": "البريد الإلكتروني '{0}' مستخدم بالفعل.", + "Volo.Abp.Identity:DuplicateRoleName": "اسم الدور '{0}' مأخوذ بالفعل.", + "Volo.Abp.Identity:DuplicateUserName": "اسم المستخدم '{0}' مأخوذ بالفعل.", + "Volo.Abp.Identity:InvalidEmail": "البريد الإلكتروني '{0}' غير صالح.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "وضع PasswordHasherCompatibilityMode غير صالح.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "يجب أن يكون عدد التكرار عددًا صحيحًا موجبًا.", + "Volo.Abp.Identity:InvalidRoleName": "اسم الدور '{0}' غير صالح.", + "Volo.Abp.Identity:InvalidToken": "غير صالح token.", + "Volo.Abp.Identity:InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.", + "Volo.Abp.Identity:PasswordMismatch": "كلمة مرور غير صحيحة.", + "Volo.Abp.Identity:PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').", + "Volo.Abp.Identity:PasswordRequiresLower": "يجب أن تحتوي كلمات المرور على حرف صغير واحد على الأقل ('a' - 'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "يجب أن تحتوي كلمات المرور على حرف واحد غير أبجدي رقمي على الأقل.", + "Volo.Abp.Identity:PasswordRequiresUpper": "يجب أن تحتوي كلمات المرور على حرف كبير واحد على الأقل ('A' - 'Z').", + "Volo.Abp.Identity:PasswordTooShort": "يجب أن تتكون كلمات المرور من {0} حرف على الأقل.", + "Volo.Abp.Identity:RoleNotFound": "الدور {0} غير موجود.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "لدى المستخدم بالفعل مجموعة كلمات مرور.", + "Volo.Abp.Identity:UserAlreadyInRole": "المستخدم بالفعل في الدور '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "المستخدم مغلق.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "التأمين غير ممكّن لهذا المستخدم.", + "Volo.Abp.Identity:UserNameNotFound": "المستخدم {0} غير موجود.", + "Volo.Abp.Identity:UserNotInRole": "المستخدم ليس في الدور '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "كلمة المرور لا تتطابق مع كلمة مرور التأكيد.", + "Volo.Abp.Identity:010005": "لا يمكن إعادة تسمية الأدوار الثابتة.", + "Volo.Abp.Identity:010006": "لا يمكن حذف الأدوار الثابتة.", "Volo.Abp.Identity:010001": "لا يمكنك حذف حسابك الخاص!", "Permission:IdentityManagement": "إدارة الهوية", "Permission:RoleManagement": "إدارة الأدوار", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json index 04c85027a6..fde498c996 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json @@ -35,35 +35,35 @@ "DisplayName:NewPasswordConfirm": "Potvrzení nového hesla", "PasswordChangedMessage": "Vaše heslo bylo úspěšně změněno.", "PersonalSettingsSavedMessage": "Vaše osobní nastavení bylo úspěšně uloženo.", - "Identity.DefaultError": "Došlo k neznámé chybě.", - "Identity.ConcurrencyFailure": "Selhání optimistické souběžnosti, objekt byl změněn.", - "Identity.DuplicateEmail": "Email '{0}' již existuje.", - "Identity.DuplicateRoleName": "Role '{0}' již existuje.", - "Identity.DuplicateUserName": "Uživatelské jméno '{0}' již existuje.", - "Identity.InvalidEmail": "Email '{0}' je neplatný.", - "Identity.InvalidPasswordHasherCompatibilityMode": "Dodaný PasswordHasherCompatibilityMode je neplatný.", - "Identity.InvalidPasswordHasherIterationCount": "Počet iterací musí být kladné celé číslo.", - "Identity.InvalidRoleName": "Role '{0}' je neplatná.", - "Identity.InvalidToken": "Neplatný token.", - "Identity.InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.", - "Identity.LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.", - "Identity.PasswordMismatch": "Chybné heslo.", - "Identity.PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').", - "Identity.PasswordRequiresLower": "Hesla musí obsahovat alespoň jedno malé písmeno ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Hesla musí obsahovat alespoň jeden nealfanumerický znak.", - "Identity.PasswordRequiresUpper": "Hesla musí obsahovat alespoň jedno velké písmeno ('A'-'Z').", - "Identity.PasswordTooShort": "Hesla musí být dlouhá alespoň {0} znaků.", - "Identity.RoleNotFound": "Role {0} neexistuje.", - "Identity.UserAlreadyHasPassword": "Uživatel již má nastavené heslo.", - "Identity.UserAlreadyInRole": "Uživatel již je v roli '{0}'.", - "Identity.UserLockedOut": "Uživatel je uzamčen.", - "Identity.UserLockoutNotEnabled": "Uzamčení není umožněno pro tohoto uživatele.", - "Identity.UserNameNotFound": "Uživatel {0} neexistuje.", - "Identity.UserNotInRole": "Uživatel není v roli '{0}'.", - "Identity.PasswordConfirmationFailed": "Heslo nesouhlasí s potvrzovacím heslem.", - "Identity.StaticRoleRenamingErrorMessage": "Statické role nemohou být přejmenovány.", - "Identity.StaticRoleDeletionErrorMessage": "Statické role nemohou být smazány.", - "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "Organizační jednotka s názvem {0} již existuje. Na stejné úrovni nelze vytvořit více jednotek se stejným názvem.", + "Volo.Abp.Identity:DefaultError": "Došlo k neznámé chybě.", + "Volo.Abp.Identity:ConcurrencyFailure": "Selhání optimistické souběžnosti, objekt byl změněn.", + "Volo.Abp.Identity:DuplicateEmail": "Email '{0}' již existuje.", + "Volo.Abp.Identity:DuplicateRoleName": "Role '{0}' již existuje.", + "Volo.Abp.Identity:DuplicateUserName": "Uživatelské jméno '{0}' již existuje.", + "Volo.Abp.Identity:InvalidEmail": "Email '{0}' je neplatný.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Dodaný PasswordHasherCompatibilityMode je neplatný.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Počet iterací musí být kladné celé číslo.", + "Volo.Abp.Identity:InvalidRoleName": "Role '{0}' je neplatná.", + "Volo.Abp.Identity:InvalidToken": "Neplatný token.", + "Volo.Abp.Identity:InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.", + "Volo.Abp.Identity:PasswordMismatch": "Chybné heslo.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Hesla musí obsahovat alespoň jedno malé písmeno ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Hesla musí obsahovat alespoň jeden nealfanumerický znak.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Hesla musí obsahovat alespoň jedno velké písmeno ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Hesla musí být dlouhá alespoň {0} znaků.", + "Volo.Abp.Identity:RoleNotFound": "Role {0} neexistuje.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Uživatel již má nastavené heslo.", + "Volo.Abp.Identity:UserAlreadyInRole": "Uživatel již je v roli '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Uživatel je uzamčen.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Uzamčení není umožněno pro tohoto uživatele.", + "Volo.Abp.Identity:UserNameNotFound": "Uživatel {0} neexistuje.", + "Volo.Abp.Identity:UserNotInRole": "Uživatel není v roli '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Heslo nesouhlasí s potvrzovacím heslem.", + "Volo.Abp.Identity:010005": "Statické role nemohou být přejmenovány.", + "Volo.Abp.Identity:010006": "Statické role nemohou být smazány.", + "Volo.Abp.Identity:010004": "Organizační jednotka s názvem {0} již existuje. Na stejné úrovni nelze vytvořit více jednotek se stejným názvem.", "Identity.OrganizationUnit.MaxUserMembershipCount": "Maximální povolený počet členů organizační jednotky pro uživatele", "Volo.Abp.Identity:010001": "Nemůžete smazat svůj vlastní účet!", "Permission:IdentityManagement": "Správa identit", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json index ccd2b60cfc..a8da0baae1 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "Neues Passwort bestätigen", "PasswordChangedMessage": "Ihr Passwort wurde erfolgreich geändert.", "PersonalSettingsSavedMessage": "Ihre persönlichen Einstellungen wurden erfolgreich gespeichert.", - "Identity.DefaultError": "Ein unbekannter Fehler ist aufgetreten.", - "Identity.ConcurrencyFailure": "Optimistischer Nebenläufigkeitsfehler, Objekt wurde geändert.", - "Identity.DuplicateEmail": "E-Mail '{0}' ist bereits vergeben.", - "Identity.DuplicateRoleName": "Der Rollenname '{0}' ist bereits vergeben.", - "Identity.DuplicateUserName": "Der Benutzername '{0}' ist bereits vergeben.", - "Identity.InvalidEmail": "E-Mail '{0}' ist ungültig.", - "Identity.InvalidPasswordHasherCompatibilityMode": "Der angegebene PasswordHasherCompatibilityMode ist ungültig.", - "Identity.InvalidPasswordHasherIterationCount": "Die Iterationszahl muss eine positive Ganzzahl sein.", - "Identity.InvalidRoleName": "Der Rollenname '{0}' ist ungültig.", - "Identity.InvalidToken": "Ungültiges Token.", - "Identity.InvalidUserName": "Benutzername '{0}' ist ungültig, kann nur Buchstaben oder Ziffern enthalten.", - "Identity.LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.", - "Identity.PasswordMismatch": "Falsches Passwort.", - "Identity.PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer ('0'-'9') enthalten.", - "Identity.PasswordRequiresLower": "Passwörter müssen mindestens einen Kleinbuchstaben ('a'-'z') enthalten.", - "Identity.PasswordRequiresNonAlphanumeric": "Passwörter müssen mindestens ein Sonderzeichen enthalten.", - "Identity.PasswordRequiresUpper": "Passwörter müssen mindestens einen Großbuchstaben ('A'-'Z') enthalten.", - "Identity.PasswordTooShort": "Passwörter müssen mindestens {0} Zeichen enthalten.", - "Identity.RoleNotFound": "Die Rolle {0} existiert nicht.", - "Identity.UserAlreadyHasPassword": "Der Benutzer hat bereits ein Passwort gesetzt.", - "Identity.UserAlreadyInRole": "Benutzer ist bereits in der Rolle '{0}'.", - "Identity.UserLockedOut": "Benutzer ist ausgesperrt.", - "Identity.UserLockoutNotEnabled": "Aussperrung ist für diesen Benutzer nicht aktiviert.", - "Identity.UserNameNotFound": "Benutzer {0} existiert nicht.", - "Identity.UserNotInRole": "Benutzer ist nicht in der Rolle '{0}'.", - "Identity.PasswordConfirmationFailed": "Passwort stimmt nicht mit dem Bestätigungspasswort überein.", - "Identity.StaticRoleRenamingErrorMessage": "Statische Rollen können nicht umbenannt werden.", - "Identity.StaticRoleDeletionErrorMessage": "Statische Rollen können nicht gelöscht werden.", + "Volo.Abp.Identity:DefaultError": "Ein unbekannter Fehler ist aufgetreten.", + "Volo.Abp.Identity:ConcurrencyFailure": "Optimistischer Nebenläufigkeitsfehler, Objekt wurde geändert.", + "Volo.Abp.Identity:DuplicateEmail": "E-Mail '{0}' ist bereits vergeben.", + "Volo.Abp.Identity:DuplicateRoleName": "Der Rollenname '{0}' ist bereits vergeben.", + "Volo.Abp.Identity:DuplicateUserName": "Der Benutzername '{0}' ist bereits vergeben.", + "Volo.Abp.Identity:InvalidEmail": "E-Mail '{0}' ist ungültig.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Der angegebene PasswordHasherCompatibilityMode ist ungültig.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Die Iterationszahl muss eine positive Ganzzahl sein.", + "Volo.Abp.Identity:InvalidRoleName": "Der Rollenname '{0}' ist ungültig.", + "Volo.Abp.Identity:InvalidToken": "Ungültiges Token.", + "Volo.Abp.Identity:InvalidUserName": "Benutzername '{0}' ist ungültig, kann nur Buchstaben oder Ziffern enthalten.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.", + "Volo.Abp.Identity:PasswordMismatch": "Falsches Passwort.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer ('0'-'9') enthalten.", + "Volo.Abp.Identity:PasswordRequiresLower": "Passwörter müssen mindestens einen Kleinbuchstaben ('a'-'z') enthalten.", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Passwörter müssen mindestens ein Sonderzeichen enthalten.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Passwörter müssen mindestens einen Großbuchstaben ('A'-'Z') enthalten.", + "Volo.Abp.Identity:PasswordTooShort": "Passwörter müssen mindestens {0} Zeichen enthalten.", + "Volo.Abp.Identity:RoleNotFound": "Die Rolle {0} existiert nicht.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Der Benutzer hat bereits ein Passwort gesetzt.", + "Volo.Abp.Identity:UserAlreadyInRole": "Benutzer ist bereits in der Rolle '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Benutzer ist ausgesperrt.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Aussperrung ist für diesen Benutzer nicht aktiviert.", + "Volo.Abp.Identity:UserNameNotFound": "Benutzer {0} existiert nicht.", + "Volo.Abp.Identity:UserNotInRole": "Benutzer ist nicht in der Rolle '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Passwort stimmt nicht mit dem Bestätigungspasswort überein.", + "Volo.Abp.Identity:010005": "Statische Rollen können nicht umbenannt werden.", + "Volo.Abp.Identity:010006": "Statische Rollen können nicht gelöscht werden.", "Volo.Abp.Identity:010001": "Sie können Ihr eigenes Konto nicht löschen!", "Permission:IdentityManagement": "Identitätsverwaltung", "Permission:RoleManagement": "Rollenverwaltung", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json index 6d8a5c58c5..166433c5eb 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json @@ -35,37 +35,39 @@ "DisplayName:NewPasswordConfirm": "Confirm new password", "PasswordChangedMessage": "Your password has been changed successfully.", "PersonalSettingsSavedMessage": "Your personal settings has been saved successfully.", - "Identity.DefaultError": "An unknown failure has occurred.", - "Identity.ConcurrencyFailure": "Optimistic concurrency failure, object has been modified.", - "Identity.DuplicateEmail": "Email '{0}' is already taken.", - "Identity.DuplicateRoleName": "Role name '{0}' is already taken.", - "Identity.DuplicateUserName": "User name '{0}' is already taken.", - "Identity.InvalidEmail": "Email '{0}' is invalid.", - "Identity.InvalidPasswordHasherCompatibilityMode": "The provided PasswordHasherCompatibilityMode is invalid.", - "Identity.InvalidPasswordHasherIterationCount": "The iteration count must be a positive integer.", - "Identity.InvalidRoleName": "Role name '{0}' is invalid.", - "Identity.InvalidToken": "Invalid token.", - "Identity.InvalidUserName": "User name '{0}' is invalid, can only contain letters or digits.", - "Identity.LoginAlreadyAssociated": "A user with this login already exists.", - "Identity.PasswordMismatch": "Incorrect password.", - "Identity.PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", - "Identity.PasswordRequiresLower": "Passwords must have at least one lowercase ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Passwords must have at least one non alphanumeric character.", - "Identity.PasswordRequiresUpper": "Passwords must have at least one uppercase ('A'-'Z').", - "Identity.PasswordTooShort": "Passwords must be at least {0} characters.", - "Identity.RoleNotFound": "Role {0} does not exist.", - "Identity.UserAlreadyHasPassword": "User already has a password set.", - "Identity.UserAlreadyInRole": "User already in role '{0}'.", - "Identity.UserLockedOut": "User is locked out.", - "Identity.UserLockoutNotEnabled": "Lockout is not enabled for this user.", - "Identity.UserNameNotFound": "User {0} does not exist.", - "Identity.UserNotInRole": "User is not in role '{0}'.", - "Identity.PasswordConfirmationFailed": "Password does not match the confirm password.", - "Identity.StaticRoleRenamingErrorMessage": "Static roles can not be renamed.", - "Identity.StaticRoleDeletionErrorMessage": "Static roles can not be deleted.", - "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "There is already an organization unit with name {0}. Two units with same name can not be created in same level.", - "Identity.OrganizationUnit.MaxUserMembershipCount": "Maximum allowed organization unit membership count for a user", + "Volo.Abp.Identity:DefaultError": "An unknown failure has occurred.", + "Volo.Abp.Identity:ConcurrencyFailure": "Optimistic concurrency failure, object has been modified.", + "Volo.Abp.Identity:DuplicateEmail": "Email '{0}' is already taken.", + "Volo.Abp.Identity:DuplicateRoleName": "Role name '{0}' is already taken.", + "Volo.Abp.Identity:DuplicateUserName": "User name '{0}' is already taken.", + "Volo.Abp.Identity:InvalidEmail": "Email '{0}' is invalid.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "The provided PasswordHasherCompatibilityMode is invalid.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "The iteration count must be a positive integer.", + "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", + "Volo.Abp.Identity:InvalidToken": "Invalid token.", + "Volo.Abp.Identity:InvalidUserName": "User name '{0}' is invalid, can only contain letters or digits.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", + "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Passwords must have at least one lowercase ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Passwords must have at least one non alphanumeric character.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Passwords must have at least one uppercase ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Passwords must be at least {0} characters.", + "Volo.Abp.Identity:RoleNotFound": "Role {0} does not exist.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "User already has a password set.", + "Volo.Abp.Identity:UserAlreadyInRole": "User already in role '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "User is locked out.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Lockout is not enabled for this user.", + "Volo.Abp.Identity:UserNameNotFound": "User {0} does not exist.", + "Volo.Abp.Identity:UserNotInRole": "User is not in role '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Password does not match the confirm password.", "Volo.Abp.Identity:010001": "You can not delete your own account!", + "Volo.Abp.Identity:010002": "Can not set more than {MaxUserMembershipCount} organization unit for a user!", + "Volo.Abp.Identity:010003": "Can not change password of an externally logged in user!", + "Volo.Abp.Identity:010004": "There is already an organization unit with name {0}. Two units with same name can not be created in same level.", + "Volo.Abp.Identity:010005": "Static roles can not be renamed.", + "Volo.Abp.Identity:010006": "Static roles can not be deleted.", + "Identity.OrganizationUnit.MaxUserMembershipCount": "Maximum allowed organization unit membership count for a user", "Permission:IdentityManagement": "Identity management", "Permission:RoleManagement": "Role management", "Permission:Create": "Create", @@ -74,6 +76,12 @@ "Permission:ChangePermissions": "Change permissions", "Permission:UserManagement": "User management", "Permission:UserLookup": "User lookup", + "Feature:IdentityGroup": "Identity", + "Feature:TwoFactor": "Two Factor", + "Feature:TwoFactorDescription": "Two Factor", + "Feature:TwoFactor.Optional": "Optional", + "Feature:TwoFactor.Disabled": "Disabled", + "Feature:TwoFactor.Forced": "Forced", "DisplayName:Abp.Identity.Password.RequiredLength": "Required length", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Required unique characters number", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Required non-alphanumeric character", @@ -102,7 +110,9 @@ "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Whether a confirmed telephone number is required to sign in.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Whether the username can be updated by the user.", "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Whether the email can be updated by the user.", - "Volo.Abp.Identity:010002": "Can not set more than {MaxUserMembershipCount} organization unit for a user!", - "Volo.Abp.Identity:010003": "Can not change password of an externally logged in user!" + "DisplayName:Abp.Identity.TwoFactorBehaviour": "Two Factor behaviour", + "Description:Abp.Identity.TwoFactorBehaviour": "Two Factor behaviour", + "DisplayName:Abp.Identity.UsersCanChange": "Allow users to change their Two Factor.", + "Description:Abp.Identity.UsersCanChange": "Allow users to change their Two Factor." } -} +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 84ed47efce..1ca863e935 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "Bevestig nieuw wachtwoord", "PasswordChangedMessage": "Uw wachtwoord is met succes veranderd.", "PersonalSettingsSavedMessage": "Uw persoonlijke instellingen zijn succesvol opgeslagen.", - "Identity.DefaultError": "Er is een onbekende fout opgetreden.", - "Identity.ConcurrencyFailure": "Optimistische gelijktijdigheidsfout, object is gewijzigd.", - "Identity.DuplicateEmail": "E-mail '{0}' is al in gebruik.", - "Identity.DuplicateRoleName": "De rolnaam '{0}' is al in gebruik.", - "Identity.DuplicateUserName": "Gebruikersnaam '{0}' is al in gebruik.", - "Identity.InvalidEmail": "E-mail' {0} 'is ongeldig.", - "Identity.InvalidPasswordHasherCompatibilityMode": "De opgegeven PasswordHasherCompatibilityMode is ongeldig.", - "Identity.InvalidPasswordHasherIterationCount": "De iteratietelling moet een positief geheel getal zijn.", - "Identity.InvalidRoleName": "Rolnaam '{0}' is ongeldig.", - "Identity.InvalidToken": "Ongeldig token.", - "Identity.InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", - "Identity.LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", - "Identity.PasswordMismatch": "Incorrect wachtwoord.", - "Identity.PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').", - "Identity.PasswordRequiresLower": "Wachtwoorden moeten minstens één kleine letter bevatten ('a' - 'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Wachtwoorden moeten minimaal één niet-alfanumeriek teken bevatten.", - "Identity.PasswordRequiresUpper": "Wachtwoorden moeten ten minste één hoofdletter bevatten ('A' - 'Z').", - "Identity.PasswordTooShort": "Wachtwoorden moeten uit minimaal {0} tekens bestaan.", - "Identity.RoleNotFound": "Rol {0} bestaat niet.", - "Identity.UserAlreadyHasPassword": "Gebruiker heeft al een wachtwoord ingesteld.", - "Identity.UserAlreadyInRole": "Gebruiker al in rol '{0}'.", - "Identity.UserLockedOut": "Gebruiker is geblokkeerd.", - "Identity.UserLockoutNotEnabled": "Lockout is niet ingeschakeld voor deze gebruiker.", - "Identity.UserNameNotFound": "Gebruiker {0} bestaat niet.", - "Identity.UserNotInRole": "Gebruiker speelt geen rol '{0}'.", - "Identity.PasswordConfirmationFailed": "Wachtwoord komt niet overeen met de wachtwoord bevestiging.", - "Identity.StaticRoleRenamingErrorMessage": "Statische rollen kunnen niet worden hernoemd.", - "Identity.StaticRoleDeletionErrorMessage": "Statische rollen kunnen niet worden verwijderd.", + "Volo.Abp.Identity:DefaultError": "Er is een onbekende fout opgetreden.", + "Volo.Abp.Identity:ConcurrencyFailure": "Optimistische gelijktijdigheidsfout, object is gewijzigd.", + "Volo.Abp.Identity:DuplicateEmail": "E-mail '{0}' is al in gebruik.", + "Volo.Abp.Identity:DuplicateRoleName": "De rolnaam '{0}' is al in gebruik.", + "Volo.Abp.Identity:DuplicateUserName": "Gebruikersnaam '{0}' is al in gebruik.", + "Volo.Abp.Identity:InvalidEmail": "E-mail' {0} 'is ongeldig.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "De opgegeven PasswordHasherCompatibilityMode is ongeldig.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "De iteratietelling moet een positief geheel getal zijn.", + "Volo.Abp.Identity:InvalidRoleName": "Rolnaam '{0}' is ongeldig.", + "Volo.Abp.Identity:InvalidToken": "Ongeldig token.", + "Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", + "Volo.Abp.Identity:PasswordMismatch": "Incorrect wachtwoord.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Wachtwoorden moeten minstens één kleine letter bevatten ('a' - 'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Wachtwoorden moeten minimaal één niet-alfanumeriek teken bevatten.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Wachtwoorden moeten ten minste één hoofdletter bevatten ('A' - 'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Wachtwoorden moeten uit minimaal {0} tekens bestaan.", + "Volo.Abp.Identity:RoleNotFound": "Rol {0} bestaat niet.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Gebruiker heeft al een wachtwoord ingesteld.", + "Volo.Abp.Identity:UserAlreadyInRole": "Gebruiker al in rol '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Gebruiker is geblokkeerd.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Lockout is niet ingeschakeld voor deze gebruiker.", + "Volo.Abp.Identity:UserNameNotFound": "Gebruiker {0} bestaat niet.", + "Volo.Abp.Identity:UserNotInRole": "Gebruiker speelt geen rol '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Wachtwoord komt niet overeen met de wachtwoord bevestiging.", + "Volo.Abp.Identity:010005": "Statische rollen kunnen niet worden hernoemd.", + "Volo.Abp.Identity:010006": "Statische rollen kunnen niet worden verwijderd.", "Volo.Abp.Identity:010001": "U kunt uw eigen account niet verwijderen!", "Permission:IdentityManagement": "Identiteitsbeheer", "Permission:RoleManagement": "Rolbeheer", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json index 54d137988d..e8094553a9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "Powtierdź nowe hasło", "PasswordChangedMessage": "Twoje hasło zostało zmienione pomyślnie.", "PersonalSettingsSavedMessage": "Twoje personalne ustawienia zostały zapisane pomyślnie.", - "Identity.DefaultError": "Wystąpił niespodziewany błąd.", - "Identity.ConcurrencyFailure": "Optymistyczny błąd współbierzności, obiekt został zmodyfikowany.", - "Identity.DuplicateEmail": "Email '{0}' już istnieje.", - "Identity.DuplicateRoleName": "Rola '{0}' już istnieje.", - "Identity.DuplicateUserName": "Nazwa użytkownika '{0}' już istnieje.", - "Identity.InvalidEmail": "Email '{0}' jest niepoprawny.", - "Identity.InvalidPasswordHasherCompatibilityMode": "Dostawca PasswordHasherCompatibilityMode jest niepoprawny.", - "Identity.InvalidPasswordHasherIterationCount": "Wartość iteracji musi być większa od zera.", - "Identity.InvalidRoleName": "Rola '{0}' jest niepoprawna.", - "Identity.InvalidToken": "Niepoprawny token.", - "Identity.InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", - "Identity.LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", - "Identity.PasswordMismatch": "Niepoprawne hasło.", - "Identity.PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", - "Identity.PasswordRequiresLower": "Hasło musi zawierać przynajmniej jedną małą literę ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Hasło musi zawierać przynajmniej jeden znak alfanumeryczny.", - "Identity.PasswordRequiresUpper": "Hasło musi zawierać przynajmniej jedną wielką literę ('A'-'Z').", - "Identity.PasswordTooShort": "Hasło musi zawierać przynajmnie {0} znaków.", - "Identity.RoleNotFound": "Rola {0} nie istnieje.", - "Identity.UserAlreadyHasPassword": "Użytkownik ma już ustawione hasło.", - "Identity.UserAlreadyInRole": "Użytkownik jest już przypisany do roli '{0}'.", - "Identity.UserLockedOut": "Użytkownik jest zablokowany.", - "Identity.UserLockoutNotEnabled": "Blokada nie jest włączona dla tego użytkownika.", - "Identity.UserNameNotFound": "Użytkownik {0} nie istnieje.", - "Identity.UserNotInRole": "Użytkownik nie posiada roli '{0}'.", - "Identity.PasswordConfirmationFailed": "Podane hasła różnią się od siebie.", - "Identity.StaticRoleRenamingErrorMessage": "Statyczna rola nie może mieć zmienionej nazwy.", - "Identity.StaticRoleDeletionErrorMessage": "Statyczna rola nie może zostać usunięta.", + "Volo.Abp.Identity:DefaultError": "Wystąpił niespodziewany błąd.", + "Volo.Abp.Identity:ConcurrencyFailure": "Optymistyczny błąd współbierzności, obiekt został zmodyfikowany.", + "Volo.Abp.Identity:DuplicateEmail": "Email '{0}' już istnieje.", + "Volo.Abp.Identity:DuplicateRoleName": "Rola '{0}' już istnieje.", + "Volo.Abp.Identity:DuplicateUserName": "Nazwa użytkownika '{0}' już istnieje.", + "Volo.Abp.Identity:InvalidEmail": "Email '{0}' jest niepoprawny.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Dostawca PasswordHasherCompatibilityMode jest niepoprawny.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Wartość iteracji musi być większa od zera.", + "Volo.Abp.Identity:InvalidRoleName": "Rola '{0}' jest niepoprawna.", + "Volo.Abp.Identity:InvalidToken": "Niepoprawny token.", + "Volo.Abp.Identity:InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", + "Volo.Abp.Identity:PasswordMismatch": "Niepoprawne hasło.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Hasło musi zawierać przynajmniej jedną małą literę ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Hasło musi zawierać przynajmniej jeden znak alfanumeryczny.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Hasło musi zawierać przynajmniej jedną wielką literę ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Hasło musi zawierać przynajmnie {0} znaków.", + "Volo.Abp.Identity:RoleNotFound": "Rola {0} nie istnieje.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Użytkownik ma już ustawione hasło.", + "Volo.Abp.Identity:UserAlreadyInRole": "Użytkownik jest już przypisany do roli '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Użytkownik jest zablokowany.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Blokada nie jest włączona dla tego użytkownika.", + "Volo.Abp.Identity:UserNameNotFound": "Użytkownik {0} nie istnieje.", + "Volo.Abp.Identity:UserNotInRole": "Użytkownik nie posiada roli '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Podane hasła różnią się od siebie.", + "Volo.Abp.Identity:010005": "Statyczna rola nie może mieć zmienionej nazwy.", + "Volo.Abp.Identity:010006": "Statyczna rola nie może zostać usunięta.", "Volo.Abp.Identity:010001": "Nie możesz usunąć swojego własnego konta!", "Permission:IdentityManagement": "Zarządzanie tożsamością", "Permission:RoleManagement": "Zarządanie rolami", @@ -73,4 +73,4 @@ "Permission:UserManagement": "Zarządzanie użytkownikami", "Permission:UserLookup": "Wyszukiwanie użytkownika" } -} \ No newline at end of file +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json index 1dda38b2a5..99c2289e66 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json @@ -35,35 +35,35 @@ "DisplayName:NewPasswordConfirm": "Confirmar nova senha", "PasswordChangedMessage": "Sua senha foi alterada com sucesso.", "PersonalSettingsSavedMessage": "Suas configurações pessoais foram salvas com sucesso.", - "Identity.DefaultError": "Ocorreu uma falha desconhecida.", - "Identity.ConcurrencyFailure": "Falha de concorrência otimista, o objeto foi modificado.", - "Identity.DuplicateEmail": "O e-mail '{0}' já está em uso.", - "Identity.DuplicateRoleName": "O nome de perfil '{0}' já está em uso.", - "Identity.DuplicateUserName": "O usuário '{0}' já está em uso.", - "Identity.InvalidEmail": "E-mail '{0}' inválido.", - "Identity.InvalidPasswordHasherCompatibilityMode": "O PasswordHasherCompatibilityMode é inválido.", - "Identity.InvalidPasswordHasherIterationCount": "A contagem de iterações deve ser um inteiro positivo.", - "Identity.InvalidRoleName": "Perfil '{0}' inválido.", - "Identity.InvalidToken": "Token inválido.", - "Identity.InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.", - "Identity.LoginAlreadyAssociated": "Um usuário com este login já existe.", - "Identity.PasswordMismatch": "Senha incorreta.", - "Identity.PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').", - "Identity.PasswordRequiresLower": "Senhas devem possuir pelo menos uma letra minúscula ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Senhas devem possuir pelo menos um caractere especial.", - "Identity.PasswordRequiresUpper": "Senhas devem possuir pelo menos uma letra maiúscula ('A'-'Z').", - "Identity.PasswordTooShort": "Senhas devem possuir pelo menos {0} caracteres.", - "Identity.RoleNotFound": "Perfil {0} não existe.", - "Identity.UserAlreadyHasPassword": "O usuário já possui uma senha.", - "Identity.UserAlreadyInRole": "Usuário já possui o perfil '{0}'.", - "Identity.UserLockedOut": "O usuário está bloqueado.", - "Identity.UserLockoutNotEnabled": "Este usuário não pode ser bloqueado.", - "Identity.UserNameNotFound": "Usuário {0} não existe.", - "Identity.UserNotInRole": "Usuário não está no perfil '{0}'.", - "Identity.PasswordConfirmationFailed": "A senha não confere com a confirmação de senha.", - "Identity.StaticRoleRenamingErrorMessage": "Perfis estáticos não podem ser renomeados.", - "Identity.StaticRoleDeletionErrorMessage": "Perfis estáticos não podem ser excluídos.", - "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "Já existe uma unidade organizacional com o nome {0}. Duas unidades com o mesmo nome não pode ser criada no mesmo nível.", + "Volo.Abp.Identity:DefaultError": "Ocorreu uma falha desconhecida.", + "Volo.Abp.Identity:ConcurrencyFailure": "Falha de concorrência otimista, o objeto foi modificado.", + "Volo.Abp.Identity:DuplicateEmail": "O e-mail '{0}' já está em uso.", + "Volo.Abp.Identity:DuplicateRoleName": "O nome de perfil '{0}' já está em uso.", + "Volo.Abp.Identity:DuplicateUserName": "O usuário '{0}' já está em uso.", + "Volo.Abp.Identity:InvalidEmail": "E-mail '{0}' inválido.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "O PasswordHasherCompatibilityMode é inválido.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "A contagem de iterações deve ser um inteiro positivo.", + "Volo.Abp.Identity:InvalidRoleName": "Perfil '{0}' inválido.", + "Volo.Abp.Identity:InvalidToken": "Token inválido.", + "Volo.Abp.Identity:InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Um usuário com este login já existe.", + "Volo.Abp.Identity:PasswordMismatch": "Senha incorreta.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Senhas devem possuir pelo menos uma letra minúscula ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Senhas devem possuir pelo menos um caractere especial.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Senhas devem possuir pelo menos uma letra maiúscula ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Senhas devem possuir pelo menos {0} caracteres.", + "Volo.Abp.Identity:RoleNotFound": "Perfil {0} não existe.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "O usuário já possui uma senha.", + "Volo.Abp.Identity:UserAlreadyInRole": "Usuário já possui o perfil '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "O usuário está bloqueado.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Este usuário não pode ser bloqueado.", + "Volo.Abp.Identity:UserNameNotFound": "Usuário {0} não existe.", + "Volo.Abp.Identity:UserNotInRole": "Usuário não está no perfil '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "A senha não confere com a confirmação de senha.", + "Volo.Abp.Identity:010005": "Perfis estáticos não podem ser renomeados.", + "Volo.Abp.Identity:010006": "Perfis estáticos não podem ser excluídos.", + "Volo.Abp.Identity:010004": "Já existe uma unidade organizacional com o nome {0}. Duas unidades com o mesmo nome não pode ser criada no mesmo nível.", "Volo.Abp.Identity:010001": "Você não pode deletar sua própria conta!", "Permission:IdentityManagement": "Acessos", "Permission:RoleManagement": "Perfis", @@ -74,4 +74,4 @@ "Permission:UserManagement": "Usuários", "Permission:UserLookup": "Pesquisa de usuário" } -} \ No newline at end of file +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json index 1df7b63bfe..ebc304484a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "Подтверждение нового пароля", "PasswordChangedMessage": "Ваш пароль был успешно изменен.", "PersonalSettingsSavedMessage": "Ваши персональные настройки были успешно сохранены.", - "Identity.DefaultError": "Возникла непредвиденная ошибка.", - "Identity.ConcurrencyFailure": "Ошибка оптимального управления многопоточностью, объект был изменен.", - "Identity.DuplicateEmail": "Электронная почта '{0}' уже зарегистрирована.", - "Identity.DuplicateRoleName": "Имя роли '{0}' уже занято.", - "Identity.DuplicateUserName": "Имя пользователя '{0}' уже занято.", - "Identity.InvalidEmail": "Адрес электронной почты '{0}' недействителен.", - "Identity.InvalidPasswordHasherCompatibilityMode": "Предоставленный PasswordHasherCompatibilityMode недействителен.", - "Identity.InvalidPasswordHasherIterationCount": "Число итераций должно быть положительным целым числом.", - "Identity.InvalidRoleName": "Имя роли '{0}' недопустимо.", - "Identity.InvalidToken": "Недопустимый маркер.", - "Identity.InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", - "Identity.LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", - "Identity.PasswordMismatch": "Неверный пароль.", - "Identity.PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", - "Identity.PasswordRequiresLower": "Пароль должен содержать хотя бы одну строчную букву.", - "Identity.PasswordRequiresNonAlphanumeric": "Пароль должен иметь по крайней мере один не буквенно-цифровой символ.", - "Identity.PasswordRequiresUpper": "Пароль должен иметь хотя бы одну букву верхнего регистра.", - "Identity.PasswordTooShort": "Пароль должен содержать не менее {0} символов.", - "Identity.RoleNotFound": "Роль {0} не существует.", - "Identity.UserAlreadyHasPassword": "У пользователя уже установлен пароль.", - "Identity.UserAlreadyInRole": "Пользователь уже имеет роль '{0}'.", - "Identity.UserLockedOut": "Пользователь временно заблокирован.", - "Identity.UserLockoutNotEnabled": "Блокировка не активирована для этого пользователя.", - "Identity.UserNameNotFound": "Пользователь {0} не существует.", - "Identity.UserNotInRole": "Пользователь не имеет роль '{0}'.", - "Identity.PasswordConfirmationFailed": "Пароли не совпадают.", - "Identity.StaticRoleRenamingErrorMessage": "Статические роли не могут быть переименованы.", - "Identity.StaticRoleDeletionErrorMessage": "Статические роли не могут быть удалены.", + "Volo.Abp.Identity:DefaultError": "Возникла непредвиденная ошибка.", + "Volo.Abp.Identity:ConcurrencyFailure": "Ошибка оптимального управления многопоточностью, объект был изменен.", + "Volo.Abp.Identity:DuplicateEmail": "Электронная почта '{0}' уже зарегистрирована.", + "Volo.Abp.Identity:DuplicateRoleName": "Имя роли '{0}' уже занято.", + "Volo.Abp.Identity:DuplicateUserName": "Имя пользователя '{0}' уже занято.", + "Volo.Abp.Identity:InvalidEmail": "Адрес электронной почты '{0}' недействителен.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Предоставленный PasswordHasherCompatibilityMode недействителен.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Число итераций должно быть положительным целым числом.", + "Volo.Abp.Identity:InvalidRoleName": "Имя роли '{0}' недопустимо.", + "Volo.Abp.Identity:InvalidToken": "Недопустимый маркер.", + "Volo.Abp.Identity:InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", + "Volo.Abp.Identity:PasswordMismatch": "Неверный пароль.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", + "Volo.Abp.Identity:PasswordRequiresLower": "Пароль должен содержать хотя бы одну строчную букву.", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Пароль должен иметь по крайней мере один не буквенно-цифровой символ.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Пароль должен иметь хотя бы одну букву верхнего регистра.", + "Volo.Abp.Identity:PasswordTooShort": "Пароль должен содержать не менее {0} символов.", + "Volo.Abp.Identity:RoleNotFound": "Роль {0} не существует.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "У пользователя уже установлен пароль.", + "Volo.Abp.Identity:UserAlreadyInRole": "Пользователь уже имеет роль '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Пользователь временно заблокирован.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Блокировка не активирована для этого пользователя.", + "Volo.Abp.Identity:UserNameNotFound": "Пользователь {0} не существует.", + "Volo.Abp.Identity:UserNotInRole": "Пользователь не имеет роль '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Пароли не совпадают.", + "Volo.Abp.Identity:010005": "Статические роли не могут быть переименованы.", + "Volo.Abp.Identity:010006": "Статические роли не могут быть удалены.", "Volo.Abp.Identity:010001": "Вы не можете удалить свой собственный аккаунт!", "Permission:IdentityManagement": "Управление идентификацией", "Permission:RoleManagement": "Управление ролями", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json index 5f3cd96c55..8471735066 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "Potrdite novo geslo", "PasswordChangedMessage": "Vaše geslo je bilo uspešno spremenjeno.", "PersonalSettingsSavedMessage": "Vaše osebne nastavitve so bile uspešno shranjene.", - "Identity.DefaultError": "Zgodila se je neznana napaka.", - "Identity.ConcurrencyFailure": "Napaka pri optimistični sočasnosti, objekt je bil spremenjen.", - "Identity.DuplicateEmail": "E-poštni naslov '{0}' je že zaseden.", - "Identity.DuplicateRoleName": "Naziv vloge '{0}' je že zasedeno.", - "Identity.DuplicateUserName": "Uporabniško ime '{0}' je že zasedeno.", - "Identity.InvalidEmail": "E-poštni naslov '{0}' ni veljaven.", - "Identity.InvalidPasswordHasherCompatibilityMode": "Navedeni PasswordHasherCompatibilityMode ni veljaven.", - "Identity.InvalidPasswordHasherIterationCount": "Število iteracij mora biti pozitivno celo število.", - "Identity.InvalidRoleName": "Naziv vloge '{0}' ni veljaven.", - "Identity.InvalidToken": "Neveljaven žeton.", - "Identity.InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.", - "Identity.LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.", - "Identity.PasswordMismatch": "Nepravilno geslo.", - "Identity.PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').", - "Identity.PasswordRequiresLower": "Gesla morajo imeti vsaj eno malo črko ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Gesla morajo imeti vsaj en ne-alfanumerični znak.", - "Identity.PasswordRequiresUpper": "Gesla morajo imeti vsaj eno veliko črko ('A'-'Z').", - "Identity.PasswordTooShort": "Gesla morajo biti dolga vsaj {0} znakov.", - "Identity.RoleNotFound": "Vloga {0} ne obstaja.", - "Identity.UserAlreadyHasPassword": "Uporabnik že ima nastavljeno geslo.", - "Identity.UserAlreadyInRole": "Uporabnik že ima dodeljeno vlogo '{0}'.", - "Identity.UserLockedOut": "Uporabnik je zaklenjen.", - "Identity.UserLockoutNotEnabled": "Zaklepanje za tega uporabnika ni omogočeno.", - "Identity.UserNameNotFound": "Uporabnik {0} ne obstaja.", - "Identity.UserNotInRole": "Uporabnik nima dodeljene vloge '{0}'.", - "Identity.PasswordConfirmationFailed": "Geslo se ne ujema s potrditvenim geslom.", - "Identity.StaticRoleRenamingErrorMessage": "Statičnih vlog ni mogoče preimenovati.", - "Identity.StaticRoleDeletionErrorMessage": "Statičnih vlog ni mogoče izbrisati.", + "Volo.Abp.Identity:DefaultError": "Zgodila se je neznana napaka.", + "Volo.Abp.Identity:ConcurrencyFailure": "Napaka pri optimistični sočasnosti, objekt je bil spremenjen.", + "Volo.Abp.Identity:DuplicateEmail": "E-poštni naslov '{0}' je že zaseden.", + "Volo.Abp.Identity:DuplicateRoleName": "Naziv vloge '{0}' je že zasedeno.", + "Volo.Abp.Identity:DuplicateUserName": "Uporabniško ime '{0}' je že zasedeno.", + "Volo.Abp.Identity:InvalidEmail": "E-poštni naslov '{0}' ni veljaven.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Navedeni PasswordHasherCompatibilityMode ni veljaven.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Število iteracij mora biti pozitivno celo število.", + "Volo.Abp.Identity:InvalidRoleName": "Naziv vloge '{0}' ni veljaven.", + "Volo.Abp.Identity:InvalidToken": "Neveljaven žeton.", + "Volo.Abp.Identity:InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.", + "Volo.Abp.Identity:PasswordMismatch": "Nepravilno geslo.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Gesla morajo imeti vsaj eno malo črko ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Gesla morajo imeti vsaj en ne-alfanumerični znak.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Gesla morajo imeti vsaj eno veliko črko ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Gesla morajo biti dolga vsaj {0} znakov.", + "Volo.Abp.Identity:RoleNotFound": "Vloga {0} ne obstaja.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Uporabnik že ima nastavljeno geslo.", + "Volo.Abp.Identity:UserAlreadyInRole": "Uporabnik že ima dodeljeno vlogo '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Uporabnik je zaklenjen.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Zaklepanje za tega uporabnika ni omogočeno.", + "Volo.Abp.Identity:UserNameNotFound": "Uporabnik {0} ne obstaja.", + "Volo.Abp.Identity:UserNotInRole": "Uporabnik nima dodeljene vloge '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Geslo se ne ujema s potrditvenim geslom.", + "Volo.Abp.Identity:010005": "Statičnih vlog ni mogoče preimenovati.", + "Volo.Abp.Identity:010006": "Statičnih vlog ni mogoče izbrisati.", "Volo.Abp.Identity:010001": "Ne morete izbrisati svojega lastnega računa!", "Permission:IdentityManagement": "Upravljanje identitet", "Permission:RoleManagement": "Upravljanje vlog", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json index 0b17e51276..9bdecca7b2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json @@ -35,37 +35,39 @@ "DisplayName:NewPasswordConfirm": "Yeni şifre (tekrar)", "PasswordChangedMessage": "Şifreniz başarıyla değiştirildi.", "PersonalSettingsSavedMessage": "Kişisel bilgileriniz başarıyla kaydedildi.", - "Identity.StaticRoleRenamingErrorMessage": "Bir Sabit rolün ismi değiştirilemez.", - "Identity.StaticRoleDeletionErrorMessage": "Bir Sabit rol silinemez.", - "Identity.DefaultError": "Bilinmeyen bir hata oluştu.", - "Identity.ConcurrencyFailure": "İyimser eşzamanlılık hatası. Nesne değiştirilmiş.", - "Identity.DuplicateEmail": "'{0}' email adresi zaten alınmış.", - "Identity.DuplicateRoleName": "'{0}' rol ismi zaten alınmış.", - "Identity.DuplicateUserName": "'{0}' kullanıcı adı zaten alınmış.", - "Identity.InvalidEmail": "'{0}' email adresi hatalı.", - "Identity.InvalidPasswordHasherCompatibilityMode": "Belirtilen PasswordHasherCompatibilityMode geçersiz.", - "Identity.InvalidPasswordHasherIterationCount": "Iterasyon sayısı sıfırdan büyük bir sayı olmalı.", - "Identity.InvalidRoleName": "'{0}' rol ismi geçersizdir.", - "Identity.InvalidToken": "Geçersiz token.", - "Identity.InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.", - "Identity.LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.", - "Identity.PasswordMismatch": "Hatalı şifre.", - "Identity.PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').", - "Identity.PasswordRequiresLower": "Şifre en az bir küçük harf içermeli ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Şifre en az bir sayı ya da harf olmayan karakter içermeli.", - "Identity.PasswordRequiresUpper": "Şifre en az bir büyük harf içermeli ('A'-'Z').", - "Identity.PasswordTooShort": "Şifre en az {0} karakter uzunluğunda olmalı.", - "Identity.RoleNotFound": "{0} rolü bulunamadı.", - "Identity.UserAlreadyHasPassword": "Kullanıcının zaten bir şifresi var.", - "Identity.UserAlreadyInRole": "Kullanıcı zaten '{0}' rolünde.", - "Identity.UserLockedOut": "Kullanıcı hesabı kilitlenmiş.", - "Identity.UserLockoutNotEnabled": "Bu kullanıcı için hesap kilitleme etkin değil.", - "Identity.UserNameNotFound": "{0} kullanıcısı bulunamadı.", - "Identity.UserNotInRole": "Kullanıcı '{0}' rolünde değil.", - "Identity.PasswordConfirmationFailed": "Yeni şifre ile onay şifresi uyuşmuyor.", - "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "{0} isminde bir birim zaten var. Aynı seviyede aynı isimli iki birim olamaz.", - "Identity.OrganizationUnit.MaxUserMembershipCount": "Bir kullanıcı için izin verilen en fazla organizasyon birimi sayısı", + "Volo.Abp.Identity:010005": "Bir Sabit rolün ismi değiştirilemez.", + "Volo.Abp.Identity:010006": "Bir Sabit rol silinemez.", + "Volo.Abp.Identity:DefaultError": "Bilinmeyen bir hata oluştu.", + "Volo.Abp.Identity:ConcurrencyFailure": "İyimser eşzamanlılık hatası. Nesne değiştirilmiş.", + "Volo.Abp.Identity:DuplicateEmail": "'{0}' email adresi zaten alınmış.", + "Volo.Abp.Identity:DuplicateRoleName": "'{0}' rol ismi zaten alınmış.", + "Volo.Abp.Identity:DuplicateUserName": "'{0}' kullanıcı adı zaten alınmış.", + "Volo.Abp.Identity:InvalidEmail": "'{0}' email adresi hatalı.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "Belirtilen PasswordHasherCompatibilityMode geçersiz.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Iterasyon sayısı sıfırdan büyük bir sayı olmalı.", + "Volo.Abp.Identity:InvalidRoleName": "'{0}' rol ismi geçersizdir.", + "Volo.Abp.Identity:InvalidToken": "Geçersiz token.", + "Volo.Abp.Identity:InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.", + "Volo.Abp.Identity:PasswordMismatch": "Hatalı şifre.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Şifre en az bir küçük harf içermeli ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Şifre en az bir sayı ya da harf olmayan karakter içermeli.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Şifre en az bir büyük harf içermeli ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Şifre en az {0} karakter uzunluğunda olmalı.", + "Volo.Abp.Identity:RoleNotFound": "{0} rolü bulunamadı.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Kullanıcının zaten bir şifresi var.", + "Volo.Abp.Identity:UserAlreadyInRole": "Kullanıcı zaten '{0}' rolünde.", + "Volo.Abp.Identity:UserLockedOut": "Kullanıcı hesabı kilitlenmiş.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Bu kullanıcı için hesap kilitleme etkin değil.", + "Volo.Abp.Identity:UserNameNotFound": "{0} kullanıcısı bulunamadı.", + "Volo.Abp.Identity:UserNotInRole": "Kullanıcı '{0}' rolünde değil.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Yeni şifre ile onay şifresi uyuşmuyor.", "Volo.Abp.Identity:010001": "Kendi hesabınızı silemezsiniz!", + "Volo.Abp.Identity:010002": "Bir kullanıcı en fazla {MaxUserMembershipCount} organizasyon birimine üye olabilir!", + "Volo.Abp.Identity:010003": "Kimliği dışarıdan alınan kullanıcıların şifresi değiştirilemez!", + "Volo.Abp.Identity:010004": "{0} isminde bir birim zaten var. Aynı seviyede aynı isimli iki birim olamaz.", + "Identity.OrganizationUnit.MaxUserMembershipCount": "Bir kullanıcı için izin verilen en fazla organizasyon birimi sayısı", "Permission:IdentityManagement": "Kimlik yönetimi", "Permission:RoleManagement": "Rol yönetimi", "Permission:Create": "Oluşturma", @@ -74,7 +76,12 @@ "Permission:ChangePermissions": "İzinleri değiştirme", "Permission:UserManagement": "Kullanıcı yönetimi", "Permission:UserLookup": "Kullanıcı sorgulama", - "Volo.Abp.Identity:010002": "Bir kullanıcı en fazla {MaxUserMembershipCount} organizasyon birimine üye olabilir!", + "Feature:IdentityGroup": "Kimlik", + "Feature:TwoFactor": "İki faktörlü kimlik doğrulama", + "Feature:TwoFactorDescription": "İki faktörlü kimlik doğrulama", + "Feature:TwoFactor.Optional": "İsteğe bağlı", + "Feature:TwoFactor.Disabled": "Devre dışı", + "Feature:TwoFactor.Forced": "Zorunlu", "DisplayName:Abp.Identity.Password.RequiredLength": "Uzunluk gerekli", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Tekil karakter gerekli", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Alfasayısal olmayan karakter gerekli", @@ -102,6 +109,10 @@ "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Oturum açmak için telefon numarası gerekli", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Oturum açmak için onaylanmış bir telefon numarasının gerekli olup olmadığı.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Kullanıcı adının, kullanıcının kendisi tarafından güncellenebilirliği.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "E-posta alanının, kullanıcının kendisi tarafından güncellenebilirliği" + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "E-posta alanının, kullanıcının kendisi tarafından güncellenebilirliği", + "DisplayName:Abp.Identity.TwoFactorBehaviour": "İki faktörlü kimlik doğrulama davranışı", + "Description:Abp.Identity.TwoFactorBehaviour": "İki faktörlü kimlik doğrulama davranışı", + "DisplayName:Abp.Identity.UsersCanChange": "Kullanıcıların iki faktörlü kimlik doğrulama davranışını değiştirmelerine izin verin.", + "Description:Abp.Identity.UsersCanChange": "Kullanıcıların iki faktörlü kimlik doğrulama davranışını değiştirmelerine izin verin" } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json index 64690959b7..a241a4d515 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json @@ -35,34 +35,34 @@ "DisplayName:NewPasswordConfirm": "Xác nhận mật khẩu", "PasswordChangedMessage": "Mật khẩu của bạn đã được thay đổi thành công.", "PersonalSettingsSavedMessage": "Thiết lập của bạn đã được lưu lại thành công.", - "Identity.DefaultError": "Một thất bại chưa biết đã xảy ra.", - "Identity.ConcurrencyFailure": "Thất bại đồng thời lạc quan, đối tượng đã được sửa đổi.", - "Identity.DuplicateEmail": "Email '{0}' đã được sử dụng.", - "Identity.DuplicateRoleName": "Tên vài trò '{0}' đã được sử dụng.", - "Identity.DuplicateUserName": "User name '{0}' đã được sử dụng.", - "Identity.InvalidEmail": "Email '{0}' Không hợp lệ.", - "Identity.InvalidPasswordHasherCompatibilityMode": "PasswordHasherCompatibilityMode được cung cấp không hợp lệ.", - "Identity.InvalidPasswordHasherIterationCount": "Số lần lặp phải là số nguyên dương.", - "Identity.InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", - "Identity.InvalidToken": "Token không hợp lệ.", - "Identity.InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", - "Identity.LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", - "Identity.PasswordMismatch": "Mật khẩu không đúng.", - "Identity.PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", - "Identity.PasswordRequiresLower": "Mật khẩu phải có ít nhất một chữ thường ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "Mật khẩu phải có ít nhất một ký tự không phải là chữ và số.", - "Identity.PasswordRequiresUpper": "Mật khẩu phải có ít nhất một chữ hoa ('A'-'Z').", - "Identity.PasswordTooShort": "Mật khẩu phải ít nhất {0} kí tự.", - "Identity.RoleNotFound": "Vai trò {0} không tồn tại.", - "Identity.UserAlreadyHasPassword": "Người dùng đã có một mật khẩu.", - "Identity.UserAlreadyInRole": "Người dùng đã có vai trò '{0}'.", - "Identity.UserLockedOut": "Người dùng bị khóa.", - "Identity.UserLockoutNotEnabled": "Khóa không được kích hoạt cho người dùng này.", - "Identity.UserNameNotFound": "Người dùng {0} không tồn tại.", - "Identity.UserNotInRole": "Người dùng không có vai trò '{0}'.", - "Identity.PasswordConfirmationFailed": "Mật khẩu không khớp với mật khẩu xác nhận.", - "Identity.StaticRoleRenamingErrorMessage": "Vai trò này là cố định không được phép đổi tên.", - "Identity.StaticRoleDeletionErrorMessage": "Vai trò này là cố định không được phép xóa.", + "Volo.Abp.Identity:DefaultError": "Một thất bại chưa biết đã xảy ra.", + "Volo.Abp.Identity:ConcurrencyFailure": "Thất bại đồng thời lạc quan, đối tượng đã được sửa đổi.", + "Volo.Abp.Identity:DuplicateEmail": "Email '{0}' đã được sử dụng.", + "Volo.Abp.Identity:DuplicateRoleName": "Tên vài trò '{0}' đã được sử dụng.", + "Volo.Abp.Identity:DuplicateUserName": "User name '{0}' đã được sử dụng.", + "Volo.Abp.Identity:InvalidEmail": "Email '{0}' Không hợp lệ.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "PasswordHasherCompatibilityMode được cung cấp không hợp lệ.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "Số lần lặp phải là số nguyên dương.", + "Volo.Abp.Identity:InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", + "Volo.Abp.Identity:InvalidToken": "Token không hợp lệ.", + "Volo.Abp.Identity:InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", + "Volo.Abp.Identity:PasswordMismatch": "Mật khẩu không đúng.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Mật khẩu phải có ít nhất một chữ thường ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Mật khẩu phải có ít nhất một ký tự không phải là chữ và số.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Mật khẩu phải có ít nhất một chữ hoa ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Mật khẩu phải ít nhất {0} kí tự.", + "Volo.Abp.Identity:RoleNotFound": "Vai trò {0} không tồn tại.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "Người dùng đã có một mật khẩu.", + "Volo.Abp.Identity:UserAlreadyInRole": "Người dùng đã có vai trò '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "Người dùng bị khóa.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Khóa không được kích hoạt cho người dùng này.", + "Volo.Abp.Identity:UserNameNotFound": "Người dùng {0} không tồn tại.", + "Volo.Abp.Identity:UserNotInRole": "Người dùng không có vai trò '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Mật khẩu không khớp với mật khẩu xác nhận.", + "Volo.Abp.Identity:010005": "Vai trò này là cố định không được phép đổi tên.", + "Volo.Abp.Identity:010006": "Vai trò này là cố định không được phép xóa.", "Volo.Abp.Identity:010001": "Bạn không thể xóa tài khoản của riêng bạn!", "Permission:IdentityManagement": "Quản lý danh tính", "Permission:RoleManagement": "Quản lý vai trò", diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index ffeb4d0d40..8e8c8cbccf 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -35,35 +35,35 @@ "DisplayName:NewPasswordConfirm": "确认新密码", "PasswordChangedMessage": "你已成功更改密码.", "PersonalSettingsSavedMessage": "你的个人设置保存成功.", - "Identity.DefaultError": "发生了一个未知错误.", - "Identity.ConcurrencyFailure": "对象已被修改,乐观并发失败.", - "Identity.DuplicateEmail": "邮箱 '{0}' 已存在.", - "Identity.DuplicateRoleName": "角色名 '{0}' 已存在.", - "Identity.DuplicateUserName": "用户名 '{0}' 已存在.", - "Identity.InvalidEmail": "邮箱 '{0}' 无效.", - "Identity.InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 无效.", - "Identity.InvalidPasswordHasherIterationCount": "迭代计数必须是正整数.", - "Identity.InvalidRoleName": "角色名 '{0}' 无效.", - "Identity.InvalidToken": "token无效.", - "Identity.InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", - "Identity.LoginAlreadyAssociated": "此登录名的用户已存在.", - "Identity.PasswordMismatch": "密码错误.", - "Identity.PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", - "Identity.PasswordRequiresLower": "密码至少包含一位小写字母 ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "密码至少包含一位非字母数字字符.", - "Identity.PasswordRequiresUpper": "密码至少包含一位大写字母 ('A'-'Z').", - "Identity.PasswordTooShort": "密码至少为{0}个字符.", - "Identity.RoleNotFound": "角色 {0} 不存在.", - "Identity.UserAlreadyHasPassword": "用户已设置密码.", - "Identity.UserAlreadyInRole": "用户已具有角色 '{0}'.", - "Identity.UserLockedOut": "用户被锁定.", - "Identity.UserLockoutNotEnabled": "该用户未启用锁定.", - "Identity.UserNameNotFound": "用户 {0} 不存在.", - "Identity.UserNotInRole": "用户不具有 '{0}' 角色.", - "Identity.PasswordConfirmationFailed": "密码或确认密码不一致.", - "Identity.StaticRoleRenamingErrorMessage": "无法重命名静态角色.", - "Identity.StaticRoleDeletionErrorMessage": "无法删除静态角色.", - "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "已存在名为 {0} 的组织单位. 无法在同一级别创建相同名称的组织单位.", + "Volo.Abp.Identity:DefaultError": "发生了一个未知错误.", + "Volo.Abp.Identity:ConcurrencyFailure": "对象已被修改,乐观并发失败.", + "Volo.Abp.Identity:DuplicateEmail": "邮箱 '{0}' 已存在.", + "Volo.Abp.Identity:DuplicateRoleName": "角色名 '{0}' 已存在.", + "Volo.Abp.Identity:DuplicateUserName": "用户名 '{0}' 已存在.", + "Volo.Abp.Identity:InvalidEmail": "邮箱 '{0}' 无效.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 无效.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "迭代计数必须是正整数.", + "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.", + "Volo.Abp.Identity:InvalidToken": "token无效.", + "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.", + "Volo.Abp.Identity:PasswordMismatch": "密码错误.", + "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "密码至少包含一位小写字母 ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "密码至少包含一位非字母数字字符.", + "Volo.Abp.Identity:PasswordRequiresUpper": "密码至少包含一位大写字母 ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "密码至少为{0}个字符.", + "Volo.Abp.Identity:RoleNotFound": "角色 {0} 不存在.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "用户已设置密码.", + "Volo.Abp.Identity:UserAlreadyInRole": "用户已具有角色 '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "用户被锁定.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "该用户未启用锁定.", + "Volo.Abp.Identity:UserNameNotFound": "用户 {0} 不存在.", + "Volo.Abp.Identity:UserNotInRole": "用户不具有 '{0}' 角色.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "密码或确认密码不一致.", + "Volo.Abp.Identity:010005": "无法重命名静态角色.", + "Volo.Abp.Identity:010006": "无法删除静态角色.", + "Volo.Abp.Identity:010004": "已存在名为 {0} 的组织单位. 无法在同一级别创建相同名称的组织单位.", "Volo.Abp.Identity:010001": "您无法删除自己的帐户!", "Permission:IdentityManagement": "身份标识管理", "Permission:RoleManagement": "角色管理", @@ -73,6 +73,12 @@ "Permission:ChangePermissions": "更改权限", "Permission:UserManagement": "用户管理", "Permission:UserLookup": "用户查询", + "Feature:IdentityGroup": "身份标识", + "Feature:TwoFactor": "双因素身份验证", + "Feature:TwoFactorDescription": "双因素身份验证", + "Feature:TwoFactor.Optional": "可选", + "Feature:TwoFactor.Disabled": "禁用", + "Feature:TwoFactor.Forced": "强制启用", "DisplayName:Abp.Identity.Password.RequiredLength": "要求长度", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "要求唯一字符数量", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "要求非字母数字", @@ -98,7 +104,10 @@ "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "登录时是否需要验证的电子邮箱.", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "登录时是否需要验证的手机号码.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "是否允许用户更新用户名.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允许用户更新电子邮箱." - + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允许用户更新电子邮箱.", + "DisplayName:Abp.Identity.TwoFactorBehaviour": "双因素身份验证行为", + "Description:Abp.Identity.TwoFactorBehaviour": "双因素身份验证行为", + "DisplayName:Abp.Identity.UsersCanChange": "允许用户更改其因素身份验证.", + "Description:Abp.Identity.UsersCanChange": "允许用户更改其因素身份验证." } -} \ No newline at end of file +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json index b6e42acea2..2881bd886a 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json @@ -19,7 +19,7 @@ "RoleDeletionConfirmationMessage": "角色 '{0}' 將被刪除. 你確定嗎?", "DisplayName:RoleName": "角色名稱", "DisplayName:UserName": "使用者名稱", - "DisplayName:Name": "名子", + "DisplayName:Name": "名", "DisplayName:Surname": "姓", "DisplayName:Password": "密碼", "DisplayName:Email": "電子信箱地址", @@ -35,37 +35,39 @@ "DisplayName:NewPasswordConfirm": "確認新密碼", "PasswordChangedMessage": "你已成功更改密碼.", "PersonalSettingsSavedMessage": "你的個人設置保存成功.", - "Identity.DefaultError": "發生了一個未知錯誤.", - "Identity.ConcurrencyFailure": "對象已被修改,因樂觀並行控制導致失敗.", - "Identity.DuplicateEmail": "電子信箱 '{0}' 已存在.", - "Identity.DuplicateRoleName": "角色名 '{0}' 已存在.", - "Identity.DuplicateUserName": "使用者名稱 '{0}' 已存在.", - "Identity.InvalidEmail": "電子信箱 '{0}' 無效.", - "Identity.InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 無效.", - "Identity.InvalidPasswordHasherIterationCount": "迭代計數必須是正整數.", - "Identity.InvalidRoleName": "角色名 '{0}' 無效.", - "Identity.InvalidToken": "token無效.", - "Identity.InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.", - "Identity.LoginAlreadyAssociated": "此登入名的使用者已存在.", - "Identity.PasswordMismatch": "密碼錯誤.", - "Identity.PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').", - "Identity.PasswordRequiresLower": "密碼至少包含一位小寫字母 ('a'-'z').", - "Identity.PasswordRequiresNonAlphanumeric": "密碼至少包含一位非字母數字字元.", - "Identity.PasswordRequiresUpper": "密碼至少包含一位大寫字母 ('A'-'Z').", - "Identity.PasswordTooShort": "密碼至少為{0}個字元.", - "Identity.RoleNotFound": "角色 {0} 不存在.", - "Identity.UserAlreadyHasPassword": "使用者已設置密碼.", - "Identity.UserAlreadyInRole": "使用者已具有角色 '{0}'.", - "Identity.UserLockedOut": "使用者被鎖定.", - "Identity.UserLockoutNotEnabled": "該使用者未啟用鎖定.", - "Identity.UserNameNotFound": "使用者 {0} 不存在.", - "Identity.UserNotInRole": "使用者不具有 '{0}' 角色.", - "Identity.PasswordConfirmationFailed": "密碼或確認密碼不一致.", - "Identity.StaticRoleRenamingErrorMessage": "無法重命名靜態角色.", - "Identity.StaticRoleDeletionErrorMessage": "無法刪除靜態角色.", - "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "組織內單位內已包含名稱 {0}.同一層級組織,兩個單位不能有相同名稱", - "Identity.OrganizationUnit.MaxUserMembershipCount": "允許一個使用者至多可隸屬在幾個組織單位", + "Volo.Abp.Identity:DefaultError": "發生了一個未知錯誤.", + "Volo.Abp.Identity:ConcurrencyFailure": "對象已被修改,因樂觀並行控制導致失敗.", + "Volo.Abp.Identity:DuplicateEmail": "電子信箱 '{0}' 已存在.", + "Volo.Abp.Identity:DuplicateRoleName": "角色名 '{0}' 已存在.", + "Volo.Abp.Identity:DuplicateUserName": "使用者名稱 '{0}' 已存在.", + "Volo.Abp.Identity:InvalidEmail": "電子信箱 '{0}' 無效.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 無效.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "迭代計數必須是正整數.", + "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 無效.", + "Volo.Abp.Identity:InvalidToken": "token無效.", + "Volo.Abp.Identity:InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "此登入名的使用者已存在.", + "Volo.Abp.Identity:PasswordMismatch": "密碼錯誤.", + "Volo.Abp.Identity:PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "密碼至少包含一位小寫字母 ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "密碼至少包含一位非字母數字字元.", + "Volo.Abp.Identity:PasswordRequiresUpper": "密碼至少包含一位大寫字母 ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "密碼至少為{0}個字元.", + "Volo.Abp.Identity:RoleNotFound": "角色 {0} 不存在.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "使用者已設置密碼.", + "Volo.Abp.Identity:UserAlreadyInRole": "使用者已具有角色 '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "使用者被鎖定.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "該使用者未啟用鎖定.", + "Volo.Abp.Identity:UserNameNotFound": "使用者 {0} 不存在.", + "Volo.Abp.Identity:UserNotInRole": "使用者不具有 '{0}' 角色.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "密碼或確認密碼不一致.", "Volo.Abp.Identity:010001": "您無法刪除自己的帳號!", + "Volo.Abp.Identity:010002": "一個使用者不能設定超過 {MaxUserMembershipCount} 個組織單位", + "Volo.Abp.Identity:010003": "外部登入的使用者不能改變密碼!", + "Volo.Abp.Identity:010004": "組織內單位內已包含名稱 {0}.同一層級組織,兩個單位不能有相同名稱", + "Volo.Abp.Identity:010005": "無法重命名靜態角色.", + "Volo.Abp.Identity:010006": "無法刪除靜態角色.", + "Identity.OrganizationUnit.MaxUserMembershipCount": "允許一個使用者至多可隸屬在幾個組織單位", "Permission:IdentityManagement": "身份識別管理", "Permission:RoleManagement": "角色管理", "Permission:Create": "建立", @@ -74,34 +76,33 @@ "Permission:ChangePermissions": "更改權限", "Permission:UserManagement": "使用者管理", "Permission:UserLookup": "使用者查詢", - "DisplayName:Abp.Identity.Password.RequiredLength": "要求長度", - "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "要求唯一字元數量", - "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "要求非字母數字", - "DisplayName:Abp.Identity.Password.RequireLowercase": "要求小寫字母", - "DisplayName:Abp.Identity.Password.RequireUppercase": "要求大寫字母", - "DisplayName:Abp.Identity.Password.RequireDigit": "要求數字", - "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "允許新使用者", - "DisplayName:Abp.Identity.Lockout.LockoutDuration": "鎖定時間(秒)", - "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "最大失敗存取嘗試次數", - "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "要求驗證的電子信箱", - "DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "啟用手機號碼驗證", - "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "要求驗證的手機號碼", - "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "啟用使用者名稱更新", - "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "啟用電子信箱更新", - "Description:Abp.Identity.Password.RequiredLength": "密碼的最小長度.", - "Description:Abp.Identity.Password.RequiredUniqueChars": "密碼必須包含唯一字元的數量.", - "Description:Abp.Identity.Password.RequireNonAlphanumeric": "密碼是否必須包含非字母數字.", - "Description:Abp.Identity.Password.RequireLowercase": "密碼是否必須包含小寫字母.", - "Description:Abp.Identity.Password.RequireUppercase": "密碼是否必須包含大小字母.", - "Description:Abp.Identity.Password.RequireDigit": "密碼是否必須包含數字.", - "Description:Abp.Identity.Lockout.AllowedForNewUsers": "允許新使用者被鎖定.", - "Description:Abp.Identity.Lockout.LockoutDuration": "當鎖定發生時使用者被鎖定的時間(秒).", - "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "如果啟用鎖定,當使用者被鎖定前失敗的存取嘗試次數.", - "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "登入時是否需要驗證電子信箱.", - "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "使用者手機號碼是否需要驗證.", - "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "登入時是否需要驗證手機號碼.", - "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "是否允許使用者更新使用者名稱.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允許使用者更新電子信箱.", - "Volo.Abp.Identity:010002": "一個使用者不能設置超過 {MaxUserMembershipCount} 個組織單位下" + "DisplayName:Abp.Identity.Password.RequiredLength": "長度需符合", + "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "需最小特殊字元數", + "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "需包含非數字字母", + "DisplayName:Abp.Identity.Password.RequireLowercase": "需小寫字元", + "DisplayName:Abp.Identity.Password.RequireUppercase": "需大寫字元", + "DisplayName:Abp.Identity.Password.RequireDigit": "需要數字", + "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "允許新的使用者", + "DisplayName:Abp.Identity.Lockout.LockoutDuration": "被鎖定期間(秒)", + "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "最大登入次數嘗試", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "信箱需被確認", + "DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "允許使用者確認電話號碼", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "電話號碼需認證", + "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "允許使用者更新帳號名稱", + "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "允許使用者更新信箱", + "Description:Abp.Identity.Password.RequiredLength": "密碼須符合最小長度.", + "Description:Abp.Identity.Password.RequiredUniqueChars": "密碼至少要包含特殊字元個數.", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "密碼須包含特殊字元.", + "Description:Abp.Identity.Password.RequireLowercase": "須包含小寫字母.", + "Description:Abp.Identity.Password.RequireUppercase": "須包含大寫字母.", + "Description:Abp.Identity.Password.RequireDigit": "密碼必須包含數字.", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "使用者是否會被鎖定.", + "Description:Abp.Identity.Lockout.LockoutDuration": "使用者被鎖定後的時間.", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "當啟用鎖定功能,設定最大嘗試輸入次數,超過後就被鎖定.", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "決定使用者是否需信箱驗證後才能登入.", + "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "是否啟用電話認證.", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "決定使用者是否需電話認證後才能登入.", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "決定使用者是否能更新帳號.", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "決定使用者是否能更新信箱." } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs index eb7a88407f..879c3ffd4c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs @@ -48,5 +48,14 @@ public const string MaxUserMembershipCount = OrganizationUnitPrefix + ".MaxUserMembershipCount"; } + + public static class TwoFactor + { + private const string TwoFactorPrefix = Prefix + ".TwoFactor"; + + public const string Behaviour = TwoFactorPrefix + ".Behaviour"; + + public const string UsersCanChange = TwoFactorPrefix + ".UsersCanChange"; + } } -} \ No newline at end of file +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentityTwoFactorBehaviourSettingHelper.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentityTwoFactorBehaviourSettingHelper.cs new file mode 100644 index 0000000000..46d7d414a6 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentityTwoFactorBehaviourSettingHelper.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Identity.Features; +using Volo.Abp.Settings; + +namespace Volo.Abp.Identity.Settings +{ + public static class IdentityTwoFactorBehaviourSettingHelper + { + public static async Task Get([NotNull] ISettingProvider settingProvider) + { + Check.NotNull(settingProvider, nameof(settingProvider)); + + var value = await settingProvider.GetOrNullAsync(IdentitySettingNames.TwoFactor.Behaviour); + if (value.IsNullOrWhiteSpace() || !Enum.TryParse(value, out var behaviour)) + { + throw new AbpException($"{IdentitySettingNames.TwoFactor.Behaviour} setting value is invalid"); + } + + return behaviour; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs index 0ef3582af1..f71f8f76e9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Linq; using System.Collections.Generic; using System.Globalization; @@ -26,6 +27,41 @@ namespace Microsoft.AspNetCore.Identity throw new AbpIdentityResultException(identityResult); } + public static string[] GetValuesFromErrorMessage(this IdentityResult identityResult, IStringLocalizer localizer) + { + if (identityResult.Succeeded) + { + throw new ArgumentException( + "identityResult.Succeeded should be false in order to get values from error."); + } + + if (identityResult.Errors == null) + { + throw new ArgumentException("identityResult.Errors should not be null."); + } + + var error = identityResult.Errors.First(); + var key = $"Volo.Abp.Identity:{error.Code}"; + + using (CultureHelper.Use(CultureInfo.GetCultureInfo("en"))) + { + var englishLocalizedString = localizer[key]; + + if (englishLocalizedString.ResourceNotFound) + { + return Array.Empty(); + } + + if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, + out var values)) + { + return values; + } + + return Array.Empty(); + } + } + public static string LocalizeErrors(this IdentityResult identityResult, IStringLocalizer localizer) { if (identityResult.Succeeded) @@ -43,7 +79,7 @@ namespace Microsoft.AspNetCore.Identity public static string LocalizeErrorMessage(this IdentityError error, IStringLocalizer localizer) { - var key = $"Identity.{error.Code}"; + var key = $"Volo.Abp.Identity:{error.Code}"; var localizedString = localizer[key]; @@ -54,7 +90,8 @@ namespace Microsoft.AspNetCore.Identity var englishLocalizedString = localizer[key]; if (!englishLocalizedString.ResourceNotFound) { - if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, out var values)) + if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, + out var values)) { return string.Format(localizedString.Value, values.Cast().ToArray()); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs index d21e945f60..6feddd125b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs @@ -8,6 +8,7 @@ using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Modularity; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending.Modularity; +using Volo.Abp.Security.Claims; using Volo.Abp.Users; namespace Volo.Abp.Identity @@ -36,7 +37,7 @@ namespace Volo.Abp.Identity options.EtoMappings.Add(typeof(AbpIdentityDomainModule)); options.EtoMappings.Add(typeof(AbpIdentityDomainModule)); }); - + var identityBuilder = context.Services.AddAbpIdentity(options => { options.User.RequireUniqueEmail = true; @@ -45,6 +46,13 @@ namespace Volo.Abp.Identity context.Services.AddObjectAccessor(identityBuilder); context.Services.ExecutePreConfiguredActions(identityBuilder); + Configure(options => + { + options.ClaimsIdentity.UserIdClaimType = AbpClaimTypes.UserId; + options.ClaimsIdentity.UserNameClaimType = AbpClaimTypes.UserName; + options.ClaimsIdentity.RoleClaimType = AbpClaimTypes.Role; + }); + AddAbpIdentityOptionsFactory(context.Services); } @@ -67,7 +75,7 @@ namespace Volo.Abp.Identity IdentityModuleExtensionConsts.EntityNames.ClaimType, typeof(IdentityClaimType) ); - + ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.OrganizationUnit, @@ -81,4 +89,4 @@ namespace Volo.Abp.Identity services.Replace(ServiceDescriptor.Scoped, OptionsManager>()); } } -} \ No newline at end of file +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityResultException.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityResultException.cs index de02081a1d..05ea00bc58 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityResultException.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityResultException.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.Identity public AbpIdentityResultException([NotNull] IdentityResult identityResult) : base( - code: $"Identity.{identityResult.Errors.First().Code}", + code: $"Volo.Abp.Identity:{identityResult.Errors.First().Code}", message: identityResult.Errors.Select(err => err.Description).JoinAsString(", ")) { IdentityResult = Check.NotNull(identityResult, nameof(identityResult)); @@ -32,7 +32,21 @@ namespace Volo.Abp.Identity public virtual string LocalizeMessage(LocalizationContext context) { - return IdentityResult.LocalizeErrors(context.LocalizerFactory.Create()); + var localizer = context.LocalizerFactory.Create(); + + SetData(localizer); + + return IdentityResult.LocalizeErrors(localizer); + } + + protected virtual void SetData(IStringLocalizer localizer) + { + var values = IdentityResult.GetValuesFromErrorMessage(localizer); + + for (var index = 0; index < values.Length; index++) + { + Data[index.ToString()] = values[index]; + } } } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs index 1fdd2dd451..cff38810c9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Identity.Localization; +using Volo.Abp.Identity.Features; +using Volo.Abp.Identity.Localization; using Volo.Abp.Identity.Settings; using Volo.Abp.Localization; using Volo.Abp.Settings; @@ -33,85 +34,97 @@ namespace Volo.Abp.Identity new SettingDefinition( IdentitySettingNames.Password.RequireLowercase, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Password.RequireLowercase"), L("Description:Abp.Identity.Password.RequireLowercase"), true), new SettingDefinition( IdentitySettingNames.Password.RequireUppercase, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Password.RequireUppercase"), L("Description:Abp.Identity.Password.RequireUppercase"), true), new SettingDefinition( IdentitySettingNames.Password.RequireDigit, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Password.RequireDigit"), L("Description:Abp.Identity.Password.RequireDigit"), true), new SettingDefinition( IdentitySettingNames.Lockout.AllowedForNewUsers, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.Lockout.AllowedForNewUsers"), L("Description:Abp.Identity.Lockout.AllowedForNewUsers"), true), new SettingDefinition( IdentitySettingNames.Lockout.LockoutDuration, - (5 * 60).ToString(), + (5 * 60).ToString(), L("DisplayName:Abp.Identity.Lockout.LockoutDuration"), L("Description:Abp.Identity.Lockout.LockoutDuration"), true), new SettingDefinition( IdentitySettingNames.Lockout.MaxFailedAccessAttempts, - 5.ToString(), + 5.ToString(), L("DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts"), L("Description:Abp.Identity.Lockout.MaxFailedAccessAttempts"), true), new SettingDefinition( IdentitySettingNames.SignIn.RequireConfirmedEmail, - false.ToString(), + false.ToString(), L("DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail"), L("Description:Abp.Identity.SignIn.RequireConfirmedEmail"), true), new SettingDefinition( - IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation, - true.ToString(), - L("DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), - L("Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), + IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation, + true.ToString(), + L("DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), + L("Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation"), true), new SettingDefinition( - IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, - false.ToString(), - L("DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), - L("Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), + IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, + false.ToString(), + L("DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), + L("Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber"), true), new SettingDefinition( IdentitySettingNames.User.IsUserNameUpdateEnabled, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled"), L("Description:Abp.Identity.User.IsUserNameUpdateEnabled"), true), new SettingDefinition( IdentitySettingNames.User.IsEmailUpdateEnabled, - true.ToString(), + true.ToString(), L("DisplayName:Abp.Identity.User.IsEmailUpdateEnabled"), L("Description:Abp.Identity.User.IsEmailUpdateEnabled"), true), - new SettingDefinition( + new SettingDefinition( IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount, - int.MaxValue.ToString(), + int.MaxValue.ToString(), L("Identity.OrganizationUnit.MaxUserMembershipCount"), L("Identity.OrganizationUnit.MaxUserMembershipCount"), - true) + true), + + new SettingDefinition(IdentitySettingNames.TwoFactor.Behaviour, + IdentityTwoFactorBehaviour.Optional.ToString(), + L("DisplayName:Abp.Identity.TwoFactorBehaviour"), + L("Description:Abp.Identity.TwoFactorBehaviour"), + isVisibleToClients: true), + + new SettingDefinition(IdentitySettingNames.TwoFactor.UsersCanChange, + true.ToString(), + L("DisplayName:Abp.Identity.UsersCanChange"), + L("Description:Abp.Identity.UsersCanChange"), + isVisibleToClients: true) ); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs index 8db2b95942..c9e266bf23 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; @@ -6,6 +7,7 @@ using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Security.Claims; using Volo.Abp.Uow; +using Volo.Abp.Users; namespace Volo.Abp.Identity { @@ -13,11 +15,11 @@ namespace Volo.Abp.Identity { public AbpUserClaimsPrincipalFactory( UserManager userManager, - RoleManager roleManager, - IOptions options) + RoleManager roleManager, + IOptions options) : base( - userManager, - roleManager, + userManager, + roleManager, options) { } @@ -26,14 +28,34 @@ namespace Volo.Abp.Identity public override async Task CreateAsync(IdentityUser user) { var principal = await base.CreateAsync(user); + var identity = principal.Identities.First(); if (user.TenantId.HasValue) { - principal.Identities - .First() - .AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.ToString())); + identity.AddIfNotContains(new Claim(AbpClaimTypes.TenantId, user.TenantId.ToString())); } + if (!user.Name.IsNullOrWhiteSpace()) + { + identity.AddIfNotContains(new Claim(AbpClaimTypes.Name, user.Name)); + } + if (!user.Surname.IsNullOrWhiteSpace()) + { + identity.AddIfNotContains(new Claim(AbpClaimTypes.SurName, user.Surname)); + } + + if (!user.PhoneNumber.IsNullOrWhiteSpace()) + { + identity.AddIfNotContains(new Claim(AbpClaimTypes.PhoneNumber, user.PhoneNumber)); + } + identity.AddIfNotContains(new Claim(AbpClaimTypes.PhoneNumberVerified, user.PhoneNumberConfirmed.ToString())); + + if (!user.Email.IsNullOrWhiteSpace()) + { + identity.AddIfNotContains(new Claim(AbpClaimTypes.Email, user.Email)); + } + identity.AddIfNotContains(new Claim(AbpClaimTypes.EmailVerified, user.EmailConfirmed.ToString())); + return principal; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ClaimsIdentityExtensions.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ClaimsIdentityExtensions.cs new file mode 100644 index 0000000000..156f092f9e --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ClaimsIdentityExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; +using System.Security.Claims; + +namespace Volo.Abp.Identity +{ + public static class ClaimsIdentityExtensions + { + public static ClaimsIdentity AddIfNotContains(this ClaimsIdentity claimsIdentity, Claim claim) + { + if (!claimsIdentity.Claims.Any(existClaim => + existClaim != null && + string.Equals(existClaim.Type, claim.Type, StringComparison.OrdinalIgnoreCase))) + { + claimsIdentity.AddClaim(claim); + } + + return claimsIdentity; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs index 6650f62c82..bf39874e00 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs @@ -55,6 +55,22 @@ namespace Volo.Abp.Identity CancellationToken cancellationToken = default ); + Task> GetUnaddedRolesAsync( + OrganizationUnit organizationUnit, + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default + ); + + Task GetUnaddedRolesCountAsync( + OrganizationUnit organizationUnit, + string filter = null, + CancellationToken cancellationToken = default + ); + Task> GetMembersAsync( OrganizationUnit organizationUnit, string sorting = null, @@ -71,6 +87,22 @@ namespace Volo.Abp.Identity CancellationToken cancellationToken = default ); + Task> GetUnaddedUsersAsync( + OrganizationUnit organizationUnit, + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default + ); + + Task GetUnaddedUsersCountAsync( + OrganizationUnit organizationUnit, + string filter = null, + CancellationToken cancellationToken = default + ); + Task RemoveAllRolesAsync( OrganizationUnit organizationUnit, CancellationToken cancellationToken = default diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs index 9c2a80a807..40c249e5c4 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs @@ -29,10 +29,10 @@ namespace Volo.Abp.Identity IStringLocalizer localizer, ICancellationTokenProvider cancellationTokenProvider) : base( - store, - roleValidators, - keyNormalizer, - errors, + store, + roleValidators, + keyNormalizer, + errors, logger) { Localizer = localizer; @@ -54,7 +54,7 @@ namespace Volo.Abp.Identity { if (role.IsStatic && role.Name != name) { - throw new BusinessException(Localizer["Identity.StaticRoleRenamingErrorMessage"]); // TODO: localize & change exception type + throw new BusinessException(IdentityErrorCodes.StaticRoleRenaming); } return await base.SetRoleNameAsync(role, name); @@ -64,7 +64,7 @@ namespace Volo.Abp.Identity { if (role.IsStatic) { - throw new BusinessException(Localizer["Identity.StaticRoleDeletionErrorMessage"]); // TODO: localize & change exception type + throw new BusinessException(IdentityErrorCodes.StaticRoleDeletion); } return await base.DeleteAsync(role); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityTwoFactorManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityTwoFactorManager.cs new file mode 100644 index 0000000000..75e74afa3c --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityTwoFactorManager.cs @@ -0,0 +1,70 @@ +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; +using Volo.Abp.Features; +using Volo.Abp.Identity.Features; +using Volo.Abp.Identity.Settings; +using Volo.Abp.Settings; + +namespace Volo.Abp.Identity +{ + public class IdentityTwoFactorManager : IDomainService + { + protected IFeatureChecker FeatureChecker { get; } + + protected ISettingProvider SettingProvider { get; } + + public IdentityTwoFactorManager(IFeatureChecker featureChecker, ISettingProvider settingProvider) + { + FeatureChecker = featureChecker; + SettingProvider = settingProvider; + } + + public virtual async Task IsOptionalAsync() + { + var feature = await IdentityTwoFactorBehaviourFeatureHelper.Get(FeatureChecker); + if (feature == IdentityTwoFactorBehaviour.Optional) + { + var setting = await IdentityTwoFactorBehaviourSettingHelper.Get(SettingProvider); + if (setting == IdentityTwoFactorBehaviour.Optional) + { + return true; + } + } + + return false; + } + + public virtual async Task IsForcedEnableAsync() + { + var feature = await IdentityTwoFactorBehaviourFeatureHelper.Get(FeatureChecker); + if (feature == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + var setting = await IdentityTwoFactorBehaviourSettingHelper.Get(SettingProvider); + if (setting == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + return false; + } + + public virtual async Task IsForcedDisableAsync() + { + var feature = await IdentityTwoFactorBehaviourFeatureHelper.Get(FeatureChecker); + if (feature == IdentityTwoFactorBehaviour.Disabled) + { + return true; + } + + var setting = await IdentityTwoFactorBehaviourSettingHelper.Get(SettingProvider); + if (setting == IdentityTwoFactorBehaviour.Disabled) + { + return true; + } + return false; + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs index 17a0fbd39d..ccc3e055f5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs @@ -11,7 +11,11 @@ using Microsoft.Extensions.Logging; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; +using Volo.Abp.Features; using Volo.Abp.Guids; +using Volo.Abp.Identity.Features; +using Volo.Abp.Identity.Settings; +using Volo.Abp.Settings; namespace Volo.Abp.Identity { @@ -56,12 +60,17 @@ namespace Volo.Abp.Identity protected ILookupNormalizer LookupNormalizer { get; } protected IIdentityUserRepository UserRepository { get; } + protected IFeatureChecker FeatureChecker { get; } + protected ISettingProvider SettingProvider { get; } + public IdentityUserStore( IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository, IGuidGenerator guidGenerator, ILogger logger, ILookupNormalizer lookupNormalizer, + IFeatureChecker featureChecker, + ISettingProvider settingProvider, IdentityErrorDescriber describer = null) { UserRepository = userRepository; @@ -69,6 +78,8 @@ namespace Volo.Abp.Identity GuidGenerator = guidGenerator; Logger = logger; LookupNormalizer = lookupNormalizer; + FeatureChecker = featureChecker; + SettingProvider = settingProvider; ErrorDescriber = describer ?? new IdentityErrorDescriber(); } @@ -931,13 +942,33 @@ namespace Volo.Abp.Identity /// The that represents the asynchronous operation, containing a flag indicating whether the specified /// has two factor authentication enabled or not. /// - public virtual Task GetTwoFactorEnabledAsync([NotNull] IdentityUser user, CancellationToken cancellationToken = default) + public virtual async Task GetTwoFactorEnabledAsync([NotNull] IdentityUser user, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); Check.NotNull(user, nameof(user)); - return Task.FromResult(user.TwoFactorEnabled); + var feature = await IdentityTwoFactorBehaviourFeatureHelper.Get(FeatureChecker); + if (feature == IdentityTwoFactorBehaviour.Disabled) + { + return false; + } + if (feature == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + var setting = await IdentityTwoFactorBehaviourSettingHelper.Get(SettingProvider); + if (setting == IdentityTwoFactorBehaviour.Disabled) + { + return false; + } + if (setting == IdentityTwoFactorBehaviour.Forced) + { + return true; + } + + return user.TwoFactorEnabled; } /// diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnit.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnit.cs index 3d1bbb0531..981a0f8fae 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnit.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnit.cs @@ -23,16 +23,16 @@ namespace Volo.Abp.Identity /// /// Hierarchical Code of this organization unit. /// Example: "00001.00042.00005". - /// This is a unique code for a Tenant. + /// This is a unique code for an OrganizationUnit. /// It's changeable if OU hierarchy is changed. /// public virtual string Code { get; internal set; } /// - /// Display name of this role. + /// Display name of this OrganizationUnit. /// - public virtual string DisplayName { get; set; } - + public virtual string DisplayName { get; set; } + /// /// Roles of this OU. /// @@ -77,7 +77,7 @@ namespace Volo.Abp.Identity } /// - /// Appends a child code to a parent code. + /// Appends a child code to a parent code. /// Example: if parentCode = "00001", childCode = "00042" then returns "00001.00042". /// /// Parent code. Can be null or empty if parent is a root. diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnitManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnitManager.cs index 4706f92428..ec794a51df 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnitManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnitManager.cs @@ -131,7 +131,8 @@ namespace Volo.Abp.Identity if (siblings.Any(ou => ou.DisplayName == organizationUnit.DisplayName)) { - throw new UserFriendlyException(Localizer["Identity.OrganizationUnit.DuplicateDisplayNameWarning", organizationUnit.DisplayName]); + throw new BusinessException(IdentityErrorCodes.DuplicateOrganizationUnitDisplayName) + .WithData("0", organizationUnit.DisplayName); } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs index 7bdb7d6837..59fbd9518e 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore { public class EfCoreOrganizationUnitRepository : EfCoreRepository, - IOrganizationUnitRepository + IOrganizationUnitRepository { public EfCoreOrganizationUnitRepository( IDbContextProvider dbContextProvider) @@ -56,6 +56,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore .PageBy(skipCount, maxResultCount) .ToListAsync(GetCancellationToken(cancellationToken)); } + public virtual async Task> GetListAsync( IEnumerable ids, bool includeDetails = false, @@ -111,6 +112,39 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return await query.CountAsync(GetCancellationToken(cancellationToken)); } + public virtual async Task> GetUnaddedRolesAsync( + OrganizationUnit organizationUnit, + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToList(); + + return await DbContext.Roles + .Where(r => !roleIds.Contains(r.Id)) + .IncludeDetails(includeDetails) + .WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter)) + .OrderBy(sorting ?? nameof(IdentityRole.Name)) + .PageBy(skipCount, maxResultCount) + .ToListAsync(cancellationToken); + } + + public virtual async Task GetUnaddedRolesCountAsync( + OrganizationUnit organizationUnit, + string filter = null, + CancellationToken cancellationToken = default) + { + var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToList(); + + return await DbContext.Roles + .Where(r => !roleIds.Contains(r.Id)) + .WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter)) + .CountAsync(cancellationToken); + } + public virtual async Task> GetMembersAsync( OrganizationUnit organizationUnit, string sorting = null, @@ -118,8 +152,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore int skipCount = 0, string filter = null, bool includeDetails = false, - CancellationToken cancellationToken = default - ) + CancellationToken cancellationToken = default) { var query = CreateGetMembersFilteredQuery(organizationUnit, filter); @@ -138,6 +171,56 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return await query.CountAsync(GetCancellationToken(cancellationToken)); } + public virtual async Task> GetUnaddedUsersAsync( + OrganizationUnit organizationUnit, + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var userIdsInOrganizationUnit = DbContext.Set() + .Where(uou => uou.OrganizationUnitId == organizationUnit.Id) + .Select(uou => uou.UserId); + + var query = DbContext.Users + .Where(u => !userIdsInOrganizationUnit.Contains(u.Id)); + + if (!filter.IsNullOrWhiteSpace()) + { + query = query.Where(u => + u.UserName.Contains(filter) || + u.Email.Contains(filter) || + (u.PhoneNumber != null && u.PhoneNumber.Contains(filter)) + ); + } + + return await query + .IncludeDetails(includeDetails) + .OrderBy(sorting ?? nameof(IdentityUser.Name)) + .PageBy(skipCount, maxResultCount) + .ToListAsync(cancellationToken); + } + + public virtual async Task GetUnaddedUsersCountAsync( + OrganizationUnit organizationUnit, + string filter = null, + CancellationToken cancellationToken = default) + { + var userIdsInOrganizationUnit = DbContext.Set() + .Where(uou => uou.OrganizationUnitId == organizationUnit.Id) + .Select(uou => uou.UserId); + + return await DbContext.Users + .Where(u => !userIdsInOrganizationUnit.Contains(u.Id)) + .WhereIf(!filter.IsNullOrWhiteSpace(), u => + u.UserName.Contains(filter) || + u.Email.Contains(filter) || + (u.PhoneNumber != null && u.PhoneNumber.Contains(filter))) + .CountAsync(cancellationToken); + } + public override IQueryable WithDetails() { return GetQueryable().IncludeDetails(); diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs index 8c163d4126..10ae4cd038 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs @@ -107,6 +107,38 @@ namespace Volo.Abp.Identity.MongoDB .CountAsync(cancellationToken); } + public async Task> GetUnaddedRolesAsync( + OrganizationUnit organizationUnit, + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray(); + return await DbContext.Roles.AsQueryable() + .Where(r => !roleIds.Contains(r.Id)) + .WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter)) + .OrderBy(sorting ?? nameof(IdentityRole.Name)) + .As>() + .PageBy>(skipCount, maxResultCount) + .ToListAsync(cancellationToken); + } + + public async Task GetUnaddedRolesCountAsync( + OrganizationUnit organizationUnit, + string filter = null, + CancellationToken cancellationToken = default) + { + var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray(); + return await DbContext.Roles.AsQueryable() + .Where(r => !roleIds.Contains(r.Id)) + .WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter)) + .As>() + .CountAsync(cancellationToken); + } + public virtual async Task> GetMembersAsync( OrganizationUnit organizationUnit, string sorting = null, @@ -135,6 +167,46 @@ namespace Volo.Abp.Identity.MongoDB return await query.CountAsync(GetCancellationToken(cancellationToken)); } + public async Task> GetUnaddedUsersAsync( + OrganizationUnit organizationUnit, + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + return await DbContext.Users.AsQueryable() + .Where(u => !u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id)) + .WhereIf>( + !filter.IsNullOrWhiteSpace(), + u => + u.UserName.Contains(filter) || + u.Email.Contains(filter) || + (u.PhoneNumber != null && u.PhoneNumber.Contains(filter)) + ) + .OrderBy(sorting ?? nameof(IdentityUser.UserName)) + .As>() + .PageBy>(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public async Task GetUnaddedUsersCountAsync(OrganizationUnit organizationUnit, string filter = null, + CancellationToken cancellationToken = default) + { + return await DbContext.Users.AsQueryable() + .Where(u => !u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id)) + .WhereIf>( + !filter.IsNullOrWhiteSpace(), + u => + u.UserName.Contains(filter) || + u.Email.Contains(filter) || + (u.PhoneNumber != null && u.PhoneNumber.Contains(filter)) + ) + .As>() + .CountAsync(GetCancellationToken(cancellationToken)); + } + public virtual Task RemoveAllRolesAsync(OrganizationUnit organizationUnit, CancellationToken cancellationToken = default) { organizationUnit.Roles.Clear(); diff --git a/modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs b/modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs index 23a4529502..5362969011 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Localization; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AutoMapper; using Volo.Abp.Identity.Localization; @@ -16,7 +15,6 @@ using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Identity.Web { [DependsOn(typeof(AbpIdentityHttpApiModule))] - [DependsOn(typeof(AbpAspNetCoreMvcUiBootstrapModule))] [DependsOn(typeof(AbpAutoMapperModule))] [DependsOn(typeof(AbpPermissionManagementWebModule))] [DependsOn(typeof(AbpAspNetCoreMvcUiThemeSharedModule))] diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj b/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj index 89bb07688a..8a0b8ebd5c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj +++ b/modules/identity/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj @@ -38,7 +38,6 @@ - diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs index f730e5f445..101f4836a5 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; using Volo.Abp.PermissionManagement.MongoDB; namespace Volo.Abp.Identity.MongoDB @@ -9,19 +10,24 @@ namespace Volo.Abp.Identity.MongoDB typeof(AbpIdentityTestBaseModule), typeof(AbpPermissionManagementMongoDbModule), typeof(AbpIdentityMongoDbModule) - )] + )] public class AbpIdentityMongoDbTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs index d60611b2b6..dc134f9974 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Text; +using Xunit; namespace Volo.Abp.Identity.MongoDB { + [Collection(MongoTestCollection.Name)] public class OrganizationUnitRepository_Tests : OrganizationUnitRepository_Tests { } diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs index bb8300d449..a671ba3284 100644 --- a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs @@ -284,5 +284,43 @@ namespace Volo.Abp.Identity await uow.CompleteAsync(); } } + + [Fact] + public async Task GetUnaddedUsersOfOrganizationUnitAsync() + { + var ou = await _organizationUnitRepository.GetAsync("OU111", true); + var unaddedUsers = await _organizationUnitRepository.GetUnaddedUsersAsync(ou); + + unaddedUsers.ShouldNotContain(u => u.UserName == "john.nash"); + unaddedUsers.ShouldContain(u => u.UserName == "administrator"); + } + + [Fact] + public async Task GetUnaddedRolesOfOrganizationUnitAsync() + { + var ou = await _organizationUnitRepository.GetAsync("OU111", true); + var unaddedRoles = await _organizationUnitRepository.GetUnaddedRolesAsync(ou); + + unaddedRoles.ShouldNotContain(u => u.Name == "manager"); + unaddedRoles.ShouldNotContain(u => u.Name == "moderator"); + unaddedRoles.ShouldContain(u => u.Name.Contains("admin")); + } + + [Fact] + public async Task GetUnaddedUsersCountOfOrganizationUnitAsync() + { + var ou = await _organizationUnitRepository.GetAsync("OU111", true); + var count = await _organizationUnitRepository.GetUnaddedUsersCountAsync(ou); + count.ShouldBeGreaterThan(0); + + } + + [Fact] + public async Task GetUnaddedRolesCountOfOrganizationUnitAsync() + { + var ou = await _organizationUnitRepository.GetAsync("OU111", true); + var count = await _organizationUnitRepository.GetUnaddedRolesCountAsync(ou); + count.ShouldBeGreaterThan(0); + } } } diff --git a/modules/identityserver/common.props b/modules/identityserver/common.props index a9aaa3c07a..7f5a705307 100644 --- a/modules/identityserver/common.props +++ b/modules/identityserver/common.props @@ -2,7 +2,7 @@ latest 0.3.0 - $(NoWarn);CS1591 + $(NoWarn);CS1591;CS0436 http://www.aspnetboilerplate.com/images/abp_nupkg.png http://abp.io git diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs index d1721c720f..ae32aa2d4a 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs @@ -3,6 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.Identity.MongoDB; using Volo.Abp.IdentityServer.MongoDB; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.IdentityServer { @@ -16,7 +17,7 @@ namespace Volo.Abp.IdentityServer { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); @@ -24,6 +25,11 @@ namespace Volo.Abp.IdentityServer { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/modules/permission-management/Volo.Abp.PermissionManagement.sln b/modules/permission-management/Volo.Abp.PermissionManagement.sln index 7206382e8e..535a31fb2f 100644 --- a/modules/permission-management/Volo.Abp.PermissionManagement.sln +++ b/modules/permission-management/Volo.Abp.PermissionManagement.sln @@ -35,6 +35,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.PermissionManageme EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.PermissionManagement.Application.Tests", "test\Volo.Abp.PermissionManagement.Application.Tests\Volo.Abp.PermissionManagement.Application.Tests.csproj", "{A0F72F5F-3713-4E06-ADB7-15ADFDCB79B1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.PermissionManagement.Blazor", "src\Volo.Abp.PermissionManagement.Blazor\Volo.Abp.PermissionManagement.Blazor.csproj", "{6F899C50-83BB-43C4-983A-DCCD8FBBF066}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,6 +99,10 @@ Global {A0F72F5F-3713-4E06-ADB7-15ADFDCB79B1}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0F72F5F-3713-4E06-ADB7-15ADFDCB79B1}.Release|Any CPU.ActiveCfg = Release|Any CPU {A0F72F5F-3713-4E06-ADB7-15ADFDCB79B1}.Release|Any CPU.Build.0 = Release|Any CPU + {6F899C50-83BB-43C4-983A-DCCD8FBBF066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F899C50-83BB-43C4-983A-DCCD8FBBF066}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F899C50-83BB-43C4-983A-DCCD8FBBF066}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F899C50-83BB-43C4-983A-DCCD8FBBF066}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -116,6 +122,7 @@ Global {9E0B517E-F02E-436F-9695-7CF12795D34C} = {B559B878-38F7-49CC-BC06-43A32D68C1A7} {1CD80519-9431-48DB-B0EA-291A73FF9F49} = {B559B878-38F7-49CC-BC06-43A32D68C1A7} {A0F72F5F-3713-4E06-ADB7-15ADFDCB79B1} = {63DA4A89-5908-4F37-B7E6-525AEEF20C77} + {6F899C50-83BB-43C4-983A-DCCD8FBBF066} = {B559B878-38F7-49CC-BC06-43A32D68C1A7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8FC7DF78-5E2D-489F-9D43-147D2ABAA112} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/AbpPermissionManagementBlazorModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/AbpPermissionManagementBlazorModule.cs new file mode 100644 index 0000000000..26381615f3 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/AbpPermissionManagementBlazorModule.cs @@ -0,0 +1,16 @@ +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace Volo.Abp.PermissionManagement.Blazor +{ + [DependsOn( + typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule), + typeof(AbpAutoMapperModule), + typeof(AbpPermissionManagementHttpApiClientModule) + )] + public class AbpPermissionManagementBlazorModule : AbpModule + { + + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor new file mode 100644 index 0000000000..e94319c9ff --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor @@ -0,0 +1,79 @@ +@using Microsoft.Extensions.Localization +@using Volo.Abp.PermissionManagement.Localization +@inject IStringLocalizer L + + + + + @L["Permissions"] - @_entityDisplayName + + + + + + @L["SelectAllInAllTabs"] + + + + + @if (_groups != null) + { + + + @foreach (var group in _groups) + { + + @if (group.Permissions.Any(x => x.IsGranted)) + { + + @group.DisplayName ( @(group.Permissions.Count(x => x.IsGranted)) ) + + } + else + { + + @group.DisplayName ( @(group.Permissions.Count(x => x.IsGranted)) ) + + } + + } + + + @foreach (var group in _groups) + { + +

@group.DisplayName

+ + + + + @L["SelectAllInThisTab"] + + + + + @foreach (var permission in group.Permissions) + { + + + @permission.DisplayName + + + } + +
+ } +
+
+ } +
+ + + + +
+
\ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs new file mode 100644 index 0000000000..40333fdc80 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs @@ -0,0 +1,119 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Blazorise; +using Microsoft.AspNetCore.Components; + +namespace Volo.Abp.PermissionManagement.Blazor.Components +{ + public partial class PermissionManagementModal + { + [Inject] private IPermissionAppService PermissionAppService { get; set; } + + private Modal _modal; + + private string _providerName; + private string _providerKey; + + private string _entityDisplayName; + private List _groups; + + private List _disabledPermissions; + + private string _selectedTabName; + + private bool GrantAll + { + get + { + return _groups != null && _groups.All(x => x.Permissions.All(y => y.IsGranted)); + } + set + { + if (_groups == null) + { + return; + } + + foreach (var permissionGroupDto in _groups) + { + foreach (var permission in permissionGroupDto.Permissions) + { + if (!IsDisabledPermission(permission)) + { + permission.IsGranted = value; + } + } + } + } + } + + public async Task OpenAsync(string providerName, string providerKey) + { + _providerName = providerName; + _providerKey = providerKey; + + var result = await PermissionAppService.GetAsync(_providerName, _providerKey); + + _entityDisplayName = result.EntityDisplayName; + _groups = result.Groups; + + _disabledPermissions = + _groups.SelectMany(x => x.Permissions) + .Where( + x => x.IsGranted && + x.GrantedProviders.All(y => y.ProviderName != _providerName) + ).ToList(); + + _selectedTabName = GetNormalizedGroupName(_groups.First().Name); + + _modal.Show(); + } + + private void CloseModal() + { + _modal.Hide(); + } + + private async Task SaveAsync() + { + var updateDto = new UpdatePermissionsDto + { + Permissions = _groups + .SelectMany(g => g.Permissions) + .Select(p => new UpdatePermissionDto {IsGranted = p.IsGranted, Name = p.Name}) + .ToArray() + }; + + await PermissionAppService.UpdateAsync(_providerName, _providerKey, updateDto); + + _modal.Hide(); + } + + private string GetNormalizedGroupName(string name) + { + return "PermissionGroup_" + name.Replace(".", "_"); + } + + private void GrantAllChanged(bool value) + { + GrantAll = value; + } + + private void GroupGrantAllChanged(bool value, string groupName) + { + foreach (var permission in _groups.First(x => x.Name == groupName).Permissions) + { + if (!IsDisabledPermission(permission)) + { + permission.IsGranted = value; + } + } + } + + private bool IsDisabledPermission(PermissionGrantInfoDto permissionGrantInfo) + { + return _disabledPermissions.Any(x => x == permissionGrantInfo); + } + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/FodyWeavers.xml b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/FodyWeavers.xsd b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.csproj b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.csproj new file mode 100644 index 0000000000..0663ca49a5 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Volo.Abp.PermissionManagement.Blazor.csproj @@ -0,0 +1,20 @@ + + + + + + + netstandard2.1 + 3.0 + + + + + + + + + + + + diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/_Imports.razor b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/_Imports.razor new file mode 100644 index 0000000000..4685ac9893 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/_Imports.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 \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Properties/launchSettings.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Properties/launchSettings.json new file mode 100644 index 0000000000..5e8bf1d171 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:62454/", + "sslPort": 44344 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Volo.Abp.PermissionManagement.Web": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs index 8e3c7b2c22..d896cf01dc 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.PermissionManagement.MongoDB { @@ -11,14 +12,19 @@ namespace Volo.Abp.PermissionManagement.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + - "Db_" + - Guid.NewGuid().ToString("N"); + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + "Db_" + + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs index ec221eba15..0e456a2df8 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.SettingManagement.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Abp.SettingManagement.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json index d6d1d7c155..ba4109c392 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json @@ -10,13 +10,14 @@ "ConnectionStrings": "Connection Strings", "DisplayName:DefaultConnectionString": "Default Connection String", "DisplayName:UseSharedDatabase": "Use the Shared Database", + "ManageHostFeatures": "Manage Host features", "Permission:TenantManagement": "Tenant management", "Permission:Create": "Create", "Permission:Edit": "Edit", "Permission:Delete": "Delete", "Permission:ManageConnectionStrings": "Manage connection strings", "Permission:ManageFeatures": "Manage features", - "DisplayName:AdminEmailAddress": "Admin Email Address", - "DisplayName:AdminPassword": "Admin Password" + "DisplayName:AdminEmailAddress": "Admin Email Address", + "DisplayName:AdminPassword": "Admin Password" } -} \ No newline at end of file +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json index 72b570f3f9..7315cccc3f 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json @@ -10,6 +10,7 @@ "ConnectionStrings": "Bağlantı cümlesi", "DisplayName:DefaultConnectionString": "Varsayılan bağlantı cümlesi", "DisplayName:UseSharedDatabase": "Paylaşılan veritabanını kullan", + "ManageHostFeatures": "Toplantı Sahibi özelliklerini yönetin", "Permission:TenantManagement": "Müşteri yönetimi", "Permission:Create": "Oluşturma", "Permission:Edit": "Düzenleme", @@ -19,4 +20,4 @@ "DisplayName:AdminEmailAddress": "Admin Eposta Adresi", "DisplayName:AdminPassword": "Admin Şifresi" } -} \ No newline at end of file +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json index b60c68e2e0..f85f6cf638 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json @@ -10,6 +10,7 @@ "ConnectionStrings": "连接字符串", "DisplayName:DefaultConnectionString": "默认连接字符串", "DisplayName:UseSharedDatabase": "使用共享数据库", + "ManageHostFeatures": "管理Host特性", "Permission:TenantManagement": "租户管理", "Permission:Create": "创建", "Permission:Edit": "编辑", @@ -17,4 +18,4 @@ "Permission:ManageConnectionStrings": "管理连接字符串", "Permission:ManageFeatures": "管理功能" } -} \ No newline at end of file +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json index ea8be8ae0e..6950a1ca00 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json @@ -10,13 +10,14 @@ "ConnectionStrings": "資料庫連線字串", "DisplayName:DefaultConnectionString": "預設資料庫連線字串", "DisplayName:UseSharedDatabase": "使用共用資料庫", + "ManageHostFeatures": "管理Host功能", "Permission:TenantManagement": "租戶管理", "Permission:Create": "新增", "Permission:Edit": "編輯", "Permission:Delete": "刪除", "Permission:ManageConnectionStrings": "管理資料庫連線字串", "Permission:ManageFeatures": "管理功能", - "DisplayName:AdminEmailAddress": "管理者信箱", + "DisplayName:AdminEmailAddress": "管理者信箱", "DisplayName:AdminPassword": "管理者密碼" } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml index eabc75c786..bb972b02d8 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml @@ -2,6 +2,7 @@ @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.Abp.FeatureManagement @using Volo.Abp.TenantManagement @using Volo.Abp.TenantManagement.Localization @using Volo.Abp.TenantManagement.Web.Navigation @@ -29,9 +30,13 @@ @L["Tenants"] + @if (await Authorization.IsGrantedAsync(FeatureManagementPermissions.ManageHostFeatures)) + { + + } @if (await Authorization.IsGrantedAsync(TenantManagementPermissions.Tenants.Create)) { - + } @@ -39,4 +44,4 @@ - \ No newline at end of file + diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js index 4b19d0bbb7..69bbb0b955 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js @@ -100,7 +100,7 @@ }, 0 //adds as the first contributor ); - + $(function () { var _$wrapper = $('#TenantsWrapper'); @@ -128,5 +128,12 @@ e.preventDefault(); _createModal.open(); }); + + _$wrapper.find('button[name=ManageHostFeatures]').click(function (e) { + e.preventDefault(); + _featuresModal.open({ + providerName: 'T' + }); + }); }); })(); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs index 9584ec2d44..3bdcf0ad9c 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs @@ -1,6 +1,7 @@ using System; using Volo.Abp.Data; using Volo.Abp.Modularity; +using Volo.Abp.Uow; namespace Volo.Abp.TenantManagement.MongoDB { @@ -12,14 +13,19 @@ namespace Volo.Abp.TenantManagement.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { options.ConnectionStrings.Default = connectionString; }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; + }); } } } diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs index 1b3777f6a8..689f273178 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs @@ -1,5 +1,7 @@ using System; using Mongo2Go; +using MongoDB.Driver; +using Volo.Abp.MongoDB; namespace Volo.Abp.TenantManagement.MongoDB { diff --git a/npm/lerna.json b/npm/lerna.json index c7e316ca8b..75b0730cfd 100644 --- a/npm/lerna.json +++ b/npm/lerna.json @@ -1,5 +1,5 @@ { - "version": "3.1.0-rc.3", + "version": "3.1.2", "packages": [ "packs/*" ], diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.ts index e338675552..f16ba9b898 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.ts @@ -22,5 +22,9 @@ export const environment = { url: 'https://localhost:44305', rootNamespace: 'MyCompanyName.MyProjectName', }, + AbpFeatureManagement: { + url: 'https://localhost:44305', + rootNamespace: 'Volo.Abp', + }, }, } as Config.Environment; diff --git a/npm/ng-packs/lerna.version.json b/npm/ng-packs/lerna.version.json index c872eedc50..3162795864 100644 --- a/npm/ng-packs/lerna.version.json +++ b/npm/ng-packs/lerna.version.json @@ -1,5 +1,5 @@ { - "version": "3.1.0-rc.3", + "version": "3.1.2", "packages": [ "packages/*" ], diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index afee0f022a..b3f6321b92 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -19,25 +19,27 @@ "prepare:workspace": "yarn scripts:build --noInstall", "ci": "yarn ng lint && yarn prepare:workspace && yarn ci:test && yarn ci:build", "ci:test": "ng test --coverage=false --silent", - "ci:build": "cd scripts && yarn build:prod", + "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", "postinstall": "npm run compile:ivy" }, "devDependencies": { - "@abp/ng.account": "~3.1.0-rc.3", - "@abp/ng.core": "~3.1.0-rc.3", - "@abp/ng.feature-management": "~3.1.0-rc.3", - "@abp/ng.identity": "~3.1.0-rc.3", - "@abp/ng.permission-management": "~3.1.0-rc.3", - "@abp/ng.setting-management": "~3.1.0-rc.3", - "@abp/ng.tenant-management": "~3.1.0-rc.3", - "@abp/ng.theme.basic": "~3.1.0-rc.3", - "@abp/ng.theme.shared": "~3.1.0-rc.3", - "@abp/utils": "^3.1.0-rc.3", + "@abp/ng.account": "~3.1.2", + "@abp/ng.core": "~3.1.2", + "@abp/ng.feature-management": "~3.1.2", + "@abp/ng.identity": "~3.1.2", + "@abp/ng.permission-management": "~3.1.2", + "@abp/ng.schematics": "~3.1.2", + "@abp/ng.setting-management": "~3.1.2", + "@abp/ng.tenant-management": "~3.1.2", + "@abp/ng.theme.basic": "~3.1.2", + "@abp/ng.theme.shared": "~3.1.2", + "@abp/utils": "^3.1.2", "@angular-builders/jest": "^10.0.0", "@angular-devkit/build-angular": "~0.1000.6", "@angular-devkit/build-ng-packagr": "~0.1000.6", + "@angular-devkit/schematics-cli": "^0.1001.1", "@angular/animations": "~10.0.10", "@angular/cli": "~10.0.6", "@angular/common": "~10.0.10", @@ -54,11 +56,11 @@ "@ng-bootstrap/ng-bootstrap": "^7.0.0", "@ngneat/spectator": "^5.13.0", "@ngx-validate/core": "^0.0.11", - "@ngxs/devtools-plugin": "^3.6.2", - "@ngxs/logger-plugin": "^3.6.2", - "@ngxs/router-plugin": "^3.6.2", - "@ngxs/storage-plugin": "^3.6.2", - "@ngxs/store": "^3.6.2", + "@ngxs/devtools-plugin": "^3.7.0", + "@ngxs/logger-plugin": "^3.7.0", + "@ngxs/router-plugin": "^3.7.0", + "@ngxs/storage-plugin": "^3.7.0", + "@ngxs/store": "^3.7.0", "@schematics/angular": "~10.0.5", "@swimlane/ngx-datatable": "^17.1.0", "@types/jest": "^25.2.3", diff --git a/npm/ng-packs/packages/account/package.json b/npm/ng-packs/packages/account/package.json index f1b35ab34c..6e3f4e8eaf 100644 --- a/npm/ng-packs/packages/account/package.json +++ b/npm/ng-packs/packages/account/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.account", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "~3.1.0-rc.3", + "@abp/ng.theme.shared": "~3.1.2", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/components/package.json b/npm/ng-packs/packages/components/package.json index f28f0bdccc..b59862afb5 100644 --- a/npm/ng-packs/packages/components/package.json +++ b/npm/ng-packs/packages/components/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.components", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "peerDependencies": { - "@abp/ng.core": ">=3.1.0-rc.3", + "@abp/ng.core": ">=3.1.2", "@ng-bootstrap/ng-bootstrap": ">=6.0.0" }, "dependencies": { diff --git a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html index b7c777a449..b98aa7e4ff 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html +++ b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html @@ -7,6 +7,7 @@ [nzData]="nodes" [nzTreeTemplate]="treeTemplate" [nzExpandedKeys]="expandedKeys" + [nzExpandedIcon]="expandedIconTemplate?.template" (nzExpandChange)="onExpandedKeysChange($event)" (nzCheckBoxChange)="onCheckboxChange($event)" (nzOnDrop)="onDrop($event)" @@ -18,7 +19,16 @@ [title]="node.title" (click)="onSelectedNodeChange(node)" > - {{ node.title }} + + + + {{ node.title }} +
diff --git a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts index ac7a709048..7ba6280c0b 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts +++ b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts @@ -9,6 +9,8 @@ import { } from '@angular/core'; import { NzFormatEmitEvent, NzFormatBeforeDropEvent } from 'ng-zorro-antd/tree'; import { of } from 'rxjs'; +import { TreeNodeTemplateDirective } from '../templates/tree-node-template.directive'; +import { ExpandedIconTemplateDirective } from '../templates/expanded-icon-template.directive'; export type DropEvent = NzFormatEmitEvent & { pos: number }; @@ -25,6 +27,8 @@ export class TreeComponent { dropPosition: number; @ContentChild('menu') menu: TemplateRef; + @ContentChild(TreeNodeTemplateDirective) customNodeTemplate: TreeNodeTemplateDirective; + @ContentChild(ExpandedIconTemplateDirective) expandedIconTemplate: ExpandedIconTemplateDirective; @Output() readonly checkedKeysChange = new EventEmitter(); @Output() readonly expandedKeysChange = new EventEmitter(); @Output() readonly selectedNodeChange = new EventEmitter(); diff --git a/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts b/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts new file mode 100644 index 0000000000..35706bd25f --- /dev/null +++ b/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts @@ -0,0 +1,8 @@ +import { Directive, TemplateRef } from '@angular/core'; + +@Directive({ + selector: '[abpTreeExpandedIconTemplate],[abp-tree-expanded-icon-template]', +}) +export class ExpandedIconTemplateDirective { + constructor(public template: TemplateRef) {} +} diff --git a/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts b/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts new file mode 100644 index 0000000000..56c66af04b --- /dev/null +++ b/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts @@ -0,0 +1,8 @@ +import { Directive, TemplateRef } from '@angular/core'; + +@Directive({ + selector: '[abpTreeNodeTemplate],[abp-tree-node-template]', +}) +export class TreeNodeTemplateDirective { + constructor(public template: TemplateRef) {} +} diff --git a/npm/ng-packs/packages/components/tree/src/lib/tree.module.ts b/npm/ng-packs/packages/components/tree/src/lib/tree.module.ts index f16ed0dd55..b645a69925 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/tree.module.ts +++ b/npm/ng-packs/packages/components/tree/src/lib/tree.module.ts @@ -1,12 +1,18 @@ +import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { NzTreeModule } from 'ng-zorro-antd/tree'; import { TreeComponent } from './components/tree.component'; -import { CommonModule } from '@angular/common'; +import { TreeNodeTemplateDirective } from './templates/tree-node-template.directive'; +import { ExpandedIconTemplateDirective } from './templates/expanded-icon-template.directive'; + +const templates = [TreeNodeTemplateDirective, ExpandedIconTemplateDirective]; + +const exported = [...templates, TreeComponent]; @NgModule({ imports: [CommonModule, NzTreeModule, NgbDropdownModule], - exports: [TreeComponent], - declarations: [TreeComponent], + exports: [...exported], + declarations: [...exported], }) export class TreeModule {} diff --git a/npm/ng-packs/packages/components/tree/src/lib/utils/nz-tree-adapter.ts b/npm/ng-packs/packages/components/tree/src/lib/utils/nz-tree-adapter.ts index 5d042602e2..d5d32f0146 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/utils/nz-tree-adapter.ts +++ b/npm/ng-packs/packages/components/tree/src/lib/utils/nz-tree-adapter.ts @@ -41,17 +41,33 @@ export class TreeAdapter { return this.tree; } - handleDrop(node: TreeNode) { - const { key, parentNode } = node; + handleDrop({ key, parentNode }: TreeNode) { const index = this.list.findIndex(({ id }) => id === key); this.list[index].parentId = parentNode ? parentNode.key : null; this.tree = createTreeFromList(this.list); } - handleRemove(node: TreeNode) { - const { key, parentNode } = node; - this.list = this.list.filter(({ id, parentId }) => id !== key && parentId !== key); - this.tree = createTreeFromList(this.list); + handleRemove({ key }: TreeNode) { + this.updateTreeFromList(this.list.filter(item => item.id !== key)); + } + + handleUpdate({ key, children }: { key: string; children: T[] }) { + /** + * When we need to update a node with new children, first we need to remove any descendant nodes. + * If we remove immediate children and create a new tree, any other descendant nodes will be removed + * and we won't need to recursively remove sub children. + * Then, you simply add back the new children and create a new tree. + */ + const listWithDescendantNodesRemoved = this.updateTreeFromList( + this.list.filter(item => item.parentId !== key), + ); + this.updateTreeFromList(listWithDescendantNodesRemoved.concat(children)); + } + + updateTreeFromList(list: T[]) { + this.tree = createTreeFromList(list); + this.list = createListFromTree(this.tree); + return this.list; } } @@ -66,6 +82,7 @@ function createTreeFromList(list: T[]): TreeNode[] { const node = map.get(row.id); if (parentId) { const parent = map.get(parentId); + if (!parent) return; parent.children.push(node); parent.isLeaf = false; } else { diff --git a/npm/ng-packs/packages/components/tree/src/public-api.ts b/npm/ng-packs/packages/components/tree/src/public-api.ts index df82ac0f93..1f3dd48e00 100644 --- a/npm/ng-packs/packages/components/tree/src/public-api.ts +++ b/npm/ng-packs/packages/components/tree/src/public-api.ts @@ -1,3 +1,5 @@ export * from './lib/tree.module'; export * from './lib/components/tree.component'; export * from './lib/utils/nz-tree-adapter'; +export * from './lib/templates/tree-node-template.directive'; +export * from './lib/templates/expanded-icon-template.directive'; diff --git a/npm/ng-packs/packages/core/package.json b/npm/ng-packs/packages/core/package.json index 13a5835319..a4a22ec710 100644 --- a/npm/ng-packs/packages/core/package.json +++ b/npm/ng-packs/packages/core/package.json @@ -1,17 +1,17 @@ { "name": "@abp/ng.core", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/utils": "^3.1.0-rc.3", + "@abp/utils": "^3.1.2", "@angular/localize": "~10.0.10", - "@ngxs/router-plugin": "^3.6.2", - "@ngxs/storage-plugin": "^3.6.2", - "@ngxs/store": "^3.6.2", + "@ngxs/router-plugin": "^3.7.0", + "@ngxs/storage-plugin": "^3.7.0", + "@ngxs/store": "^3.7.0", "angular-oauth2-oidc": "^10.0.0", "just-clone": "^3.1.0", "just-compare": "^1.3.0", diff --git a/npm/ng-packs/packages/core/src/lib/actions/replaceable-components.actions.ts b/npm/ng-packs/packages/core/src/lib/actions/replaceable-components.actions.ts index 8df6a384ad..a800ab858a 100644 --- a/npm/ng-packs/packages/core/src/lib/actions/replaceable-components.actions.ts +++ b/npm/ng-packs/packages/core/src/lib/actions/replaceable-components.actions.ts @@ -1,7 +1,8 @@ import { ReplaceableComponents } from '../models/replaceable-components'; +// tslint:disable: max-line-length /** - * @see usage: https://github.com/abpframework/abp/pull/2522#issue-358333183 + * @deprecated To be deleted in v4.0. Use ReplaceableComponentsService instead. See the doc (https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement) */ export class AddReplaceableComponent { static readonly type = '[ReplaceableComponents] Add'; diff --git a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts index c47b3c02fd..3d6870f577 100644 --- a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts @@ -1,13 +1,12 @@ import { Component, Injector, Optional, SkipSelf, Type } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; -import { Store } from '@ngxs/store'; import { eLayoutType } from '../enums/common'; import { ABP } from '../models'; import { ReplaceableComponents } from '../models/replaceable-components'; import { LocalizationService } from '../services/localization.service'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; import { RoutesService } from '../services/routes.service'; import { SubscriptionService } from '../services/subscription.service'; -import { ReplaceableComponentsState } from '../states/replaceable-components.state'; import { findRoute, getRoutePath } from '../utils/route-utils'; import { TreeNode } from '../utils/tree-utils'; @@ -37,7 +36,7 @@ export class DynamicLayoutComponent { constructor( injector: Injector, private localizationService: LocalizationService, - private store: Store, + private replaceableComponents: ReplaceableComponentsService, private subscription: SubscriptionService, @Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent, ) { @@ -67,7 +66,7 @@ export class DynamicLayoutComponent { if (!expectedLayout) expectedLayout = eLayoutType.empty; const key = this.layouts.get(expectedLayout); - this.layout = this.getComponent(key).component; + this.layout = this.getComponent(key)?.component; } }); @@ -82,6 +81,6 @@ export class DynamicLayoutComponent { } private getComponent(key: string): ReplaceableComponents.ReplaceableComponent { - return this.store.selectSnapshot(ReplaceableComponentsState.getComponent(key)); + return this.replaceableComponents.get(key); } } diff --git a/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts b/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts index 04c596d398..6c0dabd511 100644 --- a/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts @@ -1,10 +1,9 @@ import { Component, OnInit, Type } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Store } from '@ngxs/store'; import { distinctUntilChanged } from 'rxjs/operators'; import { ReplaceableComponents } from '../models/replaceable-components'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; import { SubscriptionService } from '../services/subscription.service'; -import { ReplaceableComponentsState } from '../states/replaceable-components.state'; @Component({ selector: 'abp-replaceable-route-container', @@ -22,7 +21,7 @@ export class ReplaceableRouteContainerComponent implements OnInit { constructor( private route: ActivatedRoute, - private store: Store, + private replaceableComponents: ReplaceableComponentsService, private subscription: SubscriptionService, ) {} @@ -31,8 +30,8 @@ export class ReplaceableRouteContainerComponent implements OnInit { this.componentKey = (this.route.snapshot.data .replaceableComponent as ReplaceableComponents.RouteData).key; - const component$ = this.store - .select(ReplaceableComponentsState.getComponent(this.componentKey)) + const component$ = this.replaceableComponents + .get$(this.componentKey) .pipe(distinctUntilChanged()); this.subscription.addOne( diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index c74591d204..597e114d4a 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -43,9 +43,10 @@ import { coreOptionsFactory, CORE_OPTIONS } from './tokens/options.token'; import { noop } from './utils/common-utils'; import './utils/date-extensions'; import { getInitialData, localeInitializer } from './utils/initial-utils'; +import { oAuthStorage } from './strategies/auth-flow.strategy'; export function storageFactory(): OAuthStorage { - return localStorage; + return oAuthStorage; } /** diff --git a/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts index fd9051c64e..489d1afabc 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts @@ -10,15 +10,14 @@ import { Type, ViewContainerRef, } from '@angular/core'; -import { Store } from '@ngxs/store'; import compare from 'just-compare'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; import snq from 'snq'; import { ABP } from '../models/common'; import { ReplaceableComponents } from '../models/replaceable-components'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; import { SubscriptionService } from '../services/subscription.service'; -import { ReplaceableComponentsState } from '../states/replaceable-components.state'; @Directive({ selector: '[abpReplaceableTemplate]', providers: [SubscriptionService] }) export class ReplaceableTemplateDirective implements OnInit, OnChanges { @@ -45,7 +44,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges { private templateRef: TemplateRef, private cfRes: ComponentFactoryResolver, private vcRef: ViewContainerRef, - private store: Store, + private replaceableComponents: ReplaceableComponentsService, private subscription: SubscriptionService, ) { this.context = { @@ -58,8 +57,8 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges { } ngOnInit() { - const component$ = this.store - .select(ReplaceableComponentsState.getComponent(this.data.componentKey)) + const component$ = this.replaceableComponents + .get$(this.data.componentKey) .pipe( filter( (res = {} as ReplaceableComponents.ReplaceableComponent) => diff --git a/npm/ng-packs/packages/core/src/lib/models/config.ts b/npm/ng-packs/packages/core/src/lib/models/config.ts index be640a4dcf..cf4eb007c9 100644 --- a/npm/ng-packs/packages/core/src/lib/models/config.ts +++ b/npm/ng-packs/packages/core/src/lib/models/config.ts @@ -22,11 +22,12 @@ export namespace Config { logoUrl?: string; } - export interface ApiConfig { + export type ApiConfig = { [key: string]: string; - rootNamespace?: string; url: string; - } + } & Partial<{ + rootNamespace: string; + }>; export interface Apis { [key: string]: ApiConfig; diff --git a/npm/ng-packs/packages/core/src/lib/models/rest.ts b/npm/ng-packs/packages/core/src/lib/models/rest.ts index 2f0e175002..03d70161bc 100644 --- a/npm/ng-packs/packages/core/src/lib/models/rest.ts +++ b/npm/ng-packs/packages/core/src/lib/models/rest.ts @@ -34,7 +34,7 @@ export namespace Rest { [param: string]: any; }; reportProgress?: boolean; - responseType?: ResponseType; + responseType?: 'arraybuffer' | 'blob' | 'json' | 'text'; url: string; withCredentials?: boolean; } diff --git a/npm/ng-packs/packages/core/src/lib/models/utility.ts b/npm/ng-packs/packages/core/src/lib/models/utility.ts index e84ad15340..228cab0de3 100644 --- a/npm/ng-packs/packages/core/src/lib/models/utility.ts +++ b/npm/ng-packs/packages/core/src/lib/models/utility.ts @@ -1,4 +1,13 @@ import { TemplateRef, Type } from '@angular/core'; +export type DeepPartial = { + [P in keyof T]?: T[P] extends Serializable ? DeepPartial : T[P]; +}; + +type Serializable = Record< + string | number | symbol, + string | number | boolean | Record +>; + export type InferredInstanceOf = T extends Type ? U : never; export type InferredContextOf = T extends TemplateRef ? U : never; diff --git a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts index 027c284f52..dd7abf929e 100644 --- a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts @@ -49,6 +49,10 @@ export class ConfigStateService { return this.store.selectSnapshot(ConfigState.getLocalization(...args)); } + getLocalizationResource(...args: Parameters) { + return this.store.selectSnapshot(ConfigState.getLocalizationResource(...args)); + } + dispatchGetAppConfiguration() { return this.store.dispatch(new GetAppConfiguration()); } diff --git a/npm/ng-packs/packages/core/src/lib/services/index.ts b/npm/ng-packs/packages/core/src/lib/services/index.ts index c084fd4808..d3d13de20b 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -9,6 +9,7 @@ export * from './localization.service'; export * from './multi-tenancy.service'; export * from './profile-state.service'; export * from './profile.service'; +export * from './replaceable-components.service'; export * from './rest.service'; export * from './routes.service'; export * from './session-state.service'; diff --git a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts index 5b98afe0c3..dd64bd27ec 100644 --- a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts @@ -70,6 +70,10 @@ export class LocalizationService { return this.store.select(ConfigState.getLocalization(key, ...interpolateParams)); } + getResource(resourceName: string) { + return this.store.select(ConfigState.getLocalizationResource(resourceName)); + } + /** * Returns localized text with the given interpolation parameters in current language. * @param key Localization key to replace with localized text diff --git a/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts b/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts new file mode 100644 index 0000000000..674db83aea --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts @@ -0,0 +1,57 @@ +import { Injectable, NgZone } from '@angular/core'; +import { Router } from '@angular/router'; +import { ReplaceableComponents } from '../models/replaceable-components'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { noop } from '../utils/common-utils'; +import { map, filter } from 'rxjs/operators'; +import { InternalStore } from '../utils/internal-store-utils'; +import { reloadRoute } from '../utils/route-utils'; + +@Injectable({ providedIn: 'root' }) +export class ReplaceableComponentsService { + private store: InternalStore; + + get replaceableComponents$(): Observable { + return this.store.sliceState(state => state); + } + + get replaceableComponents(): ReplaceableComponents.ReplaceableComponent[] { + return this.store.state; + } + + get onUpdate$(): Observable { + return this.store.sliceUpdate(state => state); + } + + constructor(private ngZone: NgZone, private router: Router) { + this.store = new InternalStore([]); + } + + add(replaceableComponent: ReplaceableComponents.ReplaceableComponent, reload?: boolean): void { + const replaceableComponents = [...this.store.state]; + + const index = replaceableComponents.findIndex( + component => component.key === replaceableComponent.key, + ); + + if (index > -1) { + replaceableComponents[index] = replaceableComponent; + } else { + replaceableComponents.push(replaceableComponent); + } + + this.store.patch(replaceableComponents); + + if (reload) reloadRoute(this.router, this.ngZone); + } + + get(replaceableComponentKey: string): ReplaceableComponents.ReplaceableComponent { + return this.replaceableComponents.find(component => component.key === replaceableComponentKey); + } + + get$(replaceableComponentKey: string): Observable { + return this.replaceableComponents$.pipe( + map(components => components.find(component => component.key === replaceableComponentKey)), + ); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index c2b90a91c7..c19628760c 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -51,9 +51,16 @@ export abstract class AbstractTreeService { } private filterWith(setOrMap: Set | Map): T[] { - return this._flat$.value.filter( - item => !setOrMap.has(item[this.id]) && !setOrMap.has(item[this.parentId]), - ); + return this._flat$.value.filter(item => !setOrMap.has(item[this.id])); + } + + private findItemsToRemove(set: Set): Set { + return this._flat$.value.reduce((acc, item) => { + if (!acc.has(item[this.parentId])) return acc; + const childSet = new Set([item[this.id]]); + const children = this.findItemsToRemove(childSet); + return new Set([...acc, ...children]); + }, set); } private publish(flatItems: T[], visibleItems: T[]): T[] { @@ -104,7 +111,8 @@ export abstract class AbstractTreeService { const set = new Set(); identifiers.forEach(id => set.add(id)); - const flatItems = this.filterWith(set); + const setToRemove = this.findItemsToRemove(set); + const flatItems = this.filterWith(setToRemove); const visibleItems = flatItems.filter(item => !this.hide(item)); return this.publish(flatItems, visibleItems); @@ -133,8 +141,8 @@ export abstract class AbstractNavTreeService extends Abstract readonly parentId = 'parentName'; readonly hide = (item: T) => item.invisible || !this.isGranted(item); readonly sort = (a: T, b: T) => { - if (!a.order) return 1; - if (!b.order) return -1; + if (!Number.isInteger(a.order)) return 1; + if (!Number.isInteger(b.order)) return -1; return a.order - b.order; }; diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index 2aaf7a3bc2..8639981456 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -9,6 +9,7 @@ import { RestOccurError } from '../actions/rest.actions'; import { SetLanguage } from '../actions/session.actions'; import { ApplicationConfiguration } from '../models/application-configuration'; import { Config } from '../models/config'; +import { interpolate } from '../utils/string-utils'; import { SessionState } from './session.state'; @State({ @@ -127,6 +128,16 @@ export class ConfigState { return selector; } + static getLocalizationResource(resourceName: string) { + const selector = createSelector([ConfigState], (state: Config.State): { + [key: string]: string; + } => { + return state.localization.values[resourceName]; + }); + + return selector; + } + static getLocalization( key: string | Config.LocalizationWithDefault, ...interpolateParams: string[] @@ -180,14 +191,12 @@ export class ConfigState { return defaultValue || sourceKey; } + // [TODO]: next line should be removed in v3.2, breaking change!!! interpolateParams = interpolateParams.filter(params => params != null); - if (localization && interpolateParams && interpolateParams.length) { - interpolateParams.forEach(param => { - localization = localization.replace(/[\'\"]?\{[\d]+\}[\'\"]?/, param); - }); - } + if (localization) localization = interpolate(localization, interpolateParams); if (typeof localization !== 'string') localization = ''; + return localization || defaultValue || (key as string); }); diff --git a/npm/ng-packs/packages/core/src/lib/states/replaceable-components.state.ts b/npm/ng-packs/packages/core/src/lib/states/replaceable-components.state.ts index 82096c5472..8b861f144e 100644 --- a/npm/ng-packs/packages/core/src/lib/states/replaceable-components.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/replaceable-components.state.ts @@ -1,11 +1,23 @@ -import { Injectable, NgZone } from '@angular/core'; -import { Router } from '@angular/router'; +import { Injectable, isDevMode } from '@angular/core'; import { Action, createSelector, Selector, State, StateContext } from '@ngxs/store'; import snq from 'snq'; import { AddReplaceableComponent } from '../actions/replaceable-components.actions'; import { ReplaceableComponents } from '../models/replaceable-components'; -import { noop } from '../utils/common-utils'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; +function logDeprecationMsg() { + if (isDevMode()) { + console.warn(` + ReplacableComponentsState has been deprecated. Use ReplaceableComponentsService instead. + See the doc https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement + `); + } +} + +// tslint:disable: max-line-length +/** + * @deprecated To be deleted in v4.0. Use ReplaceableComponentsService instead. See the doc (https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement) + */ @State({ name: 'ReplaceableComponentsState', defaults: { replaceableComponents: [] } as ReplaceableComponents.State, @@ -16,6 +28,7 @@ export class ReplaceableComponentsState { static getAll({ replaceableComponents, }: ReplaceableComponents.State): ReplaceableComponents.ReplaceableComponent[] { + logDeprecationMsg(); return replaceableComponents || []; } @@ -23,6 +36,7 @@ export class ReplaceableComponentsState { const selector = createSelector( [ReplaceableComponentsState], (state: ReplaceableComponents.State): ReplaceableComponents.ReplaceableComponent => { + logDeprecationMsg(); return snq(() => state.replaceableComponents.find(component => component.key === key)); }, ); @@ -30,29 +44,15 @@ export class ReplaceableComponentsState { return selector; } - constructor(private ngZone: NgZone, private router: Router) {} - - // TODO: Create a shared service for route reload and more - private reloadRoute() { - const { shouldReuseRoute } = this.router.routeReuseStrategy; - const setRouteReuse = (reuse: typeof shouldReuseRoute) => { - this.router.routeReuseStrategy.shouldReuseRoute = reuse; - }; - - setRouteReuse(() => false); - this.router.navigated = false; - - this.ngZone.run(async () => { - await this.router.navigateByUrl(this.router.url).catch(noop); - setRouteReuse(shouldReuseRoute); - }); - } + constructor(private service: ReplaceableComponentsService) {} @Action(AddReplaceableComponent) replaceableComponentsAction( { getState, patchState }: StateContext, { payload, reload }: AddReplaceableComponent, ) { + logDeprecationMsg(); + let { replaceableComponents } = getState(); const index = snq( @@ -69,6 +69,6 @@ export class ReplaceableComponentsState { replaceableComponents, }); - if (reload) this.reloadRoute(); + this.service.add(payload, reload); } } diff --git a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts index 19fa4f509c..2c10ba4c99 100644 --- a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts +++ b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts @@ -1,7 +1,7 @@ import { Injector } from '@angular/core'; import { Router } from '@angular/router'; import { Store } from '@ngxs/store'; -import { AuthConfig, OAuthService } from 'angular-oauth2-oidc'; +import { AuthConfig, OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; import { Observable, of } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; import { GetAppConfiguration } from '../actions/config.actions'; @@ -9,6 +9,8 @@ import { RestOccurError } from '../actions/rest.actions'; import { RestService } from '../services/rest.service'; import { ConfigState } from '../states/config.state'; +export const oAuthStorage = localStorage; + export abstract class AuthFlowStrategy { abstract readonly isInternalAuth: boolean; @@ -25,10 +27,16 @@ export abstract class AuthFlowStrategy { constructor(protected injector: Injector) { this.store = injector.get(Store); this.oAuthService = injector.get(OAuthService); - this.oAuthConfig = injector.get(Store).selectSnapshot(ConfigState.getDeep('environment.oAuthConfig')); + this.oAuthConfig = this.store.selectSnapshot(ConfigState.getDeep('environment.oAuthConfig')); } async init(): Promise { + const shouldClear = shouldStorageClear( + this.store.selectSnapshot(ConfigState.getDeep('environment.oAuthConfig.clientId')), + oAuthStorage, + ); + if (shouldClear) clearOAuthStorage(oAuthStorage); + this.oAuthService.configure(this.oAuthConfig); return this.oAuthService.loadDiscoveryDocument().catch(this.catchError); } @@ -41,7 +49,14 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { return super .init() .then(() => this.oAuthService.tryLogin()) - .then(() => this.oAuthService.setupAutomaticSilentRefresh()); + .then(() => { + if (this.oAuthService.hasValidAccessToken() || !this.oAuthService.getRefreshToken()) { + return Promise.resolve(); + } + + return this.oAuthService.refreshToken() as Promise; + }) + .then(() => this.oAuthService.setupAutomaticSilentRefresh({}, 'access_token')); } login() { @@ -88,7 +103,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { ) .pipe( tap(() => this.oAuthService.logOut()), - switchMap(() => this.store.dispatch(new GetAppConfiguration())), + switchMap(() => this.store.dispatch(new GetAppConfiguration())), ); } @@ -103,3 +118,34 @@ export const AUTH_FLOW_STRATEGY = { return new AuthPasswordFlowStrategy(injector); }, }; + +function clearOAuthStorage(storage: OAuthStorage) { + const keys = [ + 'access_token', + 'id_token', + 'refresh_token', + 'nonce', + 'PKCE_verifier', + 'expires_at', + 'id_token_claims_obj', + 'id_token_expires_at', + 'id_token_stored_at', + 'access_token_stored_at', + 'granted_scopes', + 'session_state', + ]; + + keys.forEach(key => storage.removeItem(key)); +} + +function shouldStorageClear(clientId: string, storage: OAuthStorage): boolean { + const key = 'abpOAuthClientId'; + if (!storage.getItem(key)) { + storage.setItem(key, clientId); + return false; + } + + const shouldClear = storage.getItem(key) !== clientId; + if (shouldClear) storage.setItem(key, clientId); + return shouldClear; +} diff --git a/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts index 4d5f53a9ba..43ad6f87b1 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts @@ -7,7 +7,11 @@ import { NEVER } from 'rxjs'; import { DynamicLayoutComponent, RouterOutletComponent } from '../components'; import { eLayoutType } from '../enums/common'; import { ABP } from '../models'; -import { ApplicationConfigurationService, RoutesService } from '../services'; +import { + ApplicationConfigurationService, + RoutesService, + ReplaceableComponentsService, +} from '../services'; import { ReplaceableComponentsState } from '../states'; @Component({ @@ -78,33 +82,7 @@ const routes: ABP.Route[] = [ }, ]; -const storeData = { - ReplaceableComponentsState: { - replaceableComponents: [ - { - key: 'Theme.ApplicationLayoutComponent', - component: DummyApplicationLayoutComponent, - }, - { - key: 'Theme.AccountLayoutComponent', - component: DummyAccountLayoutComponent, - }, - { - key: 'Theme.EmptyLayoutComponent', - component: DummyEmptyLayoutComponent, - }, - ], - }, -}; - describe('DynamicLayoutComponent', () => { - const mockActions: Actions = NEVER; - const mockStore = ({ - selectSnapshot() { - return true; - }, - } as unknown) as Store; - const createComponent = createRoutingFactory({ component: RouterOutletComponent, stubsEnabled: false, @@ -113,10 +91,16 @@ describe('DynamicLayoutComponent', () => { providers: [ { provide: RoutesService, - useFactory: () => new RoutesService(mockActions, mockStore), + useFactory: () => + new RoutesService(NEVER, ({ + selectSnapshot() { + return true; + }, + } as unknown) as Store), }, + ReplaceableComponentsService, ], - imports: [RouterModule, DummyLayoutModule, NgxsModule.forRoot([ReplaceableComponentsState])], + imports: [RouterModule, DummyLayoutModule, NgxsModule.forRoot()], routes: [ { path: '', component: RouterOutletComponent }, { @@ -163,15 +147,26 @@ describe('DynamicLayoutComponent', () => { }); let spectator: SpectatorRouting; - let store: Store; + let replaceableComponents: ReplaceableComponentsService; beforeEach(async () => { spectator = createComponent(); - store = spectator.inject(Store); + replaceableComponents = spectator.inject(ReplaceableComponentsService); const routesService = spectator.inject(RoutesService); routesService.add(routes); - store.reset(storeData); + replaceableComponents.add({ + key: 'Theme.ApplicationLayoutComponent', + component: DummyApplicationLayoutComponent, + }); + replaceableComponents.add({ + key: 'Theme.AccountLayoutComponent', + component: DummyAccountLayoutComponent, + }); + replaceableComponents.add({ + key: 'Theme.EmptyLayoutComponent', + component: DummyEmptyLayoutComponent, + }); }); it('should handle application layout from parent abp route and display it', async () => { @@ -204,8 +199,8 @@ describe('DynamicLayoutComponent', () => { }); it('should not display any layout when layouts are empty', async () => { - store.reset({ ...storeData, ReplaceableComponentsState: {} }); - + const spy = jest.spyOn(replaceableComponents, 'get'); + spy.mockReturnValue(null); spectator.detectChanges(); spectator.router.navigateByUrl('/withoutLayout'); diff --git a/npm/ng-packs/packages/core/src/lib/tests/internal-store.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/internal-store.spec.ts new file mode 100644 index 0000000000..e0eed44eb6 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/internal-store.spec.ts @@ -0,0 +1,108 @@ +import clone from 'just-clone'; +import { take } from 'rxjs/operators'; +import { DeepPartial } from '../models'; +import { InternalStore } from '../utils'; + +const mockInitialState = { + foo: { + bar: { + baz: [() => {}], + qux: null as Promise, + }, + n: 0, + }, + x: '', + a: false, +}; + +type MockState = typeof mockInitialState; + +const patch1: DeepPartial = { foo: { bar: { baz: [() => {}] } } }; +const expected1: MockState = clone(mockInitialState); +expected1.foo.bar.baz = patch1.foo.bar.baz; + +const patch2: DeepPartial = { foo: { bar: { qux: Promise.resolve() } } }; +const expected2: MockState = clone(mockInitialState); +expected2.foo.bar.qux = patch2.foo.bar.qux; + +const patch3: DeepPartial = { foo: { n: 1 } }; +const expected3: MockState = clone(mockInitialState); +expected3.foo.n = patch3.foo.n; + +const patch4: DeepPartial = { x: 'X' }; +const expected4: MockState = clone(mockInitialState); +expected4.x = patch4.x; + +const patch5: DeepPartial = { a: true }; +const expected5: MockState = clone(mockInitialState); +expected5.a = patch5.a; + +describe('Internal Store', () => { + describe('sliceState', () => { + test.each` + selector | expected + ${(state: MockState) => state.a} | ${mockInitialState.a} + ${(state: MockState) => state.x} | ${mockInitialState.x} + ${(state: MockState) => state.foo.n} | ${mockInitialState.foo.n} + ${(state: MockState) => state.foo.bar} | ${mockInitialState.foo.bar} + ${(state: MockState) => state.foo.bar.baz} | ${mockInitialState.foo.bar.baz} + ${(state: MockState) => state.foo.bar.qux} | ${mockInitialState.foo.bar.qux} + `( + 'should return observable $expected when selector is $selector', + async ({ selector, expected }) => { + const store = new InternalStore(mockInitialState); + + const value = await store + .sliceState(selector) + .pipe(take(1)) + .toPromise(); + + expect(value).toEqual(expected); + }, + ); + }); + + describe('patchState', () => { + test.each` + patch | expected + ${patch1} | ${expected1} + ${patch2} | ${expected2} + ${patch3} | ${expected3} + ${patch4} | ${expected4} + ${patch5} | ${expected5} + `('should set state as $expected when patch is $patch', ({ patch, expected }) => { + const store = new InternalStore(mockInitialState); + + store.patch(patch); + + expect(store.state).toEqual(expected); + }); + }); + + describe('sliceUpdate', () => { + it('should return slice of update$ based on selector', done => { + const store = new InternalStore(mockInitialState); + + const onQux$ = store.sliceUpdate(state => state.foo.bar.qux); + + onQux$.pipe(take(1)).subscribe(value => { + expect(value).toEqual(patch2.foo.bar.qux); + done(); + }); + + store.patch(patch1); + store.patch(patch2); + }); + }); + + describe('reset', () => { + it('should reset state to initialState', () => { + const store = new InternalStore(mockInitialState); + + store.patch(patch1); + store.reset(); + + expect(store.state).toEqual(mockInitialState); + }); + }); +}); diff --git a/npm/ng-packs/packages/core/src/lib/tests/replaceable-route-container.component.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/replaceable-route-container.component.spec.ts index f5874bca46..9b8b62ef46 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/replaceable-route-container.component.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/replaceable-route-container.component.spec.ts @@ -1,10 +1,9 @@ -import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; import { Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { Store } from '@ngxs/store'; -import { of, Subject, BehaviorSubject } from 'rxjs'; +import { ActivatedRoute, Router } from '@angular/router'; +import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; +import { BehaviorSubject } from 'rxjs'; import { ReplaceableRouteContainerComponent } from '../components/replaceable-route-container.component'; -import { ReplaceableComponentsState } from '../states'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; @Component({ selector: 'abp-external-component', @@ -30,18 +29,18 @@ const activatedRouteMock = { }; describe('ReplaceableRouteContainerComponent', () => { - const selectResponse = new BehaviorSubject(undefined); - const mockSelect = jest.fn(() => selectResponse); - let spectator: SpectatorHost; + const get$Res = new BehaviorSubject(undefined); + const createHost = createHostFactory({ component: ReplaceableRouteContainerComponent, providers: [ { provide: ActivatedRoute, useValue: activatedRouteMock }, - { provide: Store, useValue: { select: mockSelect } }, + { provide: ReplaceableComponentsService, useValue: { get$: () => get$Res } }, ], declarations: [ExternalComponent, DefaultComponent], entryComponents: [DefaultComponent, ExternalComponent], + mocks: [Router], }); beforeEach(() => { @@ -55,11 +54,11 @@ describe('ReplaceableRouteContainerComponent', () => { }); it("should display the external component if it's available in store.", () => { - selectResponse.next({ component: ExternalComponent }); + get$Res.next({ component: ExternalComponent }); spectator.detectChanges(); expect(spectator.query('p')).toHaveText('external'); - selectResponse.next({ component: null }); + get$Res.next({ component: null }); spectator.detectChanges(); expect(spectator.query('p')).toHaveText('default'); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts index 613508f56b..2c1432e525 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts @@ -1,9 +1,11 @@ import { Component, EventEmitter, Inject, Input, OnInit, Optional, Output } from '@angular/core'; import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; import { Store } from '@ngxs/store'; -import { Subject } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { ReplaceableTemplateDirective } from '../directives'; import { ReplaceableComponents } from '../models'; +import { Router } from '@angular/router'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; @Component({ selector: 'abp-default-component', @@ -48,15 +50,15 @@ class ExternalComponent { } describe('ReplaceableTemplateDirective', () => { - const selectResponse = new Subject(); - const mockSelect = jest.fn(() => selectResponse); - let spectator: SpectatorDirective; + const get$Res = new BehaviorSubject(undefined); + const createDirective = createDirectiveFactory({ directive: ReplaceableTemplateDirective, - providers: [{ provide: Store, useValue: { select: mockSelect } }], declarations: [DefaultComponent, ExternalComponent], entryComponents: [ExternalComponent], + mocks: [Router], + providers: [{ provide: ReplaceableComponentsService, useValue: { get$: () => get$Res } }], }); describe('without external component', () => { @@ -72,7 +74,7 @@ describe('ReplaceableTemplateDirective', () => { `, { hostProps: { oneWay: { label: 'Test' }, twoWay: false, twoWayChange, someOutput } }, ); - selectResponse.next(undefined); + const component = spectator.query(DefaultComponent); spectator.directive.context.initTemplate(component); spectator.detectChanges(); @@ -114,7 +116,8 @@ describe('ReplaceableTemplateDirective', () => { `, { hostProps: { oneWay: { label: 'Test' }, twoWay: false, twoWayChange, someOutput } }, ); - selectResponse.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); + + get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); }); afterEach(() => twoWayChange.mockClear()); @@ -150,7 +153,7 @@ describe('ReplaceableTemplateDirective', () => { const externalComponent = spectator.query(ExternalComponent); spectator.setHostInput({ oneWay: 'test' }); externalComponent.data.inputs.twoWay = true; - selectResponse.next({ component: null, key: 'TestModule.TestComponent' }); + get$Res.next({ component: null, key: 'TestModule.TestComponent' }); spectator.detectChanges(); const component = spectator.query(DefaultComponent); spectator.directive.context.initTemplate(component); @@ -161,14 +164,14 @@ describe('ReplaceableTemplateDirective', () => { }); it('should reset default component subscriptions', () => { - selectResponse.next({ component: null, key: 'TestModule.TestComponent' }); + get$Res.next({ component: null, key: 'TestModule.TestComponent' }); const component = spectator.query(DefaultComponent); spectator.directive.context.initTemplate(component); spectator.detectChanges(); const unsubscribe = jest.fn(() => {}); spectator.directive.defaultComponentSubscriptions.twoWayChange.unsubscribe = unsubscribe; - selectResponse.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); + get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); expect(unsubscribe).toHaveBeenCalled(); }); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/routes.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/routes.service.spec.ts index aa5e51cb17..6b7ae3f50a 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/routes.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/routes.service.spec.ts @@ -10,6 +10,7 @@ describe('Routes Service', () => { { path: '/foo', name: 'foo' }, { path: '/foo/bar', name: 'bar', parentName: 'foo', invisible: true, order: 2 }, { path: '/foo/bar/baz', name: 'baz', parentName: 'bar', order: 1 }, + { path: '/foo/bar/baz/qux', name: 'qux', parentName: 'baz', order: 1 }, { path: '/foo/x', name: 'x', parentName: 'foo', order: 1 }, ]; @@ -32,11 +33,12 @@ describe('Routes Service', () => { const tree = await service.tree$.pipe(take(1)).toPromise(); const visible = await service.visible$.pipe(take(1)).toPromise(); - expect(flat.length).toBe(4); - expect(flat[3].name).toBe('foo'); + expect(flat.length).toBe(5); expect(flat[0].name).toBe('baz'); - expect(flat[1].name).toBe('x'); - expect(flat[2].name).toBe('bar'); + expect(flat[1].name).toBe('qux'); + expect(flat[2].name).toBe('x'); + expect(flat[3].name).toBe('bar'); + expect(flat[4].name).toBe('foo'); expect(tree.length).toBe(1); expect(tree[0].name).toBe('foo'); @@ -44,6 +46,7 @@ describe('Routes Service', () => { expect(tree[0].children[0].name).toBe('x'); expect(tree[0].children[1].name).toBe('bar'); expect(tree[0].children[1].children[0].name).toBe('baz'); + expect(tree[0].children[1].children[0].children[0].name).toBe('qux'); expect(visible.length).toBe(1); expect(visible[0].name).toBe('foo'); @@ -74,7 +77,8 @@ describe('Routes Service', () => { expect(service.hasChildren('foo')).toBe(true); expect(service.hasChildren('bar')).toBe(true); - expect(service.hasChildren('baz')).toBe(false); + expect(service.hasChildren('baz')).toBe(true); + expect(service.hasChildren('qux')).toBe(false); }); }); @@ -123,11 +127,12 @@ describe('Routes Service', () => { const tree = service.tree; const visible = service.visible; - expect(flat.length).toBe(4); - expect(flat[3].name).toBe('foo'); + expect(flat.length).toBe(5); expect(flat[0].name).toBe('baz'); - expect(flat[1].name).toBe('x'); - expect(flat[2].name).toBe('bar'); + expect(flat[1].name).toBe('qux'); + expect(flat[2].name).toBe('x'); + expect(flat[3].name).toBe('bar'); + expect(flat[4].name).toBe('foo'); expect(tree.length).toBe(1); expect(tree[0].name).toBe('foo'); @@ -135,6 +140,7 @@ describe('Routes Service', () => { expect(tree[0].children[0].name).toBe('x'); expect(tree[0].children[1].name).toBe('bar'); expect(tree[0].children[1].children[0].name).toBe('baz'); + expect(tree[0].children[1].children[0].children[0].name).toBe('qux'); expect(visible.length).toBe(1); expect(visible[0].name).toBe('foo'); diff --git a/npm/ng-packs/packages/core/src/lib/tests/string-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/string-utils.spec.ts index a0642e43ee..c2f7a3c601 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/string-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/string-utils.spec.ts @@ -1,4 +1,4 @@ -import { createTokenParser } from '../utils/string-utils'; +import { createTokenParser, interpolate } from '../utils/string-utils'; describe('String Utils', () => { describe('#createTokenParser', () => { @@ -19,4 +19,28 @@ describe('String Utils', () => { }, ); }); + + describe('#interpolate', () => { + test.each` + text | params | expected + ${'This is {0} and {1} example.'} | ${['foo', 'bar']} | ${'This is foo and bar example.'} + ${'This is {1} and {0} example.'} | ${['foo', 'bar']} | ${'This is bar and foo example.'} + ${'This is {0} and {0} example.'} | ${['foo', 'bar']} | ${'This is foo and foo example.'} + ${'This is {1} and {1} example.'} | ${['foo', 'bar']} | ${'This is bar and bar example.'} + ${'This is "{0}" and "{1}" example.'} | ${['foo', 'bar']} | ${'This is foo and bar example.'} + ${"This is '{1}' and '{0}' example."} | ${['foo', 'bar']} | ${'This is bar and foo example.'} + ${'This is { 0 } and {0} example.'} | ${['foo', 'bar']} | ${'This is foo and foo example.'} + ${'This is {1} and { 1 } example.'} | ${['foo', 'bar']} | ${'This is bar and bar example.'} + ${'This is {0}, {3}, {1}, and {2} example.'} | ${['foo', 'bar', 'baz', 'qux']} | ${'This is foo, qux, bar, and baz example.'} + ${'This is {0} with 0 example.'} | ${['foo']} | ${'This is foo with 0 example.'} + ${'This is {0} and {1} example.'} | ${['foo']} | ${'This is foo and {1} example.'} + ${'This is {0} and {1} example.'} | ${[]} | ${'This is {0} and {1} example.'} + ${'This is {0} example.'} | ${[null]} | ${'This is {0} example.'} + `( + 'should return $expected when text is $text and params are $params', + ({ text, params, expected }) => { + expect(interpolate(text, params)).toBe(expected); + }, + ); + }); }); diff --git a/npm/ng-packs/packages/core/src/lib/utils/file-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/file-utils.ts new file mode 100644 index 0000000000..b5241ec096 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/utils/file-utils.ts @@ -0,0 +1,20 @@ +export function downloadBlob(blob: Blob, filename: string) { + const blobUrl = URL.createObjectURL(blob); + + const link = document.createElement('a'); + + link.href = blobUrl; + link.download = filename; + + document.body.appendChild(link); + + link.dispatchEvent( + new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window, + }), + ); + + document.body.removeChild(link); +} diff --git a/npm/ng-packs/packages/core/src/lib/utils/index.ts b/npm/ng-packs/packages/core/src/lib/utils/index.ts index 383261fc07..2d7ef8eab4 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/index.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/index.ts @@ -3,9 +3,11 @@ export * from './common-utils'; export * from './date-utils'; export * from './environment-utils'; export * from './factory-utils'; +export * from './file-utils'; export * from './form-utils'; export * from './generator-utils'; export * from './initial-utils'; +export * from './internal-store-utils'; export * from './lazy-load-utils'; export * from './localization-utils'; export * from './multi-tenancy-utils'; diff --git a/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts new file mode 100644 index 0000000000..7a481121ee --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts @@ -0,0 +1,36 @@ +import compare from 'just-compare'; +import { BehaviorSubject, Subject } from 'rxjs'; +import { distinctUntilChanged, filter, map } from 'rxjs/operators'; +import { DeepPartial } from '../models'; +import { deepMerge } from './object-utils'; + +export class InternalStore { + private state$ = new BehaviorSubject(this.initialState); + + private update$ = new Subject>(); + + get state() { + return this.state$.value; + } + + sliceState = ( + selector: (state: State) => Slice, + compareFn: (s1: Slice, s2: Slice) => boolean = compare, + ) => this.state$.pipe(map(selector), distinctUntilChanged(compareFn)); + + sliceUpdate = ( + selector: (state: DeepPartial) => Slice, + filterFn = (x: Slice) => x !== undefined, + ) => this.update$.pipe(map(selector), filter(filterFn)); + + constructor(private initialState: State) {} + + patch(state: DeepPartial) { + this.state$.next(deepMerge(this.state, state)); + this.update$.next(state); + } + + reset() { + this.patch(this.initialState); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/utils/route-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/route-utils.ts index a749090695..388e76cbf8 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/route-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/route-utils.ts @@ -2,6 +2,8 @@ import { PRIMARY_OUTLET, Router, UrlSegmentGroup } from '@angular/router'; import { ABP } from '../models/common'; import { RoutesService } from '../services/routes.service'; import { TreeNode } from './tree-utils'; +import { noop } from './common-utils'; +import { NgZone } from '@angular/core'; export function findRoute(routes: RoutesService, path: string): TreeNode { const node = routes.find(route => route.path === path); @@ -23,3 +25,18 @@ export function getRoutePath(router: Router, url = router.url) { return '/' + (primaryGroup || emptyGroup).segments.map(({ path }) => path).join('/'); } + +export function reloadRoute(router: Router, ngZone: NgZone) { + const { shouldReuseRoute } = router.routeReuseStrategy; + const setRouteReuse = (reuse: typeof shouldReuseRoute) => { + router.routeReuseStrategy.shouldReuseRoute = reuse; + }; + + setRouteReuse(() => false); + router.navigated = false; + + ngZone.run(async () => { + await router.navigateByUrl(router.url).catch(noop); + setRouteReuse(shouldReuseRoute); + }); +} diff --git a/npm/ng-packs/packages/core/src/lib/utils/string-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/string-utils.ts index 00db697325..7404dceab7 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/string-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/string-utils.ts @@ -15,3 +15,9 @@ export function createTokenParser(format: string) { }, {} as Record); }; } + +export function interpolate(text: string, params: string[]) { + return text + .replace(/(['"]?\{\s*(\d+)\s*\}['"]?)/g, (_, match, digit) => params[digit] ?? match) + .replace(/\s+/g, ' '); +} diff --git a/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts index d4c0ba0ab3..ba6e3a5b90 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts @@ -1,7 +1,7 @@ export class BaseTreeNode { children: TreeNode[] = []; isLeaf = true; - parent: TreeNode; + parent?: TreeNode; constructor(props: T) { Object.assign(this, props); @@ -14,7 +14,7 @@ export class BaseTreeNode { export function createTreeFromList( list: T[], - keySelector: (item: T) => number | string | symbol, + keySelector: (item: T) => NodeKey, parentKeySelector: typeof keySelector, valueMapper: (item: T) => R, ) { @@ -26,6 +26,8 @@ export function createTreeFromList( const parentId = parentKeySelector(row); const node = map.get(id); + if (!node) return; + if (parentId) { const parent = map.get(parentId); if (!parent) return; @@ -42,7 +44,7 @@ export function createTreeFromList( export function createMapFromList( list: T[], - keySelector: (item: T) => number | string | symbol, + keySelector: (item: T) => NodeKey, valueMapper: (item: T) => R, ) { type Key = ReturnType; @@ -60,6 +62,8 @@ export type TreeNode = { parent?: TreeNode; }; +type NodeKey = number | string | symbol | undefined | null; + type NodeValue any> = F extends undefined ? TreeNode : ReturnType; diff --git a/npm/ng-packs/packages/feature-management/package.json b/npm/ng-packs/packages/feature-management/package.json index 1dd7f4f92a..cc1727b9c7 100644 --- a/npm/ng-packs/packages/feature-management/package.json +++ b/npm/ng-packs/packages/feature-management/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.feature-management", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "~3.1.0-rc.3", + "@abp/ng.theme.shared": "~3.1.2", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/feature-management/src/lib/actions/feature-management.actions.ts b/npm/ng-packs/packages/feature-management/src/lib/actions/feature-management.actions.ts index dee5da664a..65791be948 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/actions/feature-management.actions.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/actions/feature-management.actions.ts @@ -1,10 +1,16 @@ import { FeatureManagement } from '../models'; +/** + * @deprecated To be deleted in v4.0. + */ export class GetFeatures { static readonly type = '[FeatureManagement] Get Features'; constructor(public payload: FeatureManagement.Provider) {} } +/** + * @deprecated To be deleted in v4.0. + */ export class UpdateFeatures { static readonly type = '[FeatureManagement] Update Features'; constructor(public payload: FeatureManagement.Provider & FeatureManagement.Features) {} diff --git a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html index 6ee1766db7..f857487e1e 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html +++ b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html @@ -1,35 +1,110 @@ - +

{{ 'AbpFeatureManagement::Features' | abpLocalization }}

-
-
-
{{ feature.displayName }}
-
- -
-
- -
+
+
+
-
+ + + {{ description }} + + +
+ +
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
- +
- + - + {{ 'AbpFeatureManagement::Save' | abpLocalization }} diff --git a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts index cd4d00491b..7eca21ecbd 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts @@ -1,11 +1,20 @@ -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { GetFeatures, UpdateFeatures } from '../../actions'; +import { TrackByService } from '@abp/ng.core'; +import { LocaleDirection } from '@abp/ng.theme.shared'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { finalize } from 'rxjs/operators'; import { FeatureManagement } from '../../models/feature-management'; -import { FeatureManagementState } from '../../states'; -import { FormGroup, FormControl } from '@angular/forms'; -import { pluck, finalize } from 'rxjs/operators'; +import { FeaturesService } from '../../proxy/feature-management/features.service'; +import { + FeatureDto, + FeatureGroupDto, + UpdateFeatureDto, +} from '../../proxy/feature-management/models'; + +enum ValueTypes { + ToggleStringValueType = 'ToggleStringValueType', + FreeTextStringValueType = 'FreeTextStringValueType', + SelectionStringValueType = 'SelectionStringValueType', +} @Component({ selector: 'abp-feature-management', @@ -22,6 +31,16 @@ export class FeatureManagementComponent @Input() providerName: string; + selectedGroupDisplayName: string; + + groups: Pick[] = []; + + features: { + [group: string]: Array; + }; + + valueTypes = ValueTypes; + protected _visible; @Input() @@ -30,78 +49,82 @@ export class FeatureManagementComponent } set visible(value: boolean) { + if (this._visible === value) return; + this._visible = value; this.visibleChange.emit(value); - if (value) this.openModal(); } @Output() readonly visibleChange = new EventEmitter(); - @Select(FeatureManagementState.getFeatures) - features$: Observable; - modalBusy = false; - form: FormGroup; - - constructor(private store: Store) {} + constructor(public readonly track: TrackByService, private service: FeaturesService) {} openModal() { - if (!this.providerKey || !this.providerName) { - throw new Error('Provider Key and Provider Name are required.'); + if (!this.providerName) { + throw new Error('providerName is required.'); } this.getFeatures(); } getFeatures() { - this.store - .dispatch( - new GetFeatures({ - providerKey: this.providerKey, - providerName: this.providerName, + this.service.get(this.providerName, this.providerKey).subscribe(res => { + this.groups = res.groups.map(({ name, displayName }) => ({ name, displayName })); + this.selectedGroupDisplayName = this.groups[0].displayName; + this.features = res.groups.reduce( + (acc, val) => ({ + ...acc, + [val.name]: mapFeatures(val.features, document.body.dir as LocaleDirection), }), - ) - .pipe(pluck('FeatureManagementState', 'features')) - .subscribe(features => { - this.buildForm(features); - }); - } - - buildForm(features) { - const formGroupObj = {}; - - for (let i = 0; i < features.length; i++) { - formGroupObj[i] = new FormControl(features[i].value === 'false' ? null : features[i].value); - } - - this.form = new FormGroup(formGroupObj); + {}, + ); + }); } save() { if (this.modalBusy) return; - this.modalBusy = true; + const changedFeatures = [] as UpdateFeatureDto[]; - let features = this.store.selectSnapshot(FeatureManagementState.getFeatures); + Object.keys(this.features).forEach(key => { + this.features[key].forEach(feature => { + if (feature.value !== feature.initialValue) + changedFeatures.push({ name: feature.name, value: feature.value }); + }); + }); - features = features.map((feature, i) => ({ - ...feature, - value: this.form.value[i], - })); - - this.store - .dispatch( - new UpdateFeatures({ - providerKey: this.providerKey, - providerName: this.providerName, - features, - }), - ) + if (!changedFeatures.length) { + this.visible = false; + return; + } + + this.modalBusy = true; + this.service + .update(this.providerName, this.providerKey, { features: changedFeatures }) .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.visible = false; }); } } + +function mapFeatures(features: FeatureDto[], dir: LocaleDirection) { + const margin = `margin-${dir === 'rtl' ? 'right' : 'left'}.px`; + + return features.map(feature => { + const value = + feature.valueType?.name === ValueTypes.ToggleStringValueType + ? (feature.value || '').toLowerCase() === 'true' + : feature.value; + + return { + ...feature, + value, + initialValue: value, + style: { [margin]: feature.depth * 20 }, + }; + }); +} diff --git a/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts b/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts index ee3eca6d42..0a3d3b822e 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts @@ -4,10 +4,16 @@ import { NgModule } from '@angular/core'; import { FeatureManagementComponent } from './components/feature-management/feature-management.component'; import { NgxsModule } from '@ngxs/store'; import { FeatureManagementState } from './states/feature-management.state'; +import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ declarations: [FeatureManagementComponent], - imports: [CoreModule, ThemeSharedModule, NgxsModule.forFeature([FeatureManagementState])], + imports: [ + CoreModule, + ThemeSharedModule, + NgbNavModule, + NgxsModule.forFeature([FeatureManagementState]), + ], exports: [FeatureManagementComponent], }) export class FeatureManagementModule {} diff --git a/npm/ng-packs/packages/feature-management/src/lib/models/feature-management.ts b/npm/ng-packs/packages/feature-management/src/lib/models/feature-management.ts index 02f6f687e2..ef53e6d11c 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/models/feature-management.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/models/feature-management.ts @@ -1,16 +1,25 @@ import { EventEmitter } from '@angular/core'; export namespace FeatureManagement { + /** + * @deprecated To be deleted in v4.0. + */ export interface State { features: Feature[]; } + /** + * @deprecated To be deleted in v4.0. + */ export interface ValueType { name: string; properties: object; validator: object; } + /** + * @deprecated To be deleted in v4.0. + */ export interface Feature { name: string; displayName: string; @@ -21,10 +30,16 @@ export namespace FeatureManagement { parentName?: string; } + /** + * @deprecated To be deleted in v4.0. + */ export interface Features { features: Feature[]; } + /** + * @deprecated To be deleted in v4.0. + */ export interface Provider { providerName: string; providerKey: string; diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/README.md b/npm/ng-packs/packages/feature-management/src/lib/proxy/README.md new file mode 100644 index 0000000000..09967f7e3a --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/README.md @@ -0,0 +1,13 @@ +# Proxy Generation Output + +This directory includes the output of the latest proxy generation. +The files and folders in it will be overwritten when proxy generation is run again. +Therefore, please do not place your own content in this folder. + +In addition, `generate-proxy.json` works like a lock file. +It includes information used by the proxy generator, so please do not delete or modify it. + +Finally, the name of the files and folders should not be changed for two reasons: +- Proxy generator will keep creating them at those paths and you will have multiple copies of the same content. +- ABP Suite generates files which include imports from this folder. + diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/features.service.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/features.service.ts new file mode 100644 index 0000000000..c1ff025b1b --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/features.service.ts @@ -0,0 +1,29 @@ +import type { GetFeatureListResultDto, UpdateFeaturesDto } from './models'; +import { RestService } from '@abp/ng.core'; +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class FeaturesService { + apiName = 'AbpFeatureManagement'; + + get = (providerName: string, providerKey: string) => + this.restService.request({ + method: 'GET', + url: '/api/feature-management/features', + params: { providerName, providerKey }, + }, + { apiName: this.apiName }); + + update = (providerName: string, providerKey: string, input: UpdateFeaturesDto) => + this.restService.request({ + method: 'PUT', + url: '/api/feature-management/features', + params: { providerName, providerKey }, + body: input, + }, + { apiName: this.apiName }); + + constructor(private restService: RestService) {} +} diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/index.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/index.ts new file mode 100644 index 0000000000..8c604f9964 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/index.ts @@ -0,0 +1,2 @@ +export * from './features.service'; +export * from './models'; diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/models.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/models.ts new file mode 100644 index 0000000000..8ea2d73164 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/feature-management/models.ts @@ -0,0 +1,36 @@ +import type { IStringValueType } from '../validation/string-values/models'; + +export interface FeatureDto { + name: string; + displayName: string; + value: string; + provider: FeatureProviderDto; + description: string; + valueType: IStringValueType; + depth: number; + parentName: string; +} + +export interface FeatureGroupDto { + name: string; + displayName: string; + features: FeatureDto[]; +} + +export interface FeatureProviderDto { + name: string; + key: string; +} + +export interface GetFeatureListResultDto { + groups: FeatureGroupDto[]; +} + +export interface UpdateFeatureDto { + name: string; + value: string; +} + +export interface UpdateFeaturesDto { + features: UpdateFeatureDto[]; +} diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/generate-proxy.json b/npm/ng-packs/packages/feature-management/src/lib/proxy/generate-proxy.json new file mode 100644 index 0000000000..eb3fe8d564 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/generate-proxy.json @@ -0,0 +1,12142 @@ +{ + "generated": [ + "featureManagement" + ], + "modules": { + "leptonThemeManagement": { + "rootPath": "leptonThemeManagement", + "remoteServiceName": "LeptonThemeManagement", + "controllers": { + "Volo.Abp.LeptonTheme.LeptonThemeSettingsController": { + "controllerName": "LeptonThemeSettings", + "type": "Volo.Abp.LeptonTheme.LeptonThemeSettingsController", + "interfaces": [ + { + "type": "Volo.Abp.LeptonTheme.Management.ILeptonThemeSettingsAppService" + } + ], + "actions": { + "GetAsync": { + "uniqueName": "GetAsync", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/lepton-theme-management/settings", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.LeptonTheme.Management.LeptonThemeSettingsDto", + "typeSimple": "Volo.Abp.LeptonTheme.Management.LeptonThemeSettingsDto" + } + }, + "UpdateAsyncByInput": { + "uniqueName": "UpdateAsyncByInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/lepton-theme-management/settings", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.LeptonTheme.Management.UpdateLeptonThemeSettingsDto, Volo.Abp.LeptonTheme.Management.Application.Contracts", + "type": "Volo.Abp.LeptonTheme.Management.UpdateLeptonThemeSettingsDto", + "typeSimple": "Volo.Abp.LeptonTheme.Management.UpdateLeptonThemeSettingsDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.LeptonTheme.Management.UpdateLeptonThemeSettingsDto", + "typeSimple": "Volo.Abp.LeptonTheme.Management.UpdateLeptonThemeSettingsDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "saas": { + "rootPath": "saas", + "remoteServiceName": "SaasHost", + "controllers": { + "Volo.Saas.Host.EditionController": { + "controllerName": "Edition", + "type": "Volo.Saas.Host.EditionController", + "interfaces": [ + { + "type": "Volo.Saas.Host.IEditionAppService" + } + ], + "actions": { + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/saas/editions/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Saas.Host.Dtos.EditionDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionDto" + } + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/saas/editions", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Saas.Host.Dtos.GetEditionsInput, Volo.Saas.Host.Application.Contracts", + "type": "Volo.Saas.Host.Dtos.GetEditionsInput", + "typeSimple": "Volo.Saas.Host.Dtos.GetEditionsInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/saas/editions", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Saas.Host.Dtos.EditionCreateDto, Volo.Saas.Host.Application.Contracts", + "type": "Volo.Saas.Host.Dtos.EditionCreateDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Saas.Host.Dtos.EditionCreateDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionCreateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Saas.Host.Dtos.EditionDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/saas/editions/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Saas.Host.Dtos.EditionUpdateDto, Volo.Saas.Host.Application.Contracts", + "type": "Volo.Saas.Host.Dtos.EditionUpdateDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Saas.Host.Dtos.EditionUpdateDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionUpdateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Saas.Host.Dtos.EditionDto", + "typeSimple": "Volo.Saas.Host.Dtos.EditionDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/saas/editions/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetUsageStatistics": { + "uniqueName": "GetUsageStatistics", + "name": "GetUsageStatistics", + "httpMethod": "GET", + "url": "api/saas/editions/statistics/usage-statistic", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Saas.Host.GetEditionUsageStatisticsResult", + "typeSimple": "Volo.Saas.Host.GetEditionUsageStatisticsResult" + } + } + } + }, + "Volo.Saas.Host.TenantController": { + "controllerName": "Tenant", + "type": "Volo.Saas.Host.TenantController", + "interfaces": [ + { + "type": "Volo.Saas.Host.ITenantAppService" + } + ], + "actions": { + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/saas/tenants/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Saas.Host.Dtos.SaasTenantDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantDto" + } + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/saas/tenants", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Saas.Host.Dtos.GetTenantsInput, Volo.Saas.Host.Application.Contracts", + "type": "Volo.Saas.Host.Dtos.GetTenantsInput", + "typeSimple": "Volo.Saas.Host.Dtos.GetTenantsInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "GetEditionNames", + "type": "System.Boolean", + "typeSimple": "boolean", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/saas/tenants", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Saas.Host.Dtos.SaasTenantCreateDto, Volo.Saas.Host.Application.Contracts", + "type": "Volo.Saas.Host.Dtos.SaasTenantCreateDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Saas.Host.Dtos.SaasTenantCreateDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantCreateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Saas.Host.Dtos.SaasTenantDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/saas/tenants/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Saas.Host.Dtos.SaasTenantUpdateDto, Volo.Saas.Host.Application.Contracts", + "type": "Volo.Saas.Host.Dtos.SaasTenantUpdateDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Saas.Host.Dtos.SaasTenantUpdateDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantUpdateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Saas.Host.Dtos.SaasTenantDto", + "typeSimple": "Volo.Saas.Host.Dtos.SaasTenantDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/saas/tenants/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetDefaultConnectionStringAsyncById": { + "uniqueName": "GetDefaultConnectionStringAsyncById", + "name": "GetDefaultConnectionStringAsync", + "httpMethod": "GET", + "url": "api/saas/tenants/{id}/default-connection-string", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.String", + "typeSimple": "string" + } + }, + "UpdateDefaultConnectionStringAsyncByIdAndDefaultConnectionString": { + "uniqueName": "UpdateDefaultConnectionStringAsyncByIdAndDefaultConnectionString", + "name": "UpdateDefaultConnectionStringAsync", + "httpMethod": "PUT", + "url": "api/saas/tenants/{id}/default-connection-string", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "defaultConnectionString", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "defaultConnectionString", + "name": "defaultConnectionString", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "DeleteDefaultConnectionStringAsyncById": { + "uniqueName": "DeleteDefaultConnectionStringAsyncById", + "name": "DeleteDefaultConnectionStringAsync", + "httpMethod": "DELETE", + "url": "api/saas/tenants/{id}/default-connection-string", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "identity": { + "rootPath": "identity", + "remoteServiceName": "AbpIdentity", + "controllers": { + "Volo.Abp.Identity.IdentityClaimTypeController": { + "controllerName": "IdentityClaimType", + "type": "Volo.Abp.Identity.IdentityClaimTypeController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IIdentityClaimTypeAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity/claim-types", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetIdentityClaimTypesInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetIdentityClaimTypesInput", + "typeSimple": "Volo.Abp.Identity.GetIdentityClaimTypesInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/claim-types/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.ClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.ClaimTypeDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity/claim-types", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.CreateClaimTypeDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.CreateClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.CreateClaimTypeDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.CreateClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.CreateClaimTypeDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.ClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.ClaimTypeDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity/claim-types/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.UpdateClaimTypeDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.UpdateClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.UpdateClaimTypeDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.UpdateClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.UpdateClaimTypeDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.ClaimTypeDto", + "typeSimple": "Volo.Abp.Identity.ClaimTypeDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity/claim-types/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.Identity.IdentityRoleController": { + "controllerName": "IdentityRole", + "type": "Volo.Abp.Identity.IdentityRoleController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IIdentityRoleAppService" + } + ], + "actions": { + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/roles/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityRoleDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentityRoleCreateDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentityRoleCreateDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentityRoleCreateDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleCreateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityRoleDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity/roles/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentityRoleUpdateDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentityRoleUpdateDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentityRoleUpdateDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleUpdateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityRoleDto", + "typeSimple": "Volo.Abp.Identity.IdentityRoleDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity/roles/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetAllListAsync": { + "uniqueName": "GetAllListAsync", + "name": "GetAllListAsync", + "httpMethod": "GET", + "url": "api/identity/roles/all", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetIdentityRoleListInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetIdentityRoleListInput", + "typeSimple": "Volo.Abp.Identity.GetIdentityRoleListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "UpdateClaimsAsyncByIdAndInput": { + "uniqueName": "UpdateClaimsAsyncByIdAndInput", + "name": "UpdateClaimsAsync", + "httpMethod": "PUT", + "url": "api/identity/roles/{id}/claims", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.Identity.IdentityRoleClaimDto, Volo.Abp.Identity.Pro.Application.Contracts, Version=3.2.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.IdentityRoleClaimDto]", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.IdentityRoleClaimDto]", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetClaimsAsyncById": { + "uniqueName": "GetClaimsAsyncById", + "name": "GetClaimsAsync", + "httpMethod": "GET", + "url": "api/identity/roles/{id}/claims", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.IdentityRoleClaimDto]" + } + }, + "GetAllClaimTypesAsync": { + "uniqueName": "GetAllClaimTypesAsync", + "name": "GetAllClaimTypesAsync", + "httpMethod": "GET", + "url": "api/identity/roles/all-claim-types", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.ClaimTypeDto]" + } + } + } + }, + "Volo.Abp.Identity.IdentitySecurityLogController": { + "controllerName": "IdentitySecurityLog", + "type": "Volo.Abp.Identity.IdentitySecurityLogController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IIdentitySecurityLogAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity/security-logs", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetIdentitySecurityLogListInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetIdentitySecurityLogListInput", + "typeSimple": "Volo.Abp.Identity.GetIdentitySecurityLogListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "StartTime", + "type": "System.DateTime?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EndTime", + "type": "System.DateTime?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Identity", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Action", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "UserName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ClientId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/security-logs/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentitySecurityLogDto", + "typeSimple": "Volo.Abp.Identity.IdentitySecurityLogDto" + } + }, + "GetMyListAsyncByInput": { + "uniqueName": "GetMyListAsyncByInput", + "name": "GetMyListAsync", + "httpMethod": "GET", + "url": "api/identity/security-logs/my", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetIdentitySecurityLogListInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetIdentitySecurityLogListInput", + "typeSimple": "Volo.Abp.Identity.GetIdentitySecurityLogListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "StartTime", + "type": "System.DateTime?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EndTime", + "type": "System.DateTime?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Identity", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Action", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "UserName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ClientId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Query", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetMyAsyncById": { + "uniqueName": "GetMyAsyncById", + "name": "GetMyAsync", + "httpMethod": "GET", + "url": "api/identity/security-logs/my/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentitySecurityLogDto", + "typeSimple": "Volo.Abp.Identity.IdentitySecurityLogDto" + } + } + } + }, + "Volo.Abp.Identity.IdentitySettingsController": { + "controllerName": "IdentitySettings", + "type": "Volo.Abp.Identity.IdentitySettingsController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IIdentitySettingsAppService" + } + ], + "actions": { + "GetAsync": { + "uniqueName": "GetAsync", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/settings", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Identity.IdentitySettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentitySettingsDto" + } + }, + "UpdateAsyncByInput": { + "uniqueName": "UpdateAsyncByInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity/settings", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentitySettingsDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentitySettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentitySettingsDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentitySettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentitySettingsDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.Identity.IdentityUserController": { + "controllerName": "IdentityUser", + "type": "Volo.Abp.Identity.IdentityUserController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IIdentityUserAppService" + } + ], + "actions": { + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/users/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity/users", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetIdentityUsersInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetIdentityUsersInput", + "typeSimple": "Volo.Abp.Identity.GetIdentityUsersInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity/users", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentityUserCreateDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentityUserCreateDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentityUserCreateDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserCreateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity/users/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentityUserUpdateDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentityUserUpdateDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentityUserUpdateDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserUpdateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity/users/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetRolesAsyncById": { + "uniqueName": "GetRolesAsyncById", + "name": "GetRolesAsync", + "httpMethod": "GET", + "url": "api/identity/users/{id}/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetAssignableRolesAsync": { + "uniqueName": "GetAssignableRolesAsync", + "name": "GetAssignableRolesAsync", + "httpMethod": "GET", + "url": "api/identity/users/assignable-roles", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetAvailableOrganizationUnitsAsync": { + "uniqueName": "GetAvailableOrganizationUnitsAsync", + "name": "GetAvailableOrganizationUnitsAsync", + "httpMethod": "GET", + "url": "api/identity/users/available-organization-units", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetAllClaimTypesAsync": { + "uniqueName": "GetAllClaimTypesAsync", + "name": "GetAllClaimTypesAsync", + "httpMethod": "GET", + "url": "api/identity/users/all-claim-types", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.ClaimTypeDto]" + } + }, + "GetClaimsAsyncById": { + "uniqueName": "GetClaimsAsyncById", + "name": "GetClaimsAsync", + "httpMethod": "GET", + "url": "api/identity/users/{id}/claims", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.IdentityUserClaimDto]" + } + }, + "GetOrganizationUnitsAsyncById": { + "uniqueName": "GetOrganizationUnitsAsyncById", + "name": "GetOrganizationUnitsAsync", + "httpMethod": "GET", + "url": "api/identity/users/{id}/organization-units", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.OrganizationUnitDto]" + } + }, + "UpdateRolesAsyncByIdAndInput": { + "uniqueName": "UpdateRolesAsyncByIdAndInput", + "name": "UpdateRolesAsync", + "httpMethod": "PUT", + "url": "api/identity/users/{id}/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentityUserUpdateRolesDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentityUserUpdateRolesDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserUpdateRolesDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentityUserUpdateRolesDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserUpdateRolesDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "UpdateClaimsAsyncByIdAndInput": { + "uniqueName": "UpdateClaimsAsyncByIdAndInput", + "name": "UpdateClaimsAsync", + "httpMethod": "PUT", + "url": "api/identity/users/{id}/claims", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.Identity.IdentityUserClaimDto, Volo.Abp.Identity.Pro.Application.Contracts, Version=3.2.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.IdentityUserClaimDto]", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.Identity.IdentityUserClaimDto]", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "LockAsyncByIdAndLockoutDuration": { + "uniqueName": "LockAsyncByIdAndLockoutDuration", + "name": "LockAsync", + "httpMethod": "PUT", + "url": "api/identity/users/{id}/lock/{lockoutDuration}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "lockoutDuration", + "typeAsString": "System.Int32, System.Private.CoreLib", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "lockoutDuration", + "name": "lockoutDuration", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "UnlockAsyncById": { + "uniqueName": "UnlockAsyncById", + "name": "UnlockAsync", + "httpMethod": "PUT", + "url": "api/identity/users/{id}/unlock", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "FindByUsernameAsyncByUsername": { + "uniqueName": "FindByUsernameAsyncByUsername", + "name": "FindByUsernameAsync", + "httpMethod": "GET", + "url": "api/identity/users/by-username/{username}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "username", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "username", + "name": "username", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + "FindByEmailAsyncByEmail": { + "uniqueName": "FindByEmailAsyncByEmail", + "name": "FindByEmailAsync", + "httpMethod": "GET", + "url": "api/identity/users/by-email/{email}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "email", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "email", + "name": "email", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + "UpdatePasswordAsyncByIdAndInput": { + "uniqueName": "UpdatePasswordAsyncByIdAndInput", + "name": "UpdatePasswordAsync", + "httpMethod": "PUT", + "url": "api/identity/users/{id}/change-password", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.IdentityUserUpdatePasswordInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.IdentityUserUpdatePasswordInput", + "typeSimple": "Volo.Abp.Identity.IdentityUserUpdatePasswordInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.IdentityUserUpdatePasswordInput", + "typeSimple": "Volo.Abp.Identity.IdentityUserUpdatePasswordInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.Identity.IdentityUserLookupController": { + "controllerName": "IdentityUserLookup", + "type": "Volo.Abp.Identity.IdentityUserLookupController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IIdentityUserLookupAppService" + } + ], + "actions": { + "FindByIdAsyncById": { + "uniqueName": "FindByIdAsyncById", + "name": "FindByIdAsync", + "httpMethod": "GET", + "url": "api/identity/users/lookup/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Users.UserData", + "typeSimple": "Volo.Abp.Users.UserData" + } + }, + "FindByUserNameAsyncByUserName": { + "uniqueName": "FindByUserNameAsyncByUserName", + "name": "FindByUserNameAsync", + "httpMethod": "GET", + "url": "api/identity/users/lookup/by-username/{userName}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "userName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "userName", + "name": "userName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Users.UserData", + "typeSimple": "Volo.Abp.Users.UserData" + } + }, + "SearchAsyncByInput": { + "uniqueName": "SearchAsyncByInput", + "name": "SearchAsync", + "httpMethod": "GET", + "url": "api/identity/users/lookup/search", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.UserLookupSearchInputDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.UserLookupSearchInputDto", + "typeSimple": "Volo.Abp.Identity.UserLookupSearchInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetCountAsyncByInput": { + "uniqueName": "GetCountAsyncByInput", + "name": "GetCountAsync", + "httpMethod": "GET", + "url": "api/identity/users/lookup/count", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.UserLookupCountInputDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.UserLookupCountInputDto", + "typeSimple": "Volo.Abp.Identity.UserLookupCountInputDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "System.Int64", + "typeSimple": "number" + } + } + } + }, + "Volo.Abp.Identity.OrganizationUnitController": { + "controllerName": "OrganizationUnit", + "type": "Volo.Abp.Identity.OrganizationUnitController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IOrganizationUnitAppService" + } + ], + "actions": { + "AddRolesAsyncByIdAndInput": { + "uniqueName": "AddRolesAsyncByIdAndInput", + "name": "AddRolesAsync", + "httpMethod": "PUT", + "url": "api/identity/organization-units/{id}/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.OrganizationUnitRoleInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.OrganizationUnitRoleInput", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitRoleInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.OrganizationUnitRoleInput", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitRoleInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "AddMembersAsyncByIdAndInput": { + "uniqueName": "AddMembersAsyncByIdAndInput", + "name": "AddMembersAsync", + "httpMethod": "PUT", + "url": "api/identity/organization-units/{id}/members", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.OrganizationUnitUserInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.OrganizationUnitUserInput", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitUserInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.OrganizationUnitUserInput", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitUserInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity/organization-units", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.OrganizationUnitCreateDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.OrganizationUnitCreateDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitCreateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.OrganizationUnitCreateDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitCreateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.OrganizationUnitWithDetailsDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitWithDetailsDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity/organization-units", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/organization-units/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.OrganizationUnitWithDetailsDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitWithDetailsDto" + } + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity/organization-units", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetOrganizationUnitInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetOrganizationUnitInput", + "typeSimple": "Volo.Abp.Identity.GetOrganizationUnitInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetListAllAsync": { + "uniqueName": "GetListAllAsync", + "name": "GetListAllAsync", + "httpMethod": "GET", + "url": "api/identity/organization-units/all", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetRolesAsyncByIdAndInput": { + "uniqueName": "GetRolesAsyncByIdAndInput", + "name": "GetRolesAsync", + "httpMethod": "GET", + "url": "api/identity/organization-units/{id}/roles", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto, Volo.Abp.Ddd.Application.Contracts", + "type": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetMembersAsyncByIdAndInput": { + "uniqueName": "GetMembersAsyncByIdAndInput", + "name": "GetMembersAsync", + "httpMethod": "GET", + "url": "api/identity/organization-units/{id}/members", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.GetIdentityUsersInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.GetIdentityUsersInput", + "typeSimple": "Volo.Abp.Identity.GetIdentityUsersInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "MoveAsyncByIdAndInput": { + "uniqueName": "MoveAsyncByIdAndInput", + "name": "MoveAsync", + "httpMethod": "PUT", + "url": "api/identity/organization-units/{id}/move", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.OrganizationUnitMoveInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.OrganizationUnitMoveInput", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitMoveInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.OrganizationUnitMoveInput", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitMoveInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity/organization-units/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.OrganizationUnitUpdateDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.OrganizationUnitUpdateDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitUpdateDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.OrganizationUnitUpdateDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitUpdateDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.OrganizationUnitWithDetailsDto", + "typeSimple": "Volo.Abp.Identity.OrganizationUnitWithDetailsDto" + } + }, + "RemoveMemberAsyncByIdAndMemberId": { + "uniqueName": "RemoveMemberAsyncByIdAndMemberId", + "name": "RemoveMemberAsync", + "httpMethod": "DELETE", + "url": "api/identity/organization-units/{id}/members/{memberId}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "memberId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "memberId", + "name": "memberId", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "RemoveRoleAsyncByIdAndRoleId": { + "uniqueName": "RemoveRoleAsyncByIdAndRoleId", + "name": "RemoveRoleAsync", + "httpMethod": "DELETE", + "url": "api/identity/organization-units/{id}/roles/{roleId}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "roleId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "roleId", + "name": "roleId", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.Identity.ProfileController": { + "controllerName": "Profile", + "type": "Volo.Abp.Identity.ProfileController", + "interfaces": [ + { + "type": "Volo.Abp.Identity.IProfileAppService" + } + ], + "actions": { + "GetAsync": { + "uniqueName": "GetAsync", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity/my-profile", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Identity.ProfileDto", + "typeSimple": "Volo.Abp.Identity.ProfileDto" + } + }, + "UpdateAsyncByInput": { + "uniqueName": "UpdateAsyncByInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity/my-profile", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.UpdateProfileDto, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.UpdateProfileDto", + "typeSimple": "Volo.Abp.Identity.UpdateProfileDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.UpdateProfileDto", + "typeSimple": "Volo.Abp.Identity.UpdateProfileDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.ProfileDto", + "typeSimple": "Volo.Abp.Identity.ProfileDto" + } + }, + "ChangePasswordAsyncByInput": { + "uniqueName": "ChangePasswordAsyncByInput", + "name": "ChangePasswordAsync", + "httpMethod": "POST", + "url": "api/identity/my-profile/change-password", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Identity.ChangePasswordInput, Volo.Abp.Identity.Pro.Application.Contracts", + "type": "Volo.Abp.Identity.ChangePasswordInput", + "typeSimple": "Volo.Abp.Identity.ChangePasswordInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Identity.ChangePasswordInput", + "typeSimple": "Volo.Abp.Identity.ChangePasswordInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "accountAdmin": { + "rootPath": "accountAdmin", + "remoteServiceName": "AbpAccountAdmin", + "controllers": { + "Volo.Abp.Account.AccountSettingsController": { + "controllerName": "AccountSettings", + "type": "Volo.Abp.Account.AccountSettingsController", + "interfaces": [ + { + "type": "Volo.Abp.Account.IAccountSettingsAppService" + } + ], + "actions": { + "GetAsync": { + "uniqueName": "GetAsync", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/account-admin/settings", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Account.AccountSettingsDto", + "typeSimple": "Volo.Abp.Account.AccountSettingsDto" + } + }, + "UpdateAsyncByInput": { + "uniqueName": "UpdateAsyncByInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/account-admin/settings", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.AccountSettingsDto, Volo.Abp.Account.Pro.Admin.Application.Contracts", + "type": "Volo.Abp.Account.AccountSettingsDto", + "typeSimple": "Volo.Abp.Account.AccountSettingsDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.AccountSettingsDto", + "typeSimple": "Volo.Abp.Account.AccountSettingsDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetLdapAsync": { + "uniqueName": "GetLdapAsync", + "name": "GetLdapAsync", + "httpMethod": "GET", + "url": "api/account-admin/settings/ldap", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Account.AccountLdapSettingsDto", + "typeSimple": "Volo.Abp.Account.AccountLdapSettingsDto" + } + }, + "UpdateLdapAsyncByInput": { + "uniqueName": "UpdateLdapAsyncByInput", + "name": "UpdateLdapAsync", + "httpMethod": "PUT", + "url": "api/account-admin/settings/ldap", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.AccountLdapSettingsDto, Volo.Abp.Account.Pro.Admin.Application.Contracts", + "type": "Volo.Abp.Account.AccountLdapSettingsDto", + "typeSimple": "Volo.Abp.Account.AccountLdapSettingsDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.AccountLdapSettingsDto", + "typeSimple": "Volo.Abp.Account.AccountLdapSettingsDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "identityServer": { + "rootPath": "identityServer", + "remoteServiceName": "AbpIdentityServer", + "controllers": { + "Volo.Abp.IdentityServer.ApiResourcesController": { + "controllerName": "ApiResources", + "type": "Volo.Abp.IdentityServer.ApiResourcesController", + "interfaces": [ + { + "type": "Volo.Abp.IdentityServer.ApiResource.IApiResourceAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity-server/api-resources", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.ApiResource.Dtos.GetApiResourceListInput, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.GetApiResourceListInput", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.GetApiResourceListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAllListAsync": { + "uniqueName": "GetAllListAsync", + "name": "GetAllListAsync", + "httpMethod": "GET", + "url": "api/identity-server/api-resources/all", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto]" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity-server/api-resources/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity-server/api-resources", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.ApiResource.Dtos.CreateApiResourceDto, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.CreateApiResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.CreateApiResourceDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.CreateApiResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.CreateApiResourceDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity-server/api-resources/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.ApiResource.Dtos.UpdateApiResourceDto, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.UpdateApiResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.UpdateApiResourceDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.UpdateApiResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.UpdateApiResourceDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity-server/api-resources", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.IdentityServer.ClientsController": { + "controllerName": "Clients", + "type": "Volo.Abp.IdentityServer.ClientsController", + "interfaces": [ + { + "type": "Volo.Abp.IdentityServer.Client.IClientAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity-server/clients", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.Client.Dtos.GetClientListInput, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.Client.Dtos.GetClientListInput", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.GetClientListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity-server/clients/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity-server/clients", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.Client.Dtos.CreateClientDto, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.Client.Dtos.CreateClientDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.CreateClientDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.IdentityServer.Client.Dtos.CreateClientDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.CreateClientDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity-server/clients/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.Client.Dtos.UpdateClientDto, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.Client.Dtos.UpdateClientDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.UpdateClientDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.IdentityServer.Client.Dtos.UpdateClientDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.UpdateClientDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity-server/clients", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.IdentityServer.IdentityResourcesController": { + "controllerName": "IdentityResources", + "type": "Volo.Abp.IdentityServer.IdentityResourcesController", + "interfaces": [ + { + "type": "Volo.Abp.IdentityServer.IdentityResource.IIdentityResourceAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity-server/identity-resources", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.IdentityResource.Dtos.GetIdentityResourceListInput, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.GetIdentityResourceListInput", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.GetIdentityResourceListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAllListAsync": { + "uniqueName": "GetAllListAsync", + "name": "GetAllListAsync", + "httpMethod": "GET", + "url": "api/identity-server/identity-resources/all", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto]" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/identity-server/identity-resources/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/identity-server/identity-resources", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.IdentityResource.Dtos.CreateIdentityResourceDto, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.CreateIdentityResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.CreateIdentityResourceDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.CreateIdentityResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.CreateIdentityResourceDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/identity-server/identity-resources/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.IdentityServer.IdentityResource.Dtos.UpdateIdentityResourceDto, Volo.Abp.IdentityServer.Application.Contracts", + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.UpdateIdentityResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.UpdateIdentityResourceDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.UpdateIdentityResourceDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.UpdateIdentityResourceDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto", + "typeSimple": "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/identity-server/identity-resources", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "CreateStandardResourcesAsync": { + "uniqueName": "CreateStandardResourcesAsync", + "name": "CreateStandardResourcesAsync", + "httpMethod": "POST", + "url": "api/identity-server/identity-resources/create-standard-resources", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + }, + "Volo.Abp.IdentityServer.IdentityServerClaimTypesController": { + "controllerName": "IdentityServerClaimTypes", + "type": "Volo.Abp.IdentityServer.IdentityServerClaimTypesController", + "interfaces": [ + { + "type": "Volo.Abp.IdentityServer.ClaimType.IIdentityServerClaimTypeAppService" + } + ], + "actions": { + "GetListAsync": { + "uniqueName": "GetListAsync", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/identity-server/claim-types", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.IdentityServer.ClaimType.Dtos.IdentityClaimTypeDto]" + } + } + } + } + } + }, + "account": { + "rootPath": "account", + "remoteServiceName": "AbpAccountPublic", + "controllers": { + "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.AccountController": { + "controllerName": "Account", + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.AccountController", + "interfaces": [], + "actions": { + "LoginByLogin": { + "uniqueName": "LoginByLogin", + "name": "Login", + "httpMethod": "POST", + "url": "api/account/login", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "login", + "typeAsString": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo, Volo.Abp.Account.Pro.Public.Web", + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "login", + "name": "login", + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.AbpLoginResult", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.AbpLoginResult" + } + }, + "Logout": { + "uniqueName": "Logout", + "name": "Logout", + "httpMethod": "GET", + "url": "api/account/logout", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "CheckPasswordByLogin": { + "uniqueName": "CheckPasswordByLogin", + "name": "CheckPassword", + "httpMethod": "POST", + "url": "api/account/checkPassword", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "login", + "typeAsString": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo, Volo.Abp.Account.Pro.Public.Web", + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "login", + "name": "login", + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.AbpLoginResult", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.AbpLoginResult" + } + } + } + }, + "Volo.Abp.Account.AccountController": { + "controllerName": "Account", + "type": "Volo.Abp.Account.AccountController", + "interfaces": [ + { + "type": "Volo.Abp.Account.IAccountAppService" + } + ], + "actions": { + "RegisterAsyncByInput": { + "uniqueName": "RegisterAsyncByInput", + "name": "RegisterAsync", + "httpMethod": "POST", + "url": "api/account/register", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.RegisterDto, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.RegisterDto", + "typeSimple": "Volo.Abp.Account.RegisterDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.RegisterDto", + "typeSimple": "Volo.Abp.Account.RegisterDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Identity.IdentityUserDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserDto" + } + }, + "SendPasswordResetCodeAsyncByInput": { + "uniqueName": "SendPasswordResetCodeAsyncByInput", + "name": "SendPasswordResetCodeAsync", + "httpMethod": "POST", + "url": "api/account/send-password-reset-code", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.SendPasswordResetCodeDto, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.SendPasswordResetCodeDto", + "typeSimple": "Volo.Abp.Account.SendPasswordResetCodeDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.SendPasswordResetCodeDto", + "typeSimple": "Volo.Abp.Account.SendPasswordResetCodeDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "ResetPasswordAsyncByInput": { + "uniqueName": "ResetPasswordAsyncByInput", + "name": "ResetPasswordAsync", + "httpMethod": "POST", + "url": "api/account/reset-password", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.ResetPasswordDto, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.ResetPasswordDto", + "typeSimple": "Volo.Abp.Account.ResetPasswordDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.ResetPasswordDto", + "typeSimple": "Volo.Abp.Account.ResetPasswordDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "SendPhoneNumberConfirmationTokenAsync": { + "uniqueName": "SendPhoneNumberConfirmationTokenAsync", + "name": "SendPhoneNumberConfirmationTokenAsync", + "httpMethod": "POST", + "url": "api/account/send-phone-number-confirmation-token", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "SendEmailConfirmationTokenAsyncByInput": { + "uniqueName": "SendEmailConfirmationTokenAsyncByInput", + "name": "SendEmailConfirmationTokenAsync", + "httpMethod": "POST", + "url": "api/account/send-email-confirmation-token", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.SendEmailConfirmationTokenDto, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.SendEmailConfirmationTokenDto", + "typeSimple": "Volo.Abp.Account.SendEmailConfirmationTokenDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.SendEmailConfirmationTokenDto", + "typeSimple": "Volo.Abp.Account.SendEmailConfirmationTokenDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "ConfirmPhoneNumberAsyncByInput": { + "uniqueName": "ConfirmPhoneNumberAsyncByInput", + "name": "ConfirmPhoneNumberAsync", + "httpMethod": "POST", + "url": "api/account/confirm-phone-number", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.ConfirmPhoneNumberInput, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.ConfirmPhoneNumberInput", + "typeSimple": "Volo.Abp.Account.ConfirmPhoneNumberInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.ConfirmPhoneNumberInput", + "typeSimple": "Volo.Abp.Account.ConfirmPhoneNumberInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "ConfirmEmailAsyncByInput": { + "uniqueName": "ConfirmEmailAsyncByInput", + "name": "ConfirmEmailAsync", + "httpMethod": "POST", + "url": "api/account/confirm-email", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.ConfirmEmailInput, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.ConfirmEmailInput", + "typeSimple": "Volo.Abp.Account.ConfirmEmailInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.ConfirmEmailInput", + "typeSimple": "Volo.Abp.Account.ConfirmEmailInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "SetProfilePictureAsyncByInput": { + "uniqueName": "SetProfilePictureAsyncByInput", + "name": "SetProfilePictureAsync", + "httpMethod": "POST", + "url": "api/account/profile-picture", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.Account.ProfilePictureInput, Volo.Abp.Account.Pro.Public.Application.Contracts", + "type": "Volo.Abp.Account.ProfilePictureInput", + "typeSimple": "Volo.Abp.Account.ProfilePictureInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.Account.ProfilePictureInput", + "typeSimple": "Volo.Abp.Account.ProfilePictureInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetProfilePictureAsyncById": { + "uniqueName": "GetProfilePictureAsyncById", + "name": "GetProfilePictureAsync", + "httpMethod": "GET", + "url": "api/account/profile-picture/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Account.ProfilePictureSourceDto", + "typeSimple": "Volo.Abp.Account.ProfilePictureSourceDto" + } + }, + "UploadProfilePictureFileAsyncByImage": { + "uniqueName": "UploadProfilePictureFileAsyncByImage", + "name": "UploadProfilePictureFileAsync", + "httpMethod": "POST", + "url": "api/account/profile-picture-file", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "image", + "typeAsString": "Microsoft.AspNetCore.Http.IFormFile, Microsoft.AspNetCore.Http.Features", + "type": "Microsoft.AspNetCore.Http.IFormFile", + "typeSimple": "Microsoft.AspNetCore.Http.IFormFile", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "image", + "name": "image", + "type": "Microsoft.AspNetCore.Http.IFormFile", + "typeSimple": "Microsoft.AspNetCore.Http.IFormFile", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "FormFile", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Microsoft.AspNetCore.Mvc.IActionResult", + "typeSimple": "Microsoft.AspNetCore.Mvc.IActionResult" + } + }, + "GetProfilePictureFileAsyncById": { + "uniqueName": "GetProfilePictureFileAsyncById", + "name": "GetProfilePictureFileAsync", + "httpMethod": "GET", + "url": "api/account/profile-picture-file/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Microsoft.AspNetCore.Mvc.IActionResult", + "typeSimple": "Microsoft.AspNetCore.Mvc.IActionResult" + } + } + } + } + } + }, + "languageManagement": { + "rootPath": "languageManagement", + "remoteServiceName": "LanguageManagement", + "controllers": { + "Volo.Abp.LanguageManagement.LanguageController": { + "controllerName": "Language", + "type": "Volo.Abp.LanguageManagement.LanguageController", + "interfaces": [ + { + "type": "Volo.Abp.LanguageManagement.ILanguageAppService" + } + ], + "actions": { + "GetAllListAsync": { + "uniqueName": "GetAllListAsync", + "name": "GetAllListAsync", + "httpMethod": "GET", + "url": "api/language-management/languages/all", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/language-management/languages", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput, Volo.Abp.LanguageManagement.Application.Contracts", + "type": "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ResourceName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "BaseCultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "TargetCultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "GetOnlyEmptyValues", + "type": "System.Boolean", + "typeSimple": "boolean", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.ListResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/language-management/languages/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.LanguageManagement.Dto.LanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.LanguageDto" + } + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/language-management/languages", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.LanguageManagement.Dto.CreateLanguageDto, Volo.Abp.LanguageManagement.Application.Contracts", + "type": "Volo.Abp.LanguageManagement.Dto.CreateLanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.CreateLanguageDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.LanguageManagement.Dto.CreateLanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.CreateLanguageDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.LanguageManagement.Dto.LanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.LanguageDto" + } + }, + "UpdateAsyncByIdAndInput": { + "uniqueName": "UpdateAsyncByIdAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/language-management/languages/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.LanguageManagement.Dto.UpdateLanguageDto, Volo.Abp.LanguageManagement.Application.Contracts", + "type": "Volo.Abp.LanguageManagement.Dto.UpdateLanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.UpdateLanguageDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.LanguageManagement.Dto.UpdateLanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.UpdateLanguageDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.LanguageManagement.Dto.LanguageDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.LanguageDto" + } + }, + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/language-management/languages/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "SetAsDefaultAsyncById": { + "uniqueName": "SetAsDefaultAsyncById", + "name": "SetAsDefaultAsync", + "httpMethod": "PUT", + "url": "api/language-management/languages/{id}/set-as-default", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "GetResourcesAsync": { + "uniqueName": "GetResourcesAsync", + "name": "GetResourcesAsync", + "httpMethod": "GET", + "url": "api/language-management/languages/resources", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.LanguageManagement.Dto.LanguageResourceDto]" + } + }, + "GetCulturelistAsync": { + "uniqueName": "GetCulturelistAsync", + "name": "GetCulturelistAsync", + "httpMethod": "GET", + "url": "api/language-management/languages/culture-list", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.LanguageManagement.Dto.CultureInfoDto]" + } + } + } + }, + "Volo.Abp.LanguageManagement.LanguageTextController": { + "controllerName": "LanguageText", + "type": "Volo.Abp.LanguageManagement.LanguageTextController", + "interfaces": [ + { + "type": "Volo.Abp.LanguageManagement.ILanguageTextAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/language-management/language-texts", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput, Volo.Abp.LanguageManagement.Application.Contracts", + "type": "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ResourceName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "BaseCultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "TargetCultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "GetOnlyEmptyValues", + "type": "System.Boolean", + "typeSimple": "boolean", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAsyncByResourceNameAndCultureNameAndNameAndBaseCultureName": { + "uniqueName": "GetAsyncByResourceNameAndCultureNameAndNameAndBaseCultureName", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/language-management/language-texts/{resourceName}/{cultureName}/{name}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "cultureName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "baseCultureName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "cultureName", + "name": "cultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "name", + "name": "name", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "baseCultureName", + "name": "baseCultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.LanguageManagement.Dto.LanguageTextDto", + "typeSimple": "Volo.Abp.LanguageManagement.Dto.LanguageTextDto" + } + }, + "UpdateAsyncByResourceNameAndCultureNameAndNameAndValue": { + "uniqueName": "UpdateAsyncByResourceNameAndCultureNameAndNameAndValue", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/language-management/language-texts/{resourceName}/{cultureName}/{name}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "cultureName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "value", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "cultureName", + "name": "cultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "name", + "name": "name", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "value", + "name": "value", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "RestoreToDefaultAsyncByResourceNameAndCultureNameAndName": { + "uniqueName": "RestoreToDefaultAsyncByResourceNameAndCultureNameAndName", + "name": "RestoreToDefaultAsync", + "httpMethod": "PUT", + "url": "api/language-management/language-texts/{resourceName}/{cultureName}/{name}/restore", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "resourceName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "cultureName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "resourceName", + "name": "resourceName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "cultureName", + "name": "cultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + }, + { + "nameOnMethod": "name", + "name": "name", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "featureManagement": { + "rootPath": "featureManagement", + "remoteServiceName": "AbpFeatureManagement", + "controllers": { + "Volo.Abp.FeatureManagement.FeaturesController": { + "controllerName": "Features", + "type": "Volo.Abp.FeatureManagement.FeaturesController", + "interfaces": [ + { + "type": "Volo.Abp.FeatureManagement.IFeatureAppService" + } + ], + "actions": { + "GetAsyncByProviderNameAndProviderKey": { + "uniqueName": "GetAsyncByProviderNameAndProviderKey", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/feature-management/features", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "providerName", + "name": "providerName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerKey", + "name": "providerKey", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.FeatureManagement.GetFeatureListResultDto", + "typeSimple": "Volo.Abp.FeatureManagement.GetFeatureListResultDto" + } + }, + "UpdateAsyncByProviderNameAndProviderKeyAndInput": { + "uniqueName": "UpdateAsyncByProviderNameAndProviderKeyAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/feature-management/features", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.FeatureManagement.UpdateFeaturesDto, Volo.Abp.FeatureManagement.Application.Contracts", + "type": "Volo.Abp.FeatureManagement.UpdateFeaturesDto", + "typeSimple": "Volo.Abp.FeatureManagement.UpdateFeaturesDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "providerName", + "name": "providerName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerKey", + "name": "providerKey", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.FeatureManagement.UpdateFeaturesDto", + "typeSimple": "Volo.Abp.FeatureManagement.UpdateFeaturesDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "abp": { + "rootPath": "abp", + "remoteServiceName": "abp", + "controllers": { + "Pages.Abp.MultiTenancy.AbpTenantController": { + "controllerName": "AbpTenant", + "type": "Pages.Abp.MultiTenancy.AbpTenantController", + "interfaces": [ + { + "type": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.IAbpTenantAppService" + } + ], + "actions": { + "FindTenantByNameAsyncByName": { + "uniqueName": "FindTenantByNameAsyncByName", + "name": "FindTenantByNameAsync", + "httpMethod": "GET", + "url": "api/abp/multi-tenancy/tenants/by-name/{name}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "name", + "name": "name", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto" + } + }, + "FindTenantByIdAsyncById": { + "uniqueName": "FindTenantByIdAsyncById", + "name": "FindTenantByIdAsync", + "httpMethod": "GET", + "url": "api/abp/multi-tenancy/tenants/by-id/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto" + } + } + } + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController": { + "controllerName": "AbpApplicationConfiguration", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController", + "interfaces": [ + { + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.IAbpApplicationConfigurationAppService" + } + ], + "actions": { + "GetAsync": { + "uniqueName": "GetAsync", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/abp/application-configuration", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationConfigurationDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationConfigurationDto" + } + } + } + }, + "Volo.Abp.AspNetCore.Mvc.ApiExploring.AbpApiDefinitionController": { + "controllerName": "AbpApiDefinition", + "type": "Volo.Abp.AspNetCore.Mvc.ApiExploring.AbpApiDefinitionController", + "interfaces": [], + "actions": { + "GetByModel": { + "uniqueName": "GetByModel", + "name": "Get", + "httpMethod": "GET", + "url": "api/abp/api-definition", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "model", + "typeAsString": "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModelRequestDto, Volo.Abp.Http", + "type": "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModelRequestDto", + "typeSimple": "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModelRequestDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "model", + "name": "IncludeTypes", + "type": "System.Boolean", + "typeSimple": "boolean", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "model" + } + ], + "returnValue": { + "type": "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModel", + "typeSimple": "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModel" + } + } + } + } + } + }, + "textTemplateManagement": { + "rootPath": "textTemplateManagement", + "remoteServiceName": "TextTemplateManagement", + "controllers": { + "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateContentController": { + "controllerName": "TemplateContent", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateContentController", + "interfaces": [ + { + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.ITemplateContentAppService" + } + ], + "actions": { + "GetAsyncByInput": { + "uniqueName": "GetAsyncByInput", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/text-template-management/template-contents", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateContentInput, Volo.Abp.TextTemplateManagement.Application.Contracts", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateContentInput", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateContentInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "TemplateName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "CultureName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.TextTemplateContentDto", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.TextTemplateContentDto" + } + }, + "RestoreToDefaultAsyncByInput": { + "uniqueName": "RestoreToDefaultAsyncByInput", + "name": "RestoreToDefaultAsync", + "httpMethod": "PUT", + "url": "api/text-template-management/template-contents/restore-to-default", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.TextTemplateManagement.TextTemplates.RestoreTemplateContentInput, Volo.Abp.TextTemplateManagement.Application.Contracts", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.RestoreTemplateContentInput", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.RestoreTemplateContentInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.RestoreTemplateContentInput", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.RestoreTemplateContentInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + "UpdateAsyncByInput": { + "uniqueName": "UpdateAsyncByInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/text-template-management/template-contents", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.TextTemplateManagement.TextTemplates.UpdateTemplateContentInput, Volo.Abp.TextTemplateManagement.Application.Contracts", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.UpdateTemplateContentInput", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.UpdateTemplateContentInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.UpdateTemplateContentInput", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.UpdateTemplateContentInput", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.TextTemplateContentDto", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.TextTemplateContentDto" + } + } + } + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateDefinitionController": { + "controllerName": "TemplateDefinition", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateDefinitionController", + "interfaces": [ + { + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.ITemplateDefinitionAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/text-template-management/template-definitions", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateDefinitionListInput, Volo.Abp.TextTemplateManagement.Application.Contracts", + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateDefinitionListInput", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateDefinitionListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "FilterText", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAsyncByName": { + "uniqueName": "GetAsyncByName", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/text-template-management/template-definitions/{name}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "name", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "name", + "name": "name", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateDefinitionDto", + "typeSimple": "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateDefinitionDto" + } + } + } + } + } + }, + "permissionManagement": { + "rootPath": "permissionManagement", + "remoteServiceName": "AbpPermissionManagement", + "controllers": { + "Volo.Abp.PermissionManagement.PermissionsController": { + "controllerName": "Permissions", + "type": "Volo.Abp.PermissionManagement.PermissionsController", + "interfaces": [ + { + "type": "Volo.Abp.PermissionManagement.IPermissionAppService" + } + ], + "actions": { + "GetAsyncByProviderNameAndProviderKey": { + "uniqueName": "GetAsyncByProviderNameAndProviderKey", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/permission-management/permissions", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "providerName", + "name": "providerName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerKey", + "name": "providerKey", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.PermissionManagement.GetPermissionListResultDto", + "typeSimple": "Volo.Abp.PermissionManagement.GetPermissionListResultDto" + } + }, + "UpdateAsyncByProviderNameAndProviderKeyAndInput": { + "uniqueName": "UpdateAsyncByProviderNameAndProviderKeyAndInput", + "name": "UpdateAsync", + "httpMethod": "PUT", + "url": "api/permission-management/permissions", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "providerName", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "providerKey", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + }, + { + "name": "input", + "typeAsString": "Volo.Abp.PermissionManagement.UpdatePermissionsDto, Volo.Abp.PermissionManagement.Application.Contracts", + "type": "Volo.Abp.PermissionManagement.UpdatePermissionsDto", + "typeSimple": "Volo.Abp.PermissionManagement.UpdatePermissionsDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "providerName", + "name": "providerName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "providerKey", + "name": "providerKey", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + }, + { + "nameOnMethod": "input", + "name": "input", + "type": "Volo.Abp.PermissionManagement.UpdatePermissionsDto", + "typeSimple": "Volo.Abp.PermissionManagement.UpdatePermissionsDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + } + } + } + }, + "auditLogging": { + "rootPath": "auditLogging", + "remoteServiceName": "AbpAuditLogging", + "controllers": { + "Volo.Abp.AuditLogging.AuditLogsController": { + "controllerName": "AuditLogs", + "type": "Volo.Abp.AuditLogging.AuditLogsController", + "interfaces": [ + { + "type": "Volo.Abp.AuditLogging.IAuditLogsAppService" + } + ], + "actions": { + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.AuditLogging.GetAuditLogListDto, Volo.Abp.AuditLogging.Application.Contracts", + "type": "Volo.Abp.AuditLogging.GetAuditLogListDto", + "typeSimple": "Volo.Abp.AuditLogging.GetAuditLogListDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Url", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "UserName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "HttpMethod", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "HttpStatusCode", + "type": "System.Net.HttpStatusCode?", + "typeSimple": "System.Net.HttpStatusCode?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxExecutionDuration", + "type": "System.Int32?", + "typeSimple": "number?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MinExecutionDuration", + "type": "System.Int32?", + "typeSimple": "number?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "HasException", + "type": "System.Boolean?", + "typeSimple": "boolean?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.AuditLogging.AuditLogDto", + "typeSimple": "Volo.Abp.AuditLogging.AuditLogDto" + } + }, + "GetErrorRateAsyncByFilter": { + "uniqueName": "GetErrorRateAsyncByFilter", + "name": "GetErrorRateAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/statistics/error-rate", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "filter", + "typeAsString": "Volo.Abp.AuditLogging.GetErrorRateFilter, Volo.Abp.AuditLogging.Application.Contracts", + "type": "Volo.Abp.AuditLogging.GetErrorRateFilter", + "typeSimple": "Volo.Abp.AuditLogging.GetErrorRateFilter", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "filter", + "name": "StartDate", + "type": "System.DateTime", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "filter" + }, + { + "nameOnMethod": "filter", + "name": "EndDate", + "type": "System.DateTime", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "filter" + } + ], + "returnValue": { + "type": "Volo.Abp.AuditLogging.GetErrorRateOutput", + "typeSimple": "Volo.Abp.AuditLogging.GetErrorRateOutput" + } + }, + "GetAverageExecutionDurationPerDayAsyncByFilter": { + "uniqueName": "GetAverageExecutionDurationPerDayAsyncByFilter", + "name": "GetAverageExecutionDurationPerDayAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/statistics/average-execution-duration-per-day", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "filter", + "typeAsString": "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayInput, Volo.Abp.AuditLogging.Application.Contracts", + "type": "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayInput", + "typeSimple": "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "filter", + "name": "StartDate", + "type": "System.DateTime", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "filter" + }, + { + "nameOnMethod": "filter", + "name": "EndDate", + "type": "System.DateTime", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "filter" + } + ], + "returnValue": { + "type": "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayOutput", + "typeSimple": "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayOutput" + } + }, + "GetEntityChangesAsyncByInput": { + "uniqueName": "GetEntityChangesAsyncByInput", + "name": "GetEntityChangesAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/entity-changes", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.AuditLogging.GetEntityChangesDto, Volo.Abp.AuditLogging.Application.Contracts", + "type": "Volo.Abp.AuditLogging.GetEntityChangesDto", + "typeSimple": "Volo.Abp.AuditLogging.GetEntityChangesDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "AuditLogId", + "type": "System.Guid?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EntityChangeType", + "type": "Volo.Abp.Auditing.EntityChangeType?", + "typeSimple": "Volo.Abp.Auditing.EntityChangeType?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EntityId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EntityTypeFullName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "StartDate", + "type": "System.DateTime?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EndDate", + "type": "System.DateTime?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + "GetEntityChangesWithUsernameAsyncByInput": { + "uniqueName": "GetEntityChangesWithUsernameAsyncByInput", + "name": "GetEntityChangesWithUsernameAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/entity-changes-with-username", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "Volo.Abp.AuditLogging.EntityChangeFilter, Volo.Abp.AuditLogging.Application.Contracts", + "type": "Volo.Abp.AuditLogging.EntityChangeFilter", + "typeSimple": "Volo.Abp.AuditLogging.EntityChangeFilter", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "EntityId", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "EntityTypeFullName", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.Abp.AuditLogging.EntityChangeWithUsernameDto]" + } + }, + "GetEntityChangeWithUsernameAsyncByEntityChangeId": { + "uniqueName": "GetEntityChangeWithUsernameAsyncByEntityChangeId", + "name": "GetEntityChangeWithUsernameAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/entity-change-with-username/{entityChangeId}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "entityChangeId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "entityChangeId", + "name": "entityChangeId", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.AuditLogging.EntityChangeWithUsernameDto", + "typeSimple": "Volo.Abp.AuditLogging.EntityChangeWithUsernameDto" + } + }, + "GetEntityChangeAsyncByEntityChangeId": { + "uniqueName": "GetEntityChangeAsyncByEntityChangeId", + "name": "GetEntityChangeAsync", + "httpMethod": "GET", + "url": "api/audit-logging/audit-logs/entity-changes/{entityChangeId}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "entityChangeId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "entityChangeId", + "name": "entityChangeId", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.AuditLogging.EntityChangeDto", + "typeSimple": "Volo.Abp.AuditLogging.EntityChangeDto" + } + } + } + } + } + } + }, + "types": { + "Volo.Abp.Account.AccountSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsSelfRegistrationEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "EnableLocalLogin", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsRememberBrowserEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Account.AccountLdapSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "EnableLdapLogin", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "LdapServerHost", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LdapServerPort", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LdapBaseDc", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LdapUserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LdapPassword", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.UserLoginInfo": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserNameOrEmailAddress", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Password", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RememberMe", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "TenanId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.AbpLoginResult": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Result", + "type": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.LoginResultType", + "typeSimple": "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.LoginResultType" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.LoginResultType": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "Success", + "InvalidUserNameOrPassword", + "NotAllowed", + "LockedOut", + "RequiresTwoFactor" + ], + "enumValues": [ + 1, + 2, + 3, + 4, + 5 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.Account.RegisterDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EmailAddress", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Password", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "AppName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ReturnUrl", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ReturnUrlHash", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentityUserDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Surname", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EmailConfirmed", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "PhoneNumber", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumberConfirmed", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "TwoFactorEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "LockoutEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsLockedOut", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ConcurrencyStamp", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Application.Dtos.ExtensibleEntityDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "TKey" + ], + "properties": [ + { + "name": "Id", + "type": "TKey", + "typeSimple": "TKey" + } + ] + }, + "Volo.Abp.ObjectExtending.ExtensibleObject": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ExtraProperties", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + } + ] + }, + "Volo.Abp.Account.SendPasswordResetCodeDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "AppName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ReturnUrl", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ReturnUrlHash", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.ResetPasswordDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "ResetToken", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Password", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.SendEmailConfirmationTokenDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "AppName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ReturnUrl", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ReturnUrlHash", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.ConfirmPhoneNumberInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Token", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.ConfirmEmailInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Token", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Account.ProfilePictureInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Type", + "type": "Volo.Abp.Account.ProfilePictureType", + "typeSimple": "Volo.Abp.Account.ProfilePictureType" + }, + { + "name": "ImageContent", + "type": "[System.Byte]", + "typeSimple": "[number]" + } + ] + }, + "Volo.Abp.Account.ProfilePictureType": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "None", + "Gravatar", + "Image" + ], + "enumValues": [ + 0, + 1, + 2 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.Account.ProfilePictureSourceDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Type", + "type": "Volo.Abp.Account.ProfilePictureType", + "typeSimple": "Volo.Abp.Account.ProfilePictureType" + }, + { + "name": "Source", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FileContent", + "type": "[System.Byte]", + "typeSimple": "[number]" + } + ] + }, + "Microsoft.AspNetCore.Http.IFormFile": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ContentType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ContentDisposition", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Headers", + "type": "{System.String:[System.String]}", + "typeSimple": "{string:[string]}" + }, + { + "name": "Length", + "type": "System.Int64", + "typeSimple": "number" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FileName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Microsoft.AspNetCore.Mvc.IActionResult": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Success", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AuditLogging.GetAuditLogListDto": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Url", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "HttpMethod", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "HttpStatusCode", + "type": "System.Net.HttpStatusCode?", + "typeSimple": "System.Net.HttpStatusCode?" + }, + { + "name": "MaxExecutionDuration", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "MinExecutionDuration", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "HasException", + "type": "System.Boolean?", + "typeSimple": "boolean?" + } + ] + }, + "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto": { + "baseType": "Volo.Abp.Application.Dtos.PagedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Sorting", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Application.Dtos.PagedResultRequestDto": { + "baseType": "Volo.Abp.Application.Dtos.LimitedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "SkipCount", + "type": "System.Int32", + "typeSimple": "number" + } + ] + }, + "Volo.Abp.Application.Dtos.LimitedResultRequestDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DefaultMaxResultCount", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "MaxMaxResultCount", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "MaxResultCount", + "type": "System.Int32", + "typeSimple": "number" + } + ] + }, + "System.Nullable": { + "baseType": "System.ValueType", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "T" + ], + "properties": [ + { + "name": "HasValue", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Value", + "type": "T", + "typeSimple": "T" + } + ] + }, + "System.Net.HttpStatusCode": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "Continue", + "SwitchingProtocols", + "Processing", + "EarlyHints", + "OK", + "Created", + "Accepted", + "NonAuthoritativeInformation", + "NoContent", + "ResetContent", + "PartialContent", + "MultiStatus", + "AlreadyReported", + "IMUsed", + "MultipleChoices", + "Ambiguous", + "MovedPermanently", + "Moved", + "Found", + "Redirect", + "SeeOther", + "RedirectMethod", + "NotModified", + "UseProxy", + "Unused", + "TemporaryRedirect", + "RedirectKeepVerb", + "PermanentRedirect", + "BadRequest", + "Unauthorized", + "PaymentRequired", + "Forbidden", + "NotFound", + "MethodNotAllowed", + "NotAcceptable", + "ProxyAuthenticationRequired", + "RequestTimeout", + "Conflict", + "Gone", + "LengthRequired", + "PreconditionFailed", + "RequestEntityTooLarge", + "RequestUriTooLong", + "UnsupportedMediaType", + "RequestedRangeNotSatisfiable", + "ExpectationFailed", + "MisdirectedRequest", + "UnprocessableEntity", + "Locked", + "FailedDependency", + "UpgradeRequired", + "PreconditionRequired", + "TooManyRequests", + "RequestHeaderFieldsTooLarge", + "UnavailableForLegalReasons", + "InternalServerError", + "NotImplemented", + "BadGateway", + "ServiceUnavailable", + "GatewayTimeout", + "HttpVersionNotSupported", + "VariantAlsoNegotiates", + "InsufficientStorage", + "LoopDetected", + "NotExtended", + "NetworkAuthenticationRequired" + ], + "enumValues": [ + 100, + 101, + 102, + 103, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 300, + 301, + 301, + 302, + 302, + 303, + 303, + 304, + 305, + 306, + 307, + 307, + 308, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 421, + 422, + 423, + 424, + 426, + 428, + 429, + 431, + 451, + 500, + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 510, + 511 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.Application.Dtos.PagedResultDto": { + "baseType": "Volo.Abp.Application.Dtos.ListResultDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "T" + ], + "properties": [ + { + "name": "TotalCount", + "type": "System.Int64", + "typeSimple": "number" + } + ] + }, + "Volo.Abp.Application.Dtos.ListResultDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "T" + ], + "properties": [ + { + "name": "Items", + "type": "[T]", + "typeSimple": "[T]" + } + ] + }, + "Volo.Abp.AuditLogging.AuditLogDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "ImpersonatorUserId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "ImpersonatorTenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "ExecutionTime", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "ExecutionDuration", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "ClientIpAddress", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BrowserInfo", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "HttpMethod", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Url", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Exceptions", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Comments", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "HttpStatusCode", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EntityChanges", + "type": "[Volo.Abp.AuditLogging.EntityChangeDto]", + "typeSimple": "[Volo.Abp.AuditLogging.EntityChangeDto]" + }, + { + "name": "Actions", + "type": "[Volo.Abp.AuditLogging.AuditLogActionDto]", + "typeSimple": "[Volo.Abp.AuditLogging.AuditLogActionDto]" + } + ] + }, + "Volo.Abp.AuditLogging.EntityChangeDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "AuditLogId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "ChangeTime", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "ChangeType", + "type": "Volo.Abp.Auditing.EntityChangeType", + "typeSimple": "Volo.Abp.Auditing.EntityChangeType" + }, + { + "name": "EntityId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EntityTypeFullName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PropertyChanges", + "type": "[Volo.Abp.AuditLogging.EntityPropertyChangeDto]", + "typeSimple": "[Volo.Abp.AuditLogging.EntityPropertyChangeDto]" + } + ] + }, + "Volo.Abp.Auditing.EntityChangeType": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "Created", + "Updated", + "Deleted" + ], + "enumValues": [ + 0, + 1, + 2 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.AuditLogging.EntityPropertyChangeDto": { + "baseType": "Volo.Abp.Application.Dtos.EntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "EntityChangeId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "NewValue", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "OriginalValue", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PropertyName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PropertyTypeFullName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Application.Dtos.EntityDto": { + "baseType": "Volo.Abp.Application.Dtos.EntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "TKey" + ], + "properties": [ + { + "name": "Id", + "type": "TKey", + "typeSimple": "TKey" + } + ] + }, + "Volo.Abp.Application.Dtos.EntityDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Abp.AuditLogging.AuditLogActionDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "AuditLogId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "ServiceName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "MethodName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Parameters", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ExecutionTime", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "ExecutionDuration", + "type": "System.Int32", + "typeSimple": "number" + } + ] + }, + "Volo.Abp.AuditLogging.GetErrorRateFilter": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "StartDate", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "EndDate", + "type": "System.DateTime", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AuditLogging.GetErrorRateOutput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Data", + "type": "{System.String:System.Int64}", + "typeSimple": "{string:number}" + } + ] + }, + "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "StartDate", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "EndDate", + "type": "System.DateTime", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AuditLogging.GetAverageExecutionDurationPerDayOutput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Data", + "type": "{System.String:System.Double}", + "typeSimple": "{string:number}" + } + ] + }, + "Volo.Abp.AuditLogging.GetEntityChangesDto": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "AuditLogId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "EntityChangeType", + "type": "Volo.Abp.Auditing.EntityChangeType?", + "typeSimple": "Volo.Abp.Auditing.EntityChangeType?" + }, + { + "name": "EntityId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EntityTypeFullName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "StartDate", + "type": "System.DateTime?", + "typeSimple": "string?" + }, + { + "name": "EndDate", + "type": "System.DateTime?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.AuditLogging.EntityChangeFilter": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "EntityId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EntityTypeFullName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AuditLogging.EntityChangeWithUsernameDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "EntityChange", + "type": "Volo.Abp.AuditLogging.EntityChangeDto", + "typeSimple": "Volo.Abp.AuditLogging.EntityChangeDto" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.GetIdentityClaimTypesInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.ClaimTypeDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsStatic", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Regex", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RegexDescription", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ValueType", + "type": "Volo.Abp.Identity.IdentityClaimValueType", + "typeSimple": "Volo.Abp.Identity.IdentityClaimValueType" + }, + { + "name": "ValueTypeAsString", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentityClaimValueType": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "String", + "Int", + "Boolean", + "DateTime" + ], + "enumValues": [ + 0, + 1, + 2, + 3 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.Identity.CreateClaimTypeDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Regex", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RegexDescription", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ValueType", + "type": "Volo.Abp.Identity.IdentityClaimValueType", + "typeSimple": "Volo.Abp.Identity.IdentityClaimValueType" + } + ] + }, + "Volo.Abp.Identity.UpdateClaimTypeDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Regex", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RegexDescription", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ValueType", + "type": "Volo.Abp.Identity.IdentityClaimValueType", + "typeSimple": "Volo.Abp.Identity.IdentityClaimValueType" + } + ] + }, + "Volo.Abp.Identity.IdentityRoleDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsDefault", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsStatic", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsPublic", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ConcurrencyStamp", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentityRoleCreateDto": { + "baseType": "Volo.Abp.Identity.IdentityRoleCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Abp.Identity.IdentityRoleCreateOrUpdateDtoBase": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsDefault", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsPublic", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Identity.IdentityRoleUpdateDto": { + "baseType": "Volo.Abp.Identity.IdentityRoleCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ConcurrencyStamp", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.GetIdentityRoleListInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentityRoleClaimDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "RoleId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "ClaimType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClaimValue", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.GetIdentitySecurityLogListInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "StartTime", + "type": "System.DateTime?", + "typeSimple": "string?" + }, + { + "name": "EndTime", + "type": "System.DateTime?", + "typeSimple": "string?" + }, + { + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Identity", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Action", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentitySecurityLogDto": { + "baseType": "Volo.Abp.Application.Dtos.EntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "ApplicationName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Identity", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Action", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UserId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TenantName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CorrelationId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientIpAddress", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BrowserInfo", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CreationTime", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "ExtraProperties", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + } + ] + }, + "Volo.Abp.Identity.IdentitySettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Password", + "type": "Volo.Abp.Identity.IdentityPasswordSettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentityPasswordSettingsDto" + }, + { + "name": "Lockout", + "type": "Volo.Abp.Identity.IdentityLockoutSettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentityLockoutSettingsDto" + }, + { + "name": "SignIn", + "type": "Volo.Abp.Identity.IdentitySignInSettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentitySignInSettingsDto" + }, + { + "name": "User", + "type": "Volo.Abp.Identity.IdentityUserSettingsDto", + "typeSimple": "Volo.Abp.Identity.IdentityUserSettingsDto" + } + ] + }, + "Volo.Abp.Identity.IdentityPasswordSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "RequiredLength", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "RequiredUniqueChars", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "RequireNonAlphanumeric", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireLowercase", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireUppercase", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireDigit", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Identity.IdentityLockoutSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "AllowedForNewUsers", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "LockoutDuration", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "MaxFailedAccessAttempts", + "type": "System.Int32", + "typeSimple": "number" + } + ] + }, + "Volo.Abp.Identity.IdentitySignInSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "RequireConfirmedEmail", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "EnablePhoneNumberConfirmation", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireConfirmedPhoneNumber", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Identity.IdentityUserSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsUserNameUpdateEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsEmailUpdateEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Identity.GetIdentityUsersInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentityUserCreateDto": { + "baseType": "Volo.Abp.Identity.IdentityUserCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Password", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.IdentityUserCreateOrUpdateDtoBase": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Surname", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumber", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TwoFactorEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "LockoutEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RoleNames", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "OrganizationUnitIds", + "type": "[System.Guid]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.Identity.IdentityUserUpdateDto": { + "baseType": "Volo.Abp.Identity.IdentityUserCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ConcurrencyStamp", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitWithDetailsDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleFullAuditedEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ParentId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "Code", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Roles", + "type": "[Volo.Abp.Identity.IdentityRoleDto]", + "typeSimple": "[Volo.Abp.Identity.IdentityRoleDto]" + } + ] + }, + "Volo.Abp.Application.Dtos.ExtensibleFullAuditedEntityDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleAuditedEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "TPrimaryKey" + ], + "properties": [ + { + "name": "IsDeleted", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "DeleterId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "DeletionTime", + "type": "System.DateTime?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Application.Dtos.ExtensibleAuditedEntityDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleCreationAuditedEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "TPrimaryKey" + ], + "properties": [ + { + "name": "LastModificationTime", + "type": "System.DateTime?", + "typeSimple": "string?" + }, + { + "name": "LastModifierId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Application.Dtos.ExtensibleCreationAuditedEntityDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "TPrimaryKey" + ], + "properties": [ + { + "name": "CreationTime", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "CreatorId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Identity.IdentityUserClaimDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "ClaimType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClaimValue", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleFullAuditedEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ParentId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "Code", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Roles", + "type": "[Volo.Abp.Identity.OrganizationUnitRoleDto]", + "typeSimple": "[Volo.Abp.Identity.OrganizationUnitRoleDto]" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitRoleDto": { + "baseType": "Volo.Abp.Application.Dtos.CreationAuditedEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "OrganizationUnitId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "RoleId", + "type": "System.Guid", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Application.Dtos.CreationAuditedEntityDto": { + "baseType": "Volo.Abp.Application.Dtos.EntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "CreationTime", + "type": "System.DateTime", + "typeSimple": "string" + }, + { + "name": "CreatorId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Identity.IdentityUserUpdateRolesDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "RoleNames", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.Identity.IdentityUserUpdatePasswordInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "NewPassword", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Users.UserData": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Id", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Surname", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EmailConfirmed", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "PhoneNumber", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumberConfirmed", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Identity.UserLookupSearchInputDto": { + "baseType": "Volo.Abp.Application.Dtos.PagedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Sorting", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.UserLookupCountInputDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitRoleInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "RoleIds", + "type": "[System.Guid]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitUserInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserIds", + "type": "[System.Guid]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitCreateDto": { + "baseType": "Volo.Abp.Identity.OrganizationUnitCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ParentId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitCreateOrUpdateDtoBase": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.GetOrganizationUnitInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitMoveInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "NewParentId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.Identity.OrganizationUnitUpdateDto": { + "baseType": "Volo.Abp.Identity.OrganizationUnitCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Abp.Identity.ProfileDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EmailConfirmed", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Surname", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumber", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumberConfirmed", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsExternal", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "HasPassword", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Identity.UpdateProfileDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Surname", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumber", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Identity.ChangePasswordInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "CurrentPassword", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "NewPassword", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.GetApiResourceListInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceWithDetailsDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "UserClaims", + "type": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceClaimClaimDto]", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceClaimClaimDto]" + }, + { + "name": "Properties", + "type": "{System.String:System.String}", + "typeSimple": "{string:string}" + }, + { + "name": "Scopes", + "type": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeDto]", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeDto]" + }, + { + "name": "Secrets", + "type": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiSecretDto]", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiSecretDto]" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiResourceClaimClaimDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ApiResourceId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ApiResourceId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Emphasize", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ShowInDiscoveryDocument", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "UserClaims", + "type": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeClaimDto]", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeClaimDto]" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeClaimDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ApiResourceId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.ApiSecretDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ApiResourceId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Expiration", + "type": "System.DateTime?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.CreateApiResourceDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Claims", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.IdentityServer.ApiResource.Dtos.UpdateApiResourceDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Claims", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "Scopes", + "type": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeDto]", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiScopeDto]" + }, + { + "name": "Secrets", + "type": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiSecretDto]", + "typeSimple": "[Volo.Abp.IdentityServer.ApiResource.Dtos.ApiSecretDto]" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.GetClientListInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientWithDetailsDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LogoUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ProtocolType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RequireClientSecret", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireConsent", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowRememberConsent", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AlwaysIncludeUserClaimsInIdToken", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequirePkce", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowPlainTextPkce", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowAccessTokensViaBrowser", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "FrontChannelLogoutUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FrontChannelLogoutSessionRequired", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "BackChannelLogoutUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BackChannelLogoutSessionRequired", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowOfflineAccess", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IdentityTokenLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "AccessTokenLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "AuthorizationCodeLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "ConsentLifetime", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "AbsoluteRefreshTokenLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "SlidingRefreshTokenLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "RefreshTokenUsage", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "UpdateAccessTokenClaimsOnRefresh", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RefreshTokenExpiration", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "AccessTokenType", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "EnableLocalLogin", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IncludeJwtId", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AlwaysSendClientClaims", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ClientClaimsPrefix", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PairWiseSubjectSalt", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UserSsoLifetime", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "UserCodeType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DeviceCodeLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "ClientSecrets", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto]" + }, + { + "name": "AllowedScopes", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientScopeDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientScopeDto]" + }, + { + "name": "Claims", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientClaimDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientClaimDto]" + }, + { + "name": "AllowedGrantTypes", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientGrantTypeDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientGrantTypeDto]" + }, + { + "name": "IdentityProviderRestrictions", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientIdentityProviderRestrictionDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientIdentityProviderRestrictionDto]" + }, + { + "name": "Properties", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientPropertyDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientPropertyDto]" + }, + { + "name": "AllowedCorsOrigins", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientCorsOriginDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientCorsOriginDto]" + }, + { + "name": "RedirectUris", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientRedirectUriDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientRedirectUriDto]" + }, + { + "name": "PostLogoutRedirectUris", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientPostLogoutRedirectUriDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientPostLogoutRedirectUriDto]" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Expiration", + "type": "System.DateTime?", + "typeSimple": "string?" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientScopeDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Scope", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientClaimDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientGrantTypeDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "GrantType", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientIdentityProviderRestrictionDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Provider", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientPropertyDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Key", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientCorsOriginDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Origin", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientRedirectUriDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "RedirectUri", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.ClientPostLogoutRedirectUriDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "PostLogoutRedirectUri", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.CreateClientDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LogoUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RequireConsent", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "CallbackUrl", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LogoutUrl", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Secrets", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto]" + }, + { + "name": "Scopes", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.IdentityServer.Client.Dtos.UpdateClientDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ClientName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ClientUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LogoUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireConsent", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowOfflineAccess", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowRememberConsent", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequirePkce", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "RequireClientSecret", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AccessTokenLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "ConsentLifetime", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "AccessTokenType", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "EnableLocalLogin", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "FrontChannelLogoutUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FrontChannelLogoutSessionRequired", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "BackChannelLogoutUri", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BackChannelLogoutSessionRequired", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IncludeJwtId", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AlwaysSendClientClaims", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "PairWiseSubjectSalt", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UserSsoLifetime", + "type": "System.Int32?", + "typeSimple": "number?" + }, + { + "name": "UserCodeType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DeviceCodeLifetime", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "ClientSecrets", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientSecretDto]" + }, + { + "name": "Claims", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientClaimDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientClaimDto]" + }, + { + "name": "Properties", + "type": "[Volo.Abp.IdentityServer.Client.Dtos.ClientPropertyDto]", + "typeSimple": "[Volo.Abp.IdentityServer.Client.Dtos.ClientPropertyDto]" + }, + { + "name": "AllowedGrantTypes", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "IdentityProviderRestrictions", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "Scopes", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "AllowedCorsOrigins", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "RedirectUris", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "PostLogoutRedirectUris", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.IdentityServer.IdentityResource.Dtos.GetIdentityResourceListInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityResourceWithDetailsDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Emphasize", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ShowInDiscoveryDocument", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "UserClaims", + "type": "[Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityClaimDto]", + "typeSimple": "[Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityClaimDto]" + }, + { + "name": "Properties", + "type": "{System.String:System.String}", + "typeSimple": "{string:string}" + } + ] + }, + "Volo.Abp.IdentityServer.IdentityResource.Dtos.IdentityClaimDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IdentityResourceId", + "type": "System.Guid", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.IdentityServer.IdentityResource.Dtos.CreateIdentityResourceDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Emphasize", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ShowInDiscoveryDocument", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Claims", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.IdentityServer.IdentityResource.Dtos.UpdateIdentityResourceDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Enabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Required", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Emphasize", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "ShowInDiscoveryDocument", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Claims", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.IdentityServer.ClaimType.Dtos.IdentityClaimTypeDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.LanguageDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleCreationAuditedEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UiCultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FlagIcon", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "IsDefaultLanguage", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.GetLanguagesTextsInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ResourceName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BaseCultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TargetCultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "GetOnlyEmptyValues", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.CreateLanguageDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UiCultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FlagIcon", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.UpdateLanguageDto": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FlagIcon", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.LanguageResourceDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.CultureInfoDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.LanguageManagement.Dto.LanguageTextDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ResourceName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BaseCultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "BaseValue", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.LeptonTheme.Management.LeptonThemeSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "BoxedLayout", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "MenuPlacement", + "type": "Volo.Abp.LeptonTheme.Management.MenuPlacement", + "typeSimple": "Volo.Abp.LeptonTheme.Management.MenuPlacement" + }, + { + "name": "MenuStatus", + "type": "Volo.Abp.LeptonTheme.Management.MenuStatus", + "typeSimple": "Volo.Abp.LeptonTheme.Management.MenuStatus" + }, + { + "name": "Style", + "type": "Volo.Abp.LeptonTheme.Management.LeptonStyle", + "typeSimple": "Volo.Abp.LeptonTheme.Management.LeptonStyle" + } + ] + }, + "Volo.Abp.LeptonTheme.Management.MenuPlacement": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "Left", + "Top" + ], + "enumValues": [ + 0, + 1 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.LeptonTheme.Management.MenuStatus": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "AlwaysOpened", + "OpenOnHover" + ], + "enumValues": [ + 0, + 1 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.LeptonTheme.Management.LeptonStyle": { + "baseType": "System.Enum", + "isEnum": true, + "enumNames": [ + "Style1", + "Style2", + "Style3", + "Style4", + "Style5", + "Style6" + ], + "enumValues": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "genericArguments": null, + "properties": null + }, + "Volo.Abp.LeptonTheme.Management.UpdateLeptonThemeSettingsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "BoxedLayout", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "MenuPlacement", + "type": "Volo.Abp.LeptonTheme.Management.MenuPlacement", + "typeSimple": "Volo.Abp.LeptonTheme.Management.MenuPlacement" + }, + { + "name": "MenuStatus", + "type": "Volo.Abp.LeptonTheme.Management.MenuStatus", + "typeSimple": "Volo.Abp.LeptonTheme.Management.MenuStatus" + }, + { + "name": "Style", + "type": "Volo.Abp.LeptonTheme.Management.LeptonStyle", + "typeSimple": "Volo.Abp.LeptonTheme.Management.LeptonStyle" + } + ] + }, + "Volo.Abp.PermissionManagement.GetPermissionListResultDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "EntityDisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Groups", + "type": "[Volo.Abp.PermissionManagement.PermissionGroupDto]", + "typeSimple": "[Volo.Abp.PermissionManagement.PermissionGroupDto]" + } + ] + }, + "Volo.Abp.PermissionManagement.PermissionGroupDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Permissions", + "type": "[Volo.Abp.PermissionManagement.PermissionGrantInfoDto]", + "typeSimple": "[Volo.Abp.PermissionManagement.PermissionGrantInfoDto]" + } + ] + }, + "Volo.Abp.PermissionManagement.PermissionGrantInfoDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ParentName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsGranted", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "AllowedProviders", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "GrantedProviders", + "type": "[Volo.Abp.PermissionManagement.ProviderInfoDto]", + "typeSimple": "[Volo.Abp.PermissionManagement.ProviderInfoDto]" + } + ] + }, + "Volo.Abp.PermissionManagement.ProviderInfoDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ProviderName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ProviderKey", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.PermissionManagement.UpdatePermissionsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Permissions", + "type": "[Volo.Abp.PermissionManagement.UpdatePermissionDto]", + "typeSimple": "[Volo.Abp.PermissionManagement.UpdatePermissionDto]" + } + ] + }, + "Volo.Abp.PermissionManagement.UpdatePermissionDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsGranted", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateContentInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TemplateName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.TextTemplateContentDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Content", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.RestoreTemplateContentInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TemplateName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.UpdateTemplateContentInput": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TemplateName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Content", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.GetTemplateDefinitionListInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "FilterText", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.TextTemplateManagement.TextTemplates.TemplateDefinitionDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsLayout", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Layout", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsInlineLocalized", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "DefaultCultureName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Saas.Host.Dtos.EditionDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Saas.Host.Dtos.GetEditionsInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Saas.Host.Dtos.EditionCreateDto": { + "baseType": "Volo.Saas.Host.Dtos.EditionCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Saas.Host.Dtos.EditionCreateOrUpdateDtoBase": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Saas.Host.Dtos.EditionUpdateDto": { + "baseType": "Volo.Saas.Host.Dtos.EditionCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Saas.Host.GetEditionUsageStatisticsResult": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Data", + "type": "{System.String:System.Int32}", + "typeSimple": "{string:number}" + } + ] + }, + "Volo.Saas.Host.Dtos.SaasTenantDto": { + "baseType": "Volo.Abp.Application.Dtos.ExtensibleEntityDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EditionId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "EditionName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Saas.Host.Dtos.GetTenantsInput": { + "baseType": "Volo.Abp.Application.Dtos.PagedAndSortedResultRequestDto", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Filter", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "GetEditionNames", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Saas.Host.Dtos.SaasTenantCreateDto": { + "baseType": "Volo.Saas.Host.Dtos.SaasTenantCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "AdminEmailAddress", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "AdminPassword", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Saas.Host.Dtos.SaasTenantCreateOrUpdateDtoBase": { + "baseType": "Volo.Abp.ObjectExtending.ExtensibleObject", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EditionId", + "type": "System.Guid?", + "typeSimple": "string?" + } + ] + }, + "Volo.Saas.Host.Dtos.SaasTenantUpdateDto": { + "baseType": "Volo.Saas.Host.Dtos.SaasTenantCreateOrUpdateDtoBase", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Abp.FeatureManagement.GetFeatureListResultDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Groups", + "type": "[Volo.Abp.FeatureManagement.FeatureGroupDto]", + "typeSimple": "[Volo.Abp.FeatureManagement.FeatureGroupDto]" + } + ] + }, + "Volo.Abp.FeatureManagement.FeatureGroupDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Features", + "type": "[Volo.Abp.FeatureManagement.FeatureDto]", + "typeSimple": "[Volo.Abp.FeatureManagement.FeatureDto]" + } + ] + }, + "Volo.Abp.FeatureManagement.FeatureDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Provider", + "type": "Volo.Abp.FeatureManagement.FeatureProviderDto", + "typeSimple": "Volo.Abp.FeatureManagement.FeatureProviderDto" + }, + { + "name": "Description", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ValueType", + "type": "Volo.Abp.Validation.StringValues.IStringValueType", + "typeSimple": "Volo.Abp.Validation.StringValues.IStringValueType" + }, + { + "name": "Depth", + "type": "System.Int32", + "typeSimple": "number" + }, + { + "name": "ParentName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.FeatureManagement.FeatureProviderDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Key", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Validation.StringValues.IStringValueType": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Item", + "type": "System.Object", + "typeSimple": "object" + }, + { + "name": "Properties", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + }, + { + "name": "Validator", + "type": "Volo.Abp.Validation.StringValues.IValueValidator", + "typeSimple": "Volo.Abp.Validation.StringValues.IValueValidator" + } + ] + }, + "Volo.Abp.Validation.StringValues.IValueValidator": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Item", + "type": "System.Object", + "typeSimple": "object" + }, + { + "name": "Properties", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + } + ] + }, + "Volo.Abp.FeatureManagement.UpdateFeaturesDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Features", + "type": "[Volo.Abp.FeatureManagement.UpdateFeatureDto]", + "typeSimple": "[Volo.Abp.FeatureManagement.UpdateFeatureDto]" + } + ] + }, + "Volo.Abp.FeatureManagement.UpdateFeatureDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationConfigurationDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Localization", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationLocalizationConfigurationDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationLocalizationConfigurationDto" + }, + { + "name": "Auth", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationAuthConfigurationDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationAuthConfigurationDto" + }, + { + "name": "Setting", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationSettingConfigurationDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationSettingConfigurationDto" + }, + { + "name": "CurrentUser", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.CurrentUserDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.CurrentUserDto" + }, + { + "name": "Features", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationFeatureConfigurationDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationFeatureConfigurationDto" + }, + { + "name": "MultiTenancy", + "type": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.MultiTenancyInfoDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.MultiTenancyInfoDto" + }, + { + "name": "CurrentTenant", + "type": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.CurrentTenantDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.MultiTenancy.CurrentTenantDto" + }, + { + "name": "Timing", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.TimingDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.TimingDto" + }, + { + "name": "Clock", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClockDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClockDto" + }, + { + "name": "ObjectExtensions", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ObjectExtensionsDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ObjectExtensionsDto" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationLocalizationConfigurationDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Values", + "type": "{System.String:{System.String:System.String}}", + "typeSimple": "{string:{string:string}}" + }, + { + "name": "Languages", + "type": "[Volo.Abp.Localization.LanguageInfo]", + "typeSimple": "[Volo.Abp.Localization.LanguageInfo]" + }, + { + "name": "CurrentCulture", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.CurrentCultureDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.CurrentCultureDto" + }, + { + "name": "DefaultResourceName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LanguagesMap", + "type": "{System.String:[Volo.Abp.NameValue]}", + "typeSimple": "{string:[Volo.Abp.NameValue]}" + }, + { + "name": "LanguageFilesMap", + "type": "{System.String:[Volo.Abp.NameValue]}", + "typeSimple": "{string:[Volo.Abp.NameValue]}" + } + ] + }, + "Volo.Abp.Localization.LanguageInfo": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "UiCultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FlagIcon", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.CurrentCultureDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "DisplayName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EnglishName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ThreeLetterIsoLanguageName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TwoLetterIsoLanguageName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsRightToLeft", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "CultureName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "NativeName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DateTimeFormat", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.DateTimeFormatDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.DateTimeFormatDto" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.DateTimeFormatDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "CalendarAlgorithmType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DateTimeFormatLong", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ShortDatePattern", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "FullDateTimePattern", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DateSeparator", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "ShortTimePattern", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "LongTimePattern", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.NameValue": { + "baseType": "Volo.Abp.NameValue", + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [] + }, + "Volo.Abp.NameValue": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": [ + "T" + ], + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "T", + "typeSimple": "T" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationAuthConfigurationDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Policies", + "type": "{System.String:System.Boolean}", + "typeSimple": "{string:boolean}" + }, + { + "name": "GrantedPolicies", + "type": "{System.String:System.Boolean}", + "typeSimple": "{string:boolean}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationSettingConfigurationDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Values", + "type": "{System.String:System.String}", + "typeSimple": "{string:string}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.CurrentUserDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsAuthenticated", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Id", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "TenantId", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "UserName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "SurName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Email", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "EmailVerified", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "PhoneNumber", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "PhoneNumberVerified", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "Roles", + "type": "[System.String]", + "typeSimple": "[string]" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationFeatureConfigurationDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Values", + "type": "{System.String:System.String}", + "typeSimple": "{string:string}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.MultiTenancy.MultiTenancyInfoDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsEnabled", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.MultiTenancy.CurrentTenantDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Id", + "type": "System.Guid?", + "typeSimple": "string?" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsAvailable", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.TimingDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TimeZone", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.TimeZone", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.TimeZone" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.TimeZone": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Iana", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.IanaTimeZone", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.IanaTimeZone" + }, + { + "name": "Windows", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.WindowsTimeZone", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.WindowsTimeZone" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.IanaTimeZone": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TimeZoneName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.WindowsTimeZone": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TimeZoneId", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClockDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Kind", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ObjectExtensionsDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Modules", + "type": "{System.String:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ModuleExtensionDto}", + "typeSimple": "{string:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ModuleExtensionDto}" + }, + { + "name": "Enums", + "type": "{System.String:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionEnumDto}", + "typeSimple": "{string:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionEnumDto}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ModuleExtensionDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Entities", + "type": "{System.String:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.EntityExtensionDto}", + "typeSimple": "{string:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.EntityExtensionDto}" + }, + { + "name": "Configuration", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.EntityExtensionDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Properties", + "type": "{System.String:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyDto}", + "typeSimple": "{string:Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyDto}" + }, + { + "name": "Configuration", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TypeSimple", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DisplayName", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.LocalizableStringDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.LocalizableStringDto" + }, + { + "name": "Api", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiDto" + }, + { + "name": "Ui", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiDto" + }, + { + "name": "Attributes", + "type": "[Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyAttributeDto]", + "typeSimple": "[Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyAttributeDto]" + }, + { + "name": "Configuration", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + }, + { + "name": "DefaultValue", + "type": "System.Object", + "typeSimple": "object" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.LocalizableStringDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Resource", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "OnGet", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiGetDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiGetDto" + }, + { + "name": "OnCreate", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiCreateDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiCreateDto" + }, + { + "name": "OnUpdate", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiUpdateDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiUpdateDto" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiGetDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsAvailable", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiCreateDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsAvailable", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyApiUpdateDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsAvailable", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "OnTable", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiTableDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiTableDto" + }, + { + "name": "OnCreateForm", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiFormDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiFormDto" + }, + { + "name": "OnEditForm", + "type": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiFormDto", + "typeSimple": "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiFormDto" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiTableDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsVisible", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyUiFormDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IsVisible", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionPropertyAttributeDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "TypeSimple", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Config", + "type": "{System.String:System.Object}", + "typeSimple": "{string:object}" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionEnumDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Fields", + "type": "[Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionEnumFieldDto]", + "typeSimple": "[Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionEnumFieldDto]" + }, + { + "name": "LocalizationResource", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending.ExtensionEnumFieldDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Value", + "type": "System.Object", + "typeSimple": "object" + } + ] + }, + "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModelRequestDto": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "IncludeTypes", + "type": "System.Boolean", + "typeSimple": "boolean" + } + ] + }, + "Volo.Abp.Http.Modeling.ApplicationApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Modules", + "type": "{System.String:Volo.Abp.Http.Modeling.ModuleApiDescriptionModel}", + "typeSimple": "{string:Volo.Abp.Http.Modeling.ModuleApiDescriptionModel}" + }, + { + "name": "Types", + "type": "{System.String:Volo.Abp.Http.Modeling.TypeApiDescriptionModel}", + "typeSimple": "{string:Volo.Abp.Http.Modeling.TypeApiDescriptionModel}" + } + ] + }, + "Volo.Abp.Http.Modeling.ModuleApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "RootPath", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "RemoteServiceName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Controllers", + "type": "{System.String:Volo.Abp.Http.Modeling.ControllerApiDescriptionModel}", + "typeSimple": "{string:Volo.Abp.Http.Modeling.ControllerApiDescriptionModel}" + } + ] + }, + "Volo.Abp.Http.Modeling.ControllerApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "ControllerName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Interfaces", + "type": "[Volo.Abp.Http.Modeling.ControllerInterfaceApiDescriptionModel]", + "typeSimple": "[Volo.Abp.Http.Modeling.ControllerInterfaceApiDescriptionModel]" + }, + { + "name": "Actions", + "type": "{System.String:Volo.Abp.Http.Modeling.ActionApiDescriptionModel}", + "typeSimple": "{string:Volo.Abp.Http.Modeling.ActionApiDescriptionModel}" + } + ] + }, + "Volo.Abp.Http.Modeling.ControllerInterfaceApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Http.Modeling.ActionApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "UniqueName", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "HttpMethod", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Url", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "SupportedVersions", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "ParametersOnMethod", + "type": "[Volo.Abp.Http.Modeling.MethodParameterApiDescriptionModel]", + "typeSimple": "[Volo.Abp.Http.Modeling.MethodParameterApiDescriptionModel]" + }, + { + "name": "Parameters", + "type": "[Volo.Abp.Http.Modeling.ParameterApiDescriptionModel]", + "typeSimple": "[Volo.Abp.Http.Modeling.ParameterApiDescriptionModel]" + }, + { + "name": "ReturnValue", + "type": "Volo.Abp.Http.Modeling.ReturnValueApiDescriptionModel", + "typeSimple": "Volo.Abp.Http.Modeling.ReturnValueApiDescriptionModel" + } + ] + }, + "Volo.Abp.Http.Modeling.MethodParameterApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TypeAsString", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TypeSimple", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsOptional", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "DefaultValue", + "type": "System.Object", + "typeSimple": "object" + } + ] + }, + "Volo.Abp.Http.Modeling.ParameterApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "NameOnMethod", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TypeSimple", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsOptional", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "DefaultValue", + "type": "System.Object", + "typeSimple": "object" + }, + { + "name": "ConstraintTypes", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "BindingSourceId", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "DescriptorName", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Http.Modeling.ReturnValueApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TypeSimple", + "type": "System.String", + "typeSimple": "string" + } + ] + }, + "Volo.Abp.Http.Modeling.TypeApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "BaseType", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "IsEnum", + "type": "System.Boolean", + "typeSimple": "boolean" + }, + { + "name": "EnumNames", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "EnumValues", + "type": "[System.Object]", + "typeSimple": "[object]" + }, + { + "name": "GenericArguments", + "type": "[System.String]", + "typeSimple": "[string]" + }, + { + "name": "Properties", + "type": "[Volo.Abp.Http.Modeling.PropertyApiDescriptionModel]", + "typeSimple": "[Volo.Abp.Http.Modeling.PropertyApiDescriptionModel]" + } + ] + }, + "Volo.Abp.Http.Modeling.PropertyApiDescriptionModel": { + "baseType": null, + "isEnum": false, + "enumNames": null, + "enumValues": null, + "genericArguments": null, + "properties": [ + { + "name": "Name", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "Type", + "type": "System.String", + "typeSimple": "string" + }, + { + "name": "TypeSimple", + "type": "System.String", + "typeSimple": "string" + } + ] + } + } +} \ No newline at end of file diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/index.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/index.ts new file mode 100644 index 0000000000..68eb7e2964 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/index.ts @@ -0,0 +1,2 @@ +export * as FeatureManagement from './feature-management'; +export * as Validation from './validation'; diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/index.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/index.ts new file mode 100644 index 0000000000..bcd4535b81 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/index.ts @@ -0,0 +1 @@ +export * as StringValues from './string-values'; diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/string-values/index.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/string-values/index.ts new file mode 100644 index 0000000000..e9644dae47 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/string-values/index.ts @@ -0,0 +1 @@ +export * from './models'; diff --git a/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/string-values/models.ts b/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/string-values/models.ts new file mode 100644 index 0000000000..f4f9381611 --- /dev/null +++ b/npm/ng-packs/packages/feature-management/src/lib/proxy/validation/string-values/models.ts @@ -0,0 +1,13 @@ + +export interface IStringValueType { + name: string; + item: object; + properties: Record; + validator: IValueValidator; +} + +export interface IValueValidator { + name: string; + item: object; + properties: Record; +} diff --git a/npm/ng-packs/packages/feature-management/src/lib/services/feature-management-state.service.ts b/npm/ng-packs/packages/feature-management/src/lib/services/feature-management-state.service.ts index 79d7fbef34..20c76c41ae 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/services/feature-management-state.service.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/services/feature-management-state.service.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngxs/store'; -import { FeatureManagementState } from '../states'; -import { FeatureManagement } from '../models'; -import { GetFeatures, UpdateFeatures } from '../actions'; +import { GetFeatures, UpdateFeatures } from '../actions/feature-management.actions'; +import { FeatureManagementState } from '../states/feature-management.state'; @Injectable({ providedIn: 'root', diff --git a/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts b/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts index 4aabf7bf80..ad66f0946e 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/services/feature-management.service.ts @@ -7,6 +7,9 @@ import { FeatureManagement } from '../models'; @Injectable({ providedIn: 'root', }) +/** + * @deprecated Use FeaturesService instead. To be deleted in v4.0. + */ export class FeatureManagementService { apiName = 'FeatureManagement'; diff --git a/npm/ng-packs/packages/feature-management/src/lib/states/feature-management.state.ts b/npm/ng-packs/packages/feature-management/src/lib/states/feature-management.state.ts index 676918708c..4ea68704f2 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/states/feature-management.state.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/states/feature-management.state.ts @@ -5,6 +5,9 @@ import { FeatureManagement } from '../models/feature-management'; import { FeatureManagementService } from '../services/feature-management.service'; import { Injectable } from '@angular/core'; +/** + * @deprecated To be deleted in v4.0. + */ @State({ name: 'FeatureManagementState', defaults: { features: {} } as FeatureManagement.State, @@ -21,7 +24,7 @@ export class FeatureManagementState { @Action(GetFeatures) getFeatures({ patchState }: StateContext, { payload }: GetFeatures) { return this.featureManagementService.getFeatures(payload).pipe( - tap(({ features }) => + tap(({ features = [] }) => patchState({ features, }), diff --git a/npm/ng-packs/packages/feature-management/src/public-api.ts b/npm/ng-packs/packages/feature-management/src/public-api.ts index 382e9ed884..1d9ef938b8 100644 --- a/npm/ng-packs/packages/feature-management/src/public-api.ts +++ b/npm/ng-packs/packages/feature-management/src/public-api.ts @@ -1,3 +1,5 @@ export * from './lib/feature-management.module'; export * from './lib/components'; export * from './lib/enums/components'; +export * from './lib/proxy/feature-management'; +export * from './lib/proxy/validation/string-values'; diff --git a/npm/ng-packs/packages/feature-management/tslint.json b/npm/ng-packs/packages/feature-management/tslint.json index 8c3919ea62..081ce1077e 100644 --- a/npm/ng-packs/packages/feature-management/tslint.json +++ b/npm/ng-packs/packages/feature-management/tslint.json @@ -1,17 +1,8 @@ { "extends": "../../tslint.json", "rules": { - "directive-selector": [ - true, - "attribute", - "abp", - "camelCase" - ], - "component-selector": [ - true, - "element", - "abp", - "kebab-case" - ] + "interface-name": false, + "directive-selector": [true, "attribute", "abp", "camelCase"], + "component-selector": [true, "element", "abp", "kebab-case"] } } diff --git a/npm/ng-packs/packages/identity/package.json b/npm/ng-packs/packages/identity/package.json index 77586f3536..0aaecc1eac 100644 --- a/npm/ng-packs/packages/identity/package.json +++ b/npm/ng-packs/packages/identity/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.identity", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.permission-management": "~3.1.0-rc.3", - "@abp/ng.theme.shared": "~3.1.0-rc.3", + "@abp/ng.permission-management": "~3.1.2", + "@abp/ng.theme.shared": "~3.1.2", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html index 802e272dce..85986e20bb 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html @@ -63,10 +63,17 @@
- + + + {{ row.name }} + {{ + 'AbpIdentity::DisplayName:IsDefault' | abpLocalization + }} + {{ + 'AbpIdentity::DisplayName:IsPublic' | abpLocalization + }} + +
diff --git a/npm/ng-packs/packages/permission-management/package.json b/npm/ng-packs/packages/permission-management/package.json index 42d7f8ef9b..141b86ec57 100644 --- a/npm/ng-packs/packages/permission-management/package.json +++ b/npm/ng-packs/packages/permission-management/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.permission-management", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "~3.1.0-rc.3", + "@abp/ng.theme.shared": "~3.1.2", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html index a34d674970..148b4ab1b5 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html @@ -63,7 +63,7 @@ let i = index; trackBy: trackByFn " - [style.margin-left]="permission.margin + 'px'" + [ngStyle]="permission.style" class="custom-checkbox custom-control mb-2" > = (_, item) => item.name; - get selectedGroupPermissions$(): Observable { + get selectedGroupPermissions$(): Observable { + const margin = `margin-${ + (document.body.dir as LocaleDirection) === 'rtl' ? 'right' : 'left' + }.px`; + return this.groups$.pipe( map(groups => this.selectedGroup ? groups.find(group => group.name === this.selectedGroup.name).permissions : [], ), - map(permissions => + map(permissions => permissions.map( permission => (({ ...permission, - margin: findMargin(permissions, permission), + style: { [margin]: findMargin(permissions, permission) }, isGranted: this.permissions.find(per => per.name === permission.name).isGranted, - } as any) as PermissionWithMargin), + } as any) as PermissionWithStyle), ), ), ); diff --git a/npm/ng-packs/packages/schematics/package.json b/npm/ng-packs/packages/schematics/package.json index 075a987af7..0124874238 100644 --- a/npm/ng-packs/packages/schematics/package.json +++ b/npm/ng-packs/packages/schematics/package.json @@ -1,6 +1,6 @@ { "name": "@abp/ng.schematics", - "version": "3.1.0-rc.3", + "version": "3.1.2", "description": "Schematics that works with ABP Backend", "keywords": [ "schematics" diff --git a/npm/ng-packs/packages/schematics/src/collection.json b/npm/ng-packs/packages/schematics/src/collection.json index 5c2df8ea36..0b1b738e08 100644 --- a/npm/ng-packs/packages/schematics/src/collection.json +++ b/npm/ng-packs/packages/schematics/src/collection.json @@ -5,6 +5,11 @@ "factory": "./commands/proxy-add", "schema": "./commands/proxy-add/schema.json" }, + "proxy-index": { + "description": "ABP Proxy Generator Index Schematics", + "factory": "./commands/proxy-index", + "schema": "./commands/proxy-index/schema.json" + }, "proxy-refresh": { "description": "ABP Proxy Generator Refresh Schematics", "factory": "./commands/proxy-refresh", diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/enums/__namespace@dir__/__name@kebab__.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/__namespace@dir__/__name@kebab__.enum.ts.template similarity index 100% rename from npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/enums/__namespace@dir__/__name@kebab__.ts.template rename to npm/ng-packs/packages/schematics/src/commands/api/files-enum/proxy/__namespace@dir__/__name@kebab__.enum.ts.template diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/models/__namespace@dir__/index.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/__namespace@dir__/models.ts.template similarity index 100% rename from npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/models/__namespace@dir__/index.ts.template rename to npm/ng-packs/packages/schematics/src/commands/api/files-model/proxy/__namespace@dir__/models.ts.template diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/services/__namespace@dir__/__name@kebab__.service.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template similarity index 85% rename from npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/services/__namespace@dir__/__name@kebab__.service.ts.template rename to npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template index ed2f8296c7..1d77599e7e 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/services/__namespace@dir__/__name@kebab__.service.ts.template +++ b/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template @@ -10,7 +10,9 @@ export class <%= name %>Service { <%= camel(signature.name) %> = (<%= serializeParameters(signature.parameters) %>) => this.restService.request<<%= body.requestType %>, <%= body.responseType %>>({ - method: '<%= body.method %>', + method: '<%= body.method %>',<% + if (body.responseType === 'string') { %> + responseType: 'text',<% } %> url: `/<%= body.url %>`,<% if (body.params.length) { %> params: { <%= body.params.join(', ') %> },<% } diff --git a/npm/ng-packs/packages/schematics/src/commands/api/index.ts b/npm/ng-packs/packages/schematics/src/commands/api/index.ts index 646f2170ea..5254f816b6 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/api/index.ts @@ -19,10 +19,10 @@ import { createImportRefToEnumMapper, createProxyConfigReader, createProxyConfigWriterCreator, + createRootNamespaceGetter, EnumGeneratorParams, generateProxyConfigJson, getEnumNamesFromImports, - getRootNamespace, interpolate, ModelGeneratorParams, removeDefaultPlaceholders, @@ -37,9 +37,10 @@ export default function(schema: GenerateProxySchema) { return chain([ async (tree: Tree, _context: SchematicContext) => { - const source = await resolveProject(tree, params.source!); + const getRootNamespace = createRootNamespaceGetter(params); + const solution = await getRootNamespace(tree); + const target = await resolveProject(tree, params.target!); - const solution = getRootNamespace(tree, source, moduleName); const targetPath = buildDefaultPath(target.definition); const readProxyConfig = createProxyConfigReader(targetPath); const createProxyConfigWriter = createProxyConfigWriterCreator(targetPath); diff --git a/npm/ng-packs/packages/schematics/src/commands/api/schema.json b/npm/ng-packs/packages/schematics/src/commands/api/schema.json index 4411418c34..db58ed73ce 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/schema.json +++ b/npm/ng-packs/packages/schematics/src/commands/api/schema.json @@ -5,34 +5,40 @@ "type": "object", "properties": { "module": { - "alias": "m", - "description": "Backend module to generate code for", + "description": "Backend module name", "type": "string", "$default": { "$source": "argv", "index": 0 }, - "x-prompt": "Please enter name of the backend module you wish to generate proxies for. (default: \"app\")" + "x-prompt": "Please enter backend module name. (default: \"app\")" }, - "source": { - "alias": "s", - "description": "Angular project to resolve root namespace & API definition URL from", + "api-name": { + "description": "Backend api name, a.k.a. remoteServiceName", "type": "string", "$default": { "$source": "argv", "index": 1 }, - "x-prompt": "Plese enter Angular project name to resolve root namespace & API definition URL from. (default: workspace \"defaultProject\")" + "x-prompt": "Please enter backend api name, a.k.a. remoteServiceName. (default: \"default\")" }, - "target": { - "alias": "t", - "description": "Angular project to generate code in", + "source": { + "description": "Source Angular project for API definition URL & root namespace resolution", "type": "string", "$default": { "$source": "argv", "index": 2 }, - "x-prompt": "Plese enter Angular project name to place generated code in. (default: workspace \"defaultProject\")" + "x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")" + }, + "target": { + "description": "Target Angular project to place the generated code", + "type": "string", + "$default": { + "$source": "argv", + "index": 3 + }, + "x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")" } }, "required": [] diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts index 1400cfca1c..3177bedeaa 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-add/index.ts @@ -3,13 +3,14 @@ import { chain, SchematicContext, Tree } from '@angular-devkit/schematics'; import { GenerateProxySchema } from '../../models'; import { buildDefaultPath, - chainAndMerge, createApiDefinitionGetter, createApisGenerator, createProxyClearer, createProxyConfigReader, createProxyConfigSaver, + createProxyIndexGenerator, createProxyWarningSaver, + mergeAndAllowDelete, removeDefaultPlaceholders, resolveProject, } from '../../utils'; @@ -45,7 +46,15 @@ export default function(schema: GenerateProxySchema) { const generateApis = createApisGenerator(schema, generated); - return chainAndMerge([clearProxy, saveProxyConfig, saveProxyWarning, generateApis])(host); + const generateIndex = createProxyIndexGenerator(targetPath); + + return chain([ + mergeAndAllowDelete(host, clearProxy), + saveProxyConfig, + saveProxyWarning, + generateApis, + generateIndex, + ]); }, ]); } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-add/schema.json b/npm/ng-packs/packages/schematics/src/commands/proxy-add/schema.json index f9e762c597..c817882730 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-add/schema.json +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-add/schema.json @@ -5,7 +5,6 @@ "type": "object", "properties": { "module": { - "alias": "m", "description": "Backend module name", "type": "string", "$default": { @@ -14,23 +13,30 @@ }, "x-prompt": "Please enter backend module name. (default: \"app\")" }, + "api-name": { + "description": "Backend api name, a.k.a. remoteServiceName", + "type": "string", + "$default": { + "$source": "argv", + "index": 1 + }, + "x-prompt": "Please enter backend api name, a.k.a. remoteServiceName. (default: \"default\")" + }, "source": { - "alias": "s", "description": "Source Angular project for API definition URL & root namespace resolution", "type": "string", "$default": { "$source": "argv", - "index": 1 + "index": 2 }, "x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")" }, "target": { - "alias": "t", "description": "Target Angular project to place the generated code", "type": "string", "$default": { "$source": "argv", - "index": 2 + "index": 3 }, "x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")" } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-index/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-index/index.ts new file mode 100644 index 0000000000..85c4707daa --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-index/index.ts @@ -0,0 +1,20 @@ +import { SchematicContext, Tree } from '@angular-devkit/schematics'; +import { + buildDefaultPath, + createProxyIndexGenerator, + removeDefaultPlaceholders, + resolveProject, +} from '../../utils'; + +export default function(schema: { target?: string }) { + const params = removeDefaultPlaceholders(schema); + + return async (host: Tree, _context: SchematicContext) => { + const target = await resolveProject(host, params.target!); + const targetPath = buildDefaultPath(target.definition); + + const generateIndex = createProxyIndexGenerator(targetPath); + + return generateIndex(host); + }; +} diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-index/schema.json b/npm/ng-packs/packages/schematics/src/commands/proxy-index/schema.json new file mode 100644 index 0000000000..632c6d7e51 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-index/schema.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/schema", + "id": "SchematicsAbpIndexProxy", + "title": "ABP Index Proxy Schema", + "type": "object", + "properties": { + "target": { + "description": "Target Angular project to place the generated code", + "type": "string", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")" + } + }, + "required": [] +} diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts index 2c4e20d7d2..1a0a5ea3be 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/index.ts @@ -1,13 +1,14 @@ -import { SchematicContext, Tree } from '@angular-devkit/schematics'; +import { chain, SchematicContext, Tree } from '@angular-devkit/schematics'; import { GenerateProxySchema } from '../../models'; import { buildDefaultPath, - chainAndMerge, createApiDefinitionGetter, createApisGenerator, createProxyClearer, createProxyConfigReader, createProxyConfigSaver, + createProxyIndexGenerator, + mergeAndAllowDelete, removeDefaultPlaceholders, resolveProject, } from '../../utils'; @@ -32,6 +33,13 @@ export default function(schema: GenerateProxySchema) { const generateApis = createApisGenerator(schema, generated); - return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host); + const generateIndex = createProxyIndexGenerator(targetPath); + + return chain([ + mergeAndAllowDelete(host, clearProxy), + saveProxyConfig, + generateApis, + generateIndex, + ]); }; } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/schema.json b/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/schema.json index f9e762c597..c817882730 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/schema.json +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-refresh/schema.json @@ -5,7 +5,6 @@ "type": "object", "properties": { "module": { - "alias": "m", "description": "Backend module name", "type": "string", "$default": { @@ -14,23 +13,30 @@ }, "x-prompt": "Please enter backend module name. (default: \"app\")" }, + "api-name": { + "description": "Backend api name, a.k.a. remoteServiceName", + "type": "string", + "$default": { + "$source": "argv", + "index": 1 + }, + "x-prompt": "Please enter backend api name, a.k.a. remoteServiceName. (default: \"default\")" + }, "source": { - "alias": "s", "description": "Source Angular project for API definition URL & root namespace resolution", "type": "string", "$default": { "$source": "argv", - "index": 1 + "index": 2 }, "x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")" }, "target": { - "alias": "t", "description": "Target Angular project to place the generated code", "type": "string", "$default": { "$source": "argv", - "index": 2 + "index": 3 }, "x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")" } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts b/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts index 83cc43c0b8..59004bff11 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-remove/index.ts @@ -1,14 +1,15 @@ import { strings } from '@angular-devkit/core'; -import { SchematicContext, Tree } from '@angular-devkit/schematics'; +import { chain, SchematicContext, Tree } from '@angular-devkit/schematics'; import { GenerateProxySchema } from '../../models'; import { buildDefaultPath, - chainAndMerge, createApiDefinitionGetter, createApisGenerator, createProxyClearer, createProxyConfigReader, createProxyConfigSaver, + createProxyIndexGenerator, + mergeAndAllowDelete, removeDefaultPlaceholders, resolveProject, } from '../../utils'; @@ -38,6 +39,13 @@ export default function(schema: GenerateProxySchema) { const generateApis = createApisGenerator(schema, generated); - return chainAndMerge([clearProxy, saveProxyConfig, generateApis])(host); + const generateIndex = createProxyIndexGenerator(targetPath); + + return chain([ + mergeAndAllowDelete(host, clearProxy), + saveProxyConfig, + generateApis, + generateIndex, + ]); }; } diff --git a/npm/ng-packs/packages/schematics/src/commands/proxy-remove/schema.json b/npm/ng-packs/packages/schematics/src/commands/proxy-remove/schema.json index f9e762c597..c817882730 100644 --- a/npm/ng-packs/packages/schematics/src/commands/proxy-remove/schema.json +++ b/npm/ng-packs/packages/schematics/src/commands/proxy-remove/schema.json @@ -5,7 +5,6 @@ "type": "object", "properties": { "module": { - "alias": "m", "description": "Backend module name", "type": "string", "$default": { @@ -14,23 +13,30 @@ }, "x-prompt": "Please enter backend module name. (default: \"app\")" }, + "api-name": { + "description": "Backend api name, a.k.a. remoteServiceName", + "type": "string", + "$default": { + "$source": "argv", + "index": 1 + }, + "x-prompt": "Please enter backend api name, a.k.a. remoteServiceName. (default: \"default\")" + }, "source": { - "alias": "s", "description": "Source Angular project for API definition URL & root namespace resolution", "type": "string", "$default": { "$source": "argv", - "index": 1 + "index": 2 }, "x-prompt": "Plese enter source Angular project for API definition URL & root namespace resolution. (default: workspace \"defaultProject\")" }, "target": { - "alias": "t", "description": "Target Angular project to place the generated code", "type": "string", "$default": { "$source": "argv", - "index": 2 + "index": 3 }, "x-prompt": "Plese enter target Angular project to place the generated code. (default: workspace \"defaultProject\")" } diff --git a/npm/ng-packs/packages/schematics/src/constants/proxy.ts b/npm/ng-packs/packages/schematics/src/constants/proxy.ts index fbf7f127bd..7e159090e1 100644 --- a/npm/ng-packs/packages/schematics/src/constants/proxy.ts +++ b/npm/ng-packs/packages/schematics/src/constants/proxy.ts @@ -5,14 +5,18 @@ export const PROXY_WARNING_PATH = `${PROXY_PATH}/README.md`; export const PROXY_WARNING = `# Proxy Generation Output This directory includes the output of the latest proxy generation. -The \`services\`, \`models\`, and \`enums\` folders will be overwritten when proxy generation is run again. -Therefore, please do not place your own content in those folders. +The files and folders in it will be overwritten when proxy generation is run again. +Therefore, please do not place your own content in this folder. In addition, \`generate-proxy.json\` works like a lock file. It includes information used by the proxy generator, so please do not delete or modify it. -Finally, the name of this folder should not be changed for two reasons: -- Proxy generator will keep creating this folder and you will have multiple copies of the same content. -- ABP Suite generates imports from this folder and uses the path \`/proxy\` when doing so. +Finally, the name of the files and folders should not be changed for two reasons: +- Proxy generator will keep creating them at those paths and you will have multiple copies of the same content. +- ABP Suite generates files which include imports from this folder. +> **Important Notice:** If you are building a module and are planning to publish to npm, +> some of the generated proxies are likely to be exported from public-api.ts file. In such a case, +> please make sure you export files directly and not from barrel exports. In other words, +> do not include index.ts exports in your public-api.ts exports. `; diff --git a/npm/ng-packs/packages/schematics/src/enums/exception.ts b/npm/ng-packs/packages/schematics/src/enums/exception.ts index 98c92493d6..b267ad6674 100644 --- a/npm/ng-packs/packages/schematics/src/enums/exception.ts +++ b/npm/ng-packs/packages/schematics/src/enums/exception.ts @@ -11,6 +11,6 @@ export const enum Exception { NoTypeDefinition = '[Type Definition Not Found] There is no type definition for "{0}".', NoWorkspace = '[Workspace Not Found] Make sure you are running schematics at the root directory of your workspace and it has an angular.json file.', NoEnvironment = '[Environment Not Found] An environment file cannot be located in "{0}" project.', - NoApiUrl = '[API URL Not Found] Cannot resolve API URL for "{1}" module from "{0}" project.', - NoRootNamespace = '[Root Namespace Not Found] Cannot resolve root namespace for "{1}" module from "{0}" project.', + NoApiUrl = '[API URL Not Found] Cannot resolve API URL for "{1}" remote service name from "{0}" project.', + NoRootNamespace = '[Root Namespace Not Found] Cannot resolve root namespace for "{1}" api from "{0}" project.', } diff --git a/npm/ng-packs/packages/schematics/src/models/generate-proxy-schema.ts b/npm/ng-packs/packages/schematics/src/models/generate-proxy-schema.ts index 59c4e6adab..5e305923c4 100644 --- a/npm/ng-packs/packages/schematics/src/models/generate-proxy-schema.ts +++ b/npm/ng-packs/packages/schematics/src/models/generate-proxy-schema.ts @@ -4,6 +4,11 @@ export interface GenerateProxySchema { */ module?: string; + /** + * Backend api name, a.k.a. remoteServiceName + */ + ['api-name']?: string; + /** * Source Angular project for API definition URL & root namespace resolution */ diff --git a/npm/ng-packs/packages/schematics/src/utils/barrel.ts b/npm/ng-packs/packages/schematics/src/utils/barrel.ts new file mode 100644 index 0000000000..1681362568 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/utils/barrel.ts @@ -0,0 +1,50 @@ +import { strings } from '@angular-devkit/core'; +import { Tree } from '@angular-devkit/schematics'; +import { PROXY_PATH } from '../constants'; +import { createFileSaver } from './file'; + +export function createProxyIndexGenerator(targetPath: string) { + return createBarrelsGenerator(targetPath + PROXY_PATH); +} + +export function createBarrelsGenerator(rootPath: string) { + return (tree: Tree) => { + generateBarrelFromPath(tree, rootPath); + return tree; + }; +} + +export function generateBarrelFromPath(tree: Tree, indexPath: string) { + const saveFile = createFileSaver(tree); + const dir = tree.getDir(indexPath); + + const _exports: string[] = []; + + dir.subfiles.forEach(fragment => { + if (!fragment.endsWith('.ts') || fragment === 'index.ts') return; + + _exports.push(`export * from './${fragment.replace(/\.ts$/, '')}';`); + }); + + dir.subdirs.forEach(fragment => { + const subDirPath = indexPath + '/' + fragment; + const subDir = tree.getDir(subDirPath); + let hasFiles = false; + subDir.visit(() => (hasFiles = true)); + if (!hasFiles) return; + + _exports.push(`export * as ${strings.classify(fragment)} from './${fragment}';`); + generateBarrelFromPath(tree, subDirPath); + }); + + _exports.sort(); + + if (_exports.length) + saveFile( + indexPath + '/index.ts', + _exports.join(` +`) + + ` +`, + ); +} diff --git a/npm/ng-packs/packages/schematics/src/utils/enum.ts b/npm/ng-packs/packages/schematics/src/utils/enum.ts index 818a1a089b..c01b086ec5 100644 --- a/npm/ng-packs/packages/schematics/src/utils/enum.ts +++ b/npm/ng-packs/packages/schematics/src/utils/enum.ts @@ -13,7 +13,7 @@ export interface EnumGeneratorParams { } export function isEnumImport(path: string) { - return path.includes('/enums/'); + return path.endsWith('.enum'); } export function getEnumNamesFromImports(serviceImports: Record) { diff --git a/npm/ng-packs/packages/schematics/src/utils/file.ts b/npm/ng-packs/packages/schematics/src/utils/file.ts new file mode 100644 index 0000000000..cbfa9afcd2 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/utils/file.ts @@ -0,0 +1,8 @@ +import { Tree } from '@angular-devkit/schematics'; + +export function createFileSaver(tree: Tree) { + return (filePath: string, fileContent: string) => + tree.exists(filePath) + ? tree.overwrite(filePath, fileContent) + : tree.create(filePath, fileContent); +} diff --git a/npm/ng-packs/packages/schematics/src/utils/index.ts b/npm/ng-packs/packages/schematics/src/utils/index.ts index 304c2294b0..178920dccc 100644 --- a/npm/ng-packs/packages/schematics/src/utils/index.ts +++ b/npm/ng-packs/packages/schematics/src/utils/index.ts @@ -1,8 +1,10 @@ export * from './angular'; export * from './api'; export * from './ast'; +export * from './barrel'; export * from './common'; export * from './enum'; +export * from './file'; export * from './import'; export * from './model'; export * from './namespace'; diff --git a/npm/ng-packs/packages/schematics/src/utils/model.ts b/npm/ng-packs/packages/schematics/src/utils/model.ts index 2ac5949050..0e472e64d3 100644 --- a/npm/ng-packs/packages/schematics/src/utils/model.ts +++ b/npm/ng-packs/packages/schematics/src/utils/model.ts @@ -133,7 +133,11 @@ export function createImportRefToInterfaceReducerCreator(params: ModelGeneratorP return _interface.properties .reduce((refs, prop) => { - prop.refs.forEach(type => !types[type]?.isEnum && refs.push(type)); + prop.refs.forEach(type => { + if (types[type]?.isEnum || type === _interface.ref) return; + refs.push(type); + }); + return refs; }, []) .concat(base ? parseGenerics(typeDef.baseType!).toGenerics() : []) diff --git a/npm/ng-packs/packages/schematics/src/utils/path.ts b/npm/ng-packs/packages/schematics/src/utils/path.ts index cb1d499755..c28951c8db 100644 --- a/npm/ng-packs/packages/schematics/src/utils/path.ts +++ b/npm/ng-packs/packages/schematics/src/utils/path.ts @@ -1,15 +1,33 @@ -import { dir, kebab } from './text'; +import { strings } from '@angular-devkit/core'; +import { kebab } from './text'; export function relativePathToEnum(namespace: string, enumNamespace: string, enumName: string) { - const repeats = namespace ? namespace.split('.').length : 0; - const path = '..' + '/..'.repeat(repeats) + '/enums/' + dir(enumNamespace); - return removeDoubleSlash(path + '/' + kebab(enumName)); + const path = calculateRelativePath(namespace, enumNamespace); + return path + `/${kebab(enumName)}.enum`; } export function relativePathToModel(namespace: string, modelNamespace: string) { - const repeats = namespace ? namespace.split('.').length : 0; - const path = '..' + '/..'.repeat(repeats) + '/models/' + dir(modelNamespace); - return removeTrailingSlash(path); + const path = calculateRelativePath(namespace, modelNamespace); + return path + '/models'; +} + +function calculateRelativePath(ns1: string, ns2: string) { + if (ns1 === ns2) return '.'; + + const parts1 = ns1 ? ns1.split('.') : []; + const parts2 = ns2 ? ns2.split('.') : []; + + while (parts1.length && parts2.length) { + if (parts1[0] !== parts2[0]) break; + + parts1.shift(); + parts2.shift(); + } + + const up = '../'.repeat(parts1.length) || '.'; + const down = parts2.reduce((acc, p) => acc + '/' + strings.dasherize(p), ''); + + return removeTrailingSlash(removeDoubleSlash(up + down)); } function removeDoubleSlash(path: string) { diff --git a/npm/ng-packs/packages/schematics/src/utils/rule.ts b/npm/ng-packs/packages/schematics/src/utils/rule.ts index 39b14cec78..bd6acdd646 100644 --- a/npm/ng-packs/packages/schematics/src/utils/rule.ts +++ b/npm/ng-packs/packages/schematics/src/utils/rule.ts @@ -1,6 +1,6 @@ import { apply, - chain, + callRule, forEach, MergeStrategy, mergeWith, @@ -18,12 +18,11 @@ export function applyWithOverwrite(source: Source, rules: Rule[]): Rule { }; } -export function chainAndMerge(rules: Rule[]) { - return (host: Tree) => async (tree: Tree, context: SchematicContext) => - host.merge( - (await (chain(rules)(tree, context) as any).toPromise()) as Tree, - MergeStrategy.AllowDeleteConflict, - ); +export function mergeAndAllowDelete(host: Tree, rule: Rule) { + return async (tree: Tree, context: SchematicContext) => { + const nextTree = await callRule(rule, tree, context).toPromise(); + host.merge(nextTree, MergeStrategy.AllowDeleteConflict); + }; } export function overwriteFileIfExists(tree: Tree): Rule { diff --git a/npm/ng-packs/packages/schematics/src/utils/source.ts b/npm/ng-packs/packages/schematics/src/utils/source.ts index b495e75c20..e1e965744f 100644 --- a/npm/ng-packs/packages/schematics/src/utils/source.ts +++ b/npm/ng-packs/packages/schematics/src/utils/source.ts @@ -1,4 +1,3 @@ -import { strings } from '@angular-devkit/core'; import { SchematicsException, Tree } from '@angular-devkit/schematics'; import got from 'got'; import { @@ -15,11 +14,11 @@ import { interpolate } from './common'; import { readEnvironment, resolveProject } from './workspace'; export function createApiDefinitionGetter(params: GenerateProxySchema) { - const moduleName = strings.camelize(params.module || 'app'); + const apiName = params['api-name'] || 'default'; return async (host: Tree) => { const source = await resolveProject(host, params.source!); - const sourceUrl = getSourceUrl(host, source, moduleName); + const sourceUrl = getSourceUrl(host, source, apiName); return await getApiDefinition(sourceUrl); }; } @@ -36,7 +35,7 @@ async function getApiDefinition(sourceUrl: string) { })); } catch ({ response }) { // handle redirects - if (response.statusCode >= 400 || !response?.body) + if (!response?.body || response.statusCode >= 400) throw new SchematicsException(Exception.NoApi); body = response.body; @@ -45,48 +44,49 @@ async function getApiDefinition(sourceUrl: string) { return body; } -export function getRootNamespace(tree: Tree, project: Project, moduleName: string) { - const environmentExpr = readEnvironment(tree, project.definition); +export function createRootNamespaceGetter(params: GenerateProxySchema) { + const apiName = params['api-name'] || 'default'; - if (!environmentExpr) - throw new SchematicsException(interpolate(Exception.NoEnvironment, project.name)); + return async (tree: Tree) => { + const project = await resolveProject(tree, params.source!); + const environmentExpr = readEnvironment(tree, project.definition); - let assignment = getAssignedPropertyFromObjectliteral(environmentExpr, [ - 'apis', - moduleName, - 'rootNamespace', - ]); + if (!environmentExpr) + throw new SchematicsException(interpolate(Exception.NoEnvironment, project.name)); - if (!assignment) - assignment = getAssignedPropertyFromObjectliteral(environmentExpr, [ + let assignment = getAssignedPropertyFromObjectliteral(environmentExpr, [ 'apis', - 'default', + apiName, 'rootNamespace', ]); - if (!assignment) - throw new SchematicsException(interpolate(Exception.NoRootNamespace, project.name, moduleName)); + if (!assignment) + assignment = getAssignedPropertyFromObjectliteral(environmentExpr, [ + 'apis', + 'default', + 'rootNamespace', + ]); - return assignment.replace(/[`'"]/g, ''); + if (!assignment) + throw new SchematicsException(interpolate(Exception.NoRootNamespace, project.name, apiName)); + + return assignment.replace(/[`'"]/g, ''); + }; } -export function getSourceUrl(tree: Tree, project: Project, moduleName: string) { +export function getSourceUrl(tree: Tree, project: Project, apiName: string) { const environmentExpr = readEnvironment(tree, project.definition); if (!environmentExpr) throw new SchematicsException(interpolate(Exception.NoEnvironment, project.name)); - let assignment = getAssignedPropertyFromObjectliteral(environmentExpr, [ - 'apis', - moduleName, - 'url', - ]); + let assignment = getAssignedPropertyFromObjectliteral(environmentExpr, ['apis', apiName, 'url']); if (!assignment) assignment = getAssignedPropertyFromObjectliteral(environmentExpr, ['apis', 'default', 'url']); if (!assignment) - throw new SchematicsException(interpolate(Exception.NoApiUrl, project.name, moduleName)); + throw new SchematicsException(interpolate(Exception.NoApiUrl, project.name, apiName)); return assignment.replace(/[`'"]/g, ''); } @@ -106,15 +106,18 @@ export function createProxyConfigReader(targetPath: string) { export function createProxyClearer(targetPath: string) { targetPath += PROXY_PATH; + const proxyIndexPath = `${targetPath}/index.ts`; return (tree: Tree) => { try { tree.getDir(targetPath).subdirs.forEach(dirName => { - if (!['enums', 'models', 'services'].includes(dirName)) return; - - tree.delete(`${targetPath}/${dirName}`); + const dirPath = `${targetPath}/${dirName}`; + tree.getDir(dirPath).visit(filePath => tree.delete(filePath)); + tree.delete(dirPath); }); + if (tree.exists(proxyIndexPath)) tree.delete(proxyIndexPath); + return tree; } catch (_) { throw new SchematicsException(interpolate(Exception.DirRemoveFailed, targetPath)); diff --git a/npm/ng-packs/packages/setting-management/package.json b/npm/ng-packs/packages/setting-management/package.json index 30716290e8..2c8cb50356 100644 --- a/npm/ng-packs/packages/setting-management/package.json +++ b/npm/ng-packs/packages/setting-management/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.setting-management", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "~3.1.0-rc.3", + "@abp/ng.theme.shared": "~3.1.2", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/tenant-management/package.json b/npm/ng-packs/packages/tenant-management/package.json index 5aa95e42dd..4e4f96671a 100644 --- a/npm/ng-packs/packages/tenant-management/package.json +++ b/npm/ng-packs/packages/tenant-management/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.tenant-management", - "version": "3.1.0-rc.3", + "version": "3.1.2", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.feature-management": "~3.1.0-rc.3", - "@abp/ng.theme.shared": "~3.1.0-rc.3", + "@abp/ng.feature-management": "~3.1.2", + "@abp/ng.theme.shared": "~3.1.2", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html index c966b2c4af..78c8d10a81 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html @@ -5,6 +5,16 @@
{{ 'AbpTenantManagement::Tenants' | abpLocalization }}
+