Browse Source

Merge branch 'dev' of https://github.com/abpframework/abp into dev

pull/3691/head
Akın Sabri Çam 7 years ago
parent
commit
5b4e89b977
  1. 22
      .github/workflows/main.yml
  2. 2
      common.props
  3. 2
      docs/en/Exception-Handling.md
  4. 4
      docs/en/How-To/Customize-SignIn-Manager.md
  5. 2
      docs/en/Tutorials/Part-1.md
  6. 4
      docs/en/Tutorials/Part-2.md
  7. 8
      docs/en/UI/AspNetCore/Tag-Helpers/Index.md
  8. 2
      docs/pt-BR/Tutorials/Angular/Part-I.md
  9. 2
      docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md
  10. 4
      docs/zh-Hans/Exception-Handling.md
  11. 4
      docs/zh-Hans/How-To/Customize-SignIn-Manager.md
  12. 44
      docs/zh-Hans/Startup-Templates/Application.md
  13. 3
      docs/zh-Hans/UI/Angular/AddingSettingTab.md
  14. 293
      docs/zh-Hans/UI/Angular/Config-State.md
  15. 129
      docs/zh-Hans/UI/Angular/Dom-Insertion-Service.md
  16. 80
      docs/zh-Hans/UI/Angular/Permission-Management.md
  17. 8
      docs/zh-Hans/UI/AspNetCore/Tag-Helpers/Index.md
  18. BIN
      docs/zh-Hans/images/bookstore-home.png
  19. BIN
      docs/zh-Hans/images/bookstore-login.png
  20. BIN
      docs/zh-Hans/images/db-migrator-output.png
  21. BIN
      docs/zh-Hans/images/package-manager-console-update-database.png
  22. BIN
      docs/zh-Hans/images/rn-environment-local-ip.png
  23. BIN
      docs/zh-Hans/images/rn-expo-interface.png
  24. BIN
      docs/zh-Hans/images/rn-host-local-ip.png
  25. BIN
      docs/zh-Hans/images/rn-login-iphone.png
  26. BIN
      docs/zh-Hans/images/rn-tiered-local-ip.png
  27. BIN
      docs/zh-Hans/images/solution-files-mvc.png
  28. BIN
      docs/zh-Hans/images/solution-files-non-mvc.png
  29. BIN
      docs/zh-Hans/images/swagger-ui.png
  30. BIN
      docs/zh-Hans/images/vs-app-solution-structure-mongodb.png
  31. BIN
      docs/zh-Hans/images/vs-app-solution-structure-tiered.png
  32. BIN
      docs/zh-Hans/images/vs-app-solution-structure.png
  33. BIN
      docs/zh-Hans/images/vs-spa-app-backend-structure-mongodb.png
  34. BIN
      docs/zh-Hans/images/vs-spa-app-backend-structure.png
  35. 2
      framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
  36. 600
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js
  37. 1
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js.map
  38. 2
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js
  39. 1
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js.map
  40. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/AbpAspNetCoreMvcUiThemeBasicDemoModule.cs
  41. 58
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/BasicThemeDemoMenuContributor.cs
  42. 58
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Menus/BasicThemeDemoMenuContributor.cs
  43. 36
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Menus/BasicThemeDemoMenus.cs
  44. 7
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Alerts/Index.cshtml
  45. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Badges/Index.cshtml
  46. 19
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Borders/Index.cshtml
  47. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Breadcrumbs/Index.cshtml
  48. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/ButtonGroups/Index.cshtml
  49. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Buttons/Index.cshtml
  50. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Cards/Index.cshtml
  51. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Carousel/Index.cshtml
  52. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Collapse/Index.cshtml
  53. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Dropdowns/Index.cshtml
  54. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/DynamicForms/Index.cshtml
  55. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/FormElements/Index.cshtml
  56. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Grids/Index.cshtml
  57. 22
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Index.cshtml
  58. 22
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Index.cshtml.cs
  59. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/ListGroups/Index.cshtml
  60. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Modals/Index.cshtml
  61. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Navbars/Index.cshtml
  62. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Navs/Index.cshtml
  63. 8
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Paginator/Index.cshtml
  64. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Popovers/Index.cshtml
  65. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/ProgressBars/Index.cshtml
  66. 5
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Tables/Index.cshtml
  67. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Tabs/Index.cshtml
  68. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Tooltips/Index.cshtml
  69. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Index.cshtml
  70. 2
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Program.cs
  71. 600
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js
  72. 1
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js.map
  73. 2
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js
  74. 1
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js.map
  75. 2
      modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.csproj
  76. 9
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/ClearCacheInput.cs
  77. 2
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs
  78. 35
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
  79. 7
      modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
  80. 12
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/index.js
  81. 46
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
  82. 5
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs
  83. 27
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Caching/CacheKeyGenerator.cs
  84. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs
  85. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
  86. 8
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs
  87. 7
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs
  88. 4
      modules/docs/test/Volo.Docs.Application.Tests/Volo/Docs/ApplicationService_Tests.cs
  89. 2
      modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/Document/DocumentRepository_Tests.cs
  90. 4
      modules/docs/test/Volo.Docs.TestBase/Volo/Docs/ProjectRepository_Tests.cs
  91. 2
      npm/lerna.json
  92. 2
      npm/ng-packs/lerna.version.json
  93. 6
      npm/ng-packs/package.json
  94. 2
      npm/ng-packs/packages/account-config/package.json
  95. 6
      npm/ng-packs/packages/account/package.json
  96. 2
      npm/ng-packs/packages/core/package.json
  97. 4
      npm/ng-packs/packages/feature-management/package.json
  98. 2
      npm/ng-packs/packages/identity-config/package.json
  99. 8
      npm/ng-packs/packages/identity/package.json
  100. 4
      npm/ng-packs/packages/permission-management/package.json

22
.github/workflows/main.yml

@ -14,15 +14,17 @@ jobs:
build-test: build-test:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- uses: actions/setup-dotnet@master - uses: actions/setup-dotnet@master
with: with:
dotnet-version: "3.1.100" dotnet-version: 3.1.100
- name: Build All - name: Build All
run: .\build\build-all.ps1 run: .\build-all.ps1
shell: pwsh working-directory: .\build
shell: powershell
- name: Test All - name: Test All
run: .\build\test-all.ps1 run: .\test-all.ps1
shell: pwsh working-directory: .\build
shell: powershell

2
common.props

@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Version>2.6.0</Version> <Version>2.7.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl> <PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io</PackageProjectUrl> <PackageProjectUrl>https://abp.io</PackageProjectUrl>

2
docs/en/Exception-Handling.md

@ -316,7 +316,7 @@ The `context` object contains necessary information about the exception occurred
Some exception types are automatically thrown by the framework: Some exception types are automatically thrown by the framework:
- `AbpAuthorizationException` is thrown if the current user has no permission to perform the requested operation. See [authorization](Authorization.md) for more. - `AbpAuthorizationException` is thrown if the current user has no permission to perform the requested operation. See [authorization](Authorization.md) for more.
- `AbpValidationException` is thrown if the input of the current request is not valid. See [validation] (Validation.md) for more. - `AbpValidationException` is thrown if the input of the current request is not valid. See [validation](Validation.md) for more.
- `EntityNotFoundException` is thrown if the requested entity is not available. This is mostly thrown by [repositories](Repositories.md). - `EntityNotFoundException` is thrown if the requested entity is not available. This is mostly thrown by [repositories](Repositories.md).
You can also throw these type of exceptions in your code (although it's rarely needed). You can also throw these type of exceptions in your code (although it's rarely needed).

4
docs/en/How-To/Customize-SignIn-Manager.md

@ -42,14 +42,14 @@ public override async Task<Microsoft.AspNetCore.Identity.ExternalLoginInfo> GetE
{ {
var auth = await Context.AuthenticateAsync(Microsoft.AspNetCore.Identity.IdentityConstants.ExternalScheme); var auth = await Context.AuthenticateAsync(Microsoft.AspNetCore.Identity.IdentityConstants.ExternalScheme);
var items = auth?.Properties?.Items; var items = auth?.Properties?.Items;
if (auth?.Principal == null || items == null || !items.ContainsKey("LoginProviderKey")) if (auth?.Principal == null || items == null || !items.ContainsKey(LoginProviderKey))
{ {
return null; return null;
} }
if (expectedXsrf != null) if (expectedXsrf != null)
{ {
if (!items.ContainsKey("XsrfKey")) if (!items.ContainsKey(XsrfKey))
{ {
return null; return null;
} }

2
docs/en/Tutorials/Part-1.md

@ -982,11 +982,13 @@ import { GetBooks } from '../actions/books.actions';
import { Books } from '../models/books'; import { Books } from '../models/books';
import { BooksService } from '../../books/shared/books.service'; import { BooksService } from '../../books/shared/books.service';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
@State<Books.State>({ @State<Books.State>({
name: 'BooksState', name: 'BooksState',
defaults: { books: {} } as Books.State, defaults: { books: {} } as Books.State,
}) })
@Injectable()
export class BooksState { export class BooksState {
@Selector() @Selector()
static getBooks(state: Books.State) { static getBooks(state: Books.State) {

4
docs/en/Tutorials/Part-2.md

@ -574,11 +574,13 @@ import { GetBooks, CreateUpdateBook } from '../actions/books.actions'; //<== add
import { Books } from '../models/books'; import { Books } from '../models/books';
import { BooksService } from '../../books/shared/books.service'; import { BooksService } from '../../books/shared/books.service';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
@State<Books.State>({ @State<Books.State>({
name: 'BooksState', name: 'BooksState',
defaults: { books: {} } as Books.State, defaults: { books: {} } as Books.State,
}) })
@Injectable()
export class BooksState { export class BooksState {
@Selector() @Selector()
static getBooks(state: Books.State) { static getBooks(state: Books.State) {
@ -1330,11 +1332,13 @@ import { GetBooks, CreateUpdateBook, DeleteBook } from '../actions/books.actions
import { Books } from '../models/books'; import { Books } from '../models/books';
import { BooksService } from '../../books/shared/books.service'; import { BooksService } from '../../books/shared/books.service';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
@State<Books.State>({ @State<Books.State>({
name: 'BooksState', name: 'BooksState',
defaults: { books: {} } as Books.State, defaults: { books: {} } as Books.State,
}) })
@Injectable()
export class BooksState { export class BooksState {
@Selector() @Selector()
static getBooks(state: Books.State) { static getBooks(state: Books.State) {

8
docs/en/UI/AspNetCore/Tag-Helpers/Index.md

@ -12,18 +12,18 @@ ABP Framework also adds some **useful features** to the standard bootstrap compo
Here, the list of components those are wrapped by the ABP Framework: Here, the list of components those are wrapped by the ABP Framework:
* [Alerts](Alerts.md)
* [Buttons](Buttons.md) * [Buttons](Buttons.md)
* [Cards](Cards.md) * [Cards](Cards.md)
* [Alerts](Alerts.md)
* [Tabs](Tabs.md)
* [Grids](Grids.md)
* [Modals](Modals.md)
* [Collapse](Collapse.md) * [Collapse](Collapse.md)
* [Dropdowns](Dropdowns.md) * [Dropdowns](Dropdowns.md)
* [Grids](Grids.md)
* [List Groups](List-Groups.md) * [List Groups](List-Groups.md)
* [Modals](Modals.md)
* [Paginator](Paginator.md) * [Paginator](Paginator.md)
* [Popovers](Popovers.md) * [Popovers](Popovers.md)
* [Progress Bars](Progress-Bars.md) * [Progress Bars](Progress-Bars.md)
* [Tabs](Tabs.md)
* [Tooltips](Tooltips.md) * [Tooltips](Tooltips.md)
* ... * ...

2
docs/pt-BR/Tutorials/Angular/Part-I.md

@ -537,11 +537,13 @@ import { GetBooks } from '../actions/books.actions';
import { Books } from '../models/books'; import { Books } from '../models/books';
import { BooksService } from '../../books/shared/books.service'; import { BooksService } from '../../books/shared/books.service';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
@State<Books.State>({ @State<Books.State>({
name: 'BooksState', name: 'BooksState',
defaults: { books: {} } as Books.State, defaults: { books: {} } as Books.State,
}) })
@Injectable()
export class BooksState { export class BooksState {
@Selector() @Selector()
static getBooks(state: Books.State) { static getBooks(state: Books.State) {

2
docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md

@ -50,7 +50,7 @@ ObjectExtensionManager.Instance
* 你提供了 `IdentityUser` 作为实体名(泛型参数), `string` 做为新属性的类型, `SocialSecurityNumber` 做为属性名(也是数据库表的字段名). * 你提供了 `IdentityUser` 作为实体名(泛型参数), `string` 做为新属性的类型, `SocialSecurityNumber` 做为属性名(也是数据库表的字段名).
* 你还需要提供一个使用[EF Core Fluent API](https://docs.microsoft.com/en-us/ef/core/modeling/entity-properties)定义数据库映射属性的操作. * 你还需要提供一个使用[EF Core Fluent API](https://docs.microsoft.com/en-us/ef/core/modeling/entity-properties)定义数据库映射属性的操作.
> 必须在使用相关的 `DbContext` 之前执行此代码. 应用程序启动模板定义了一个名为 `YourProjectNameEntityExtensions` 的静态类. 你可以在此类中定义扩展确保在正确的时间执行它. 否则你需要自己处理. > 必须在使用相关的 `DbContext` 之前执行此代码. 应用程序启动模板定义了一个名为 `YourProjectNameEfCoreEntityExtensionMappings` 的静态类. 你可以在此类中定义扩展确保在正确的时间执行它. 否则你需要自己处理.
定义实体扩展后你需要使用EF Core的[Add-Migration](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#add-migration)和[Update-Database](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#update-database)命令来创建code first迁移类并更新数据库. 定义实体扩展后你需要使用EF Core的[Add-Migration](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#add-migration)和[Update-Database](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#update-database)命令来创建code first迁移类并更新数据库.

4
docs/zh-Hans/Exception-Handling.md

@ -295,8 +295,8 @@ services.Configure<AbpExceptionHttpStatusCodeOptions>(options =>
框架会自动抛出以下异常类型: 框架会自动抛出以下异常类型:
- 当用户没有权限执行操作时,会抛出 `AbpAuthorizationException` 异常. 有关更多信息,请参阅授权文档(TODO:link). - 当用户没有权限执行操作时,会抛出 `AbpAuthorizationException` 异常. 有关更多信息,请参阅授权文档[authorization](Authorization.md).
- 如果当前请求的输入无效,则抛出`AbpValidationException 异常`. 有关更多信息,请参阅授权文档(TODO:link). - 如果当前请求的输入无效,则抛出`AbpValidationException 异常`. 有关更多信息,请参阅[验证文档](Validation.md).
- 如果请求的实体不存在,则抛出`EntityNotFoundException` 异常. 此异常大多数由 [repositories](Repositories.md) 抛出. - 如果请求的实体不存在,则抛出`EntityNotFoundException` 异常. 此异常大多数由 [repositories](Repositories.md) 抛出.
你同样可以在代码中抛出这些类型的异常(虽然很少需要这样做) 你同样可以在代码中抛出这些类型的异常(虽然很少需要这样做)

4
docs/zh-Hans/How-To/Customize-SignIn-Manager.md

@ -42,14 +42,14 @@ public override async Task<Microsoft.AspNetCore.Identity.ExternalLoginInfo> GetE
{ {
var auth = await Context.AuthenticateAsync(Microsoft.AspNetCore.Identity.IdentityConstants.ExternalScheme); var auth = await Context.AuthenticateAsync(Microsoft.AspNetCore.Identity.IdentityConstants.ExternalScheme);
var items = auth?.Properties?.Items; var items = auth?.Properties?.Items;
if (auth?.Principal == null || items == null || !items.ContainsKey("LoginProviderKey")) if (auth?.Principal == null || items == null || !items.ContainsKey(LoginProviderKey))
{ {
return null; return null;
} }
if (expectedXsrf != null) if (expectedXsrf != null)
{ {
if (!items.ContainsKey("XsrfKey")) if (!items.ContainsKey(XsrfKey))
{ {
return null; return null;
} }

44
docs/zh-Hans/Startup-Templates/Application.md

@ -362,7 +362,7 @@ React Native 应用文件夹结构, 如下图所示:
#### Components(组件) #### Components(组件)
可以在所有屏幕上使用的组件是在 `src/components` 文件夹中创建的. 所有组件都是作为一个能够使用 [hooks](https://reactjs.org/docs/hooks-intro.html) 的函数创建的. 可以在所有屏幕上使用的组件是在 `src/components` 文件夹中创建的. 所有组件都是作为一个能够使用 [hooks](https://reactjs.org/docs/hooks-intro.html) 的函数创建的.
#### Screens(屏幕) #### Screens(屏幕)
@ -378,7 +378,7 @@ Screens 是通过在 `src/screens` 文件夹中创建将名称分开的文件夹
#### State Management(状态管理) #### State Management(状态管理)
[Redux](https://redux.js.org/) 被用作状态管理库. [Redux Toolkit](https://redux-toolkit.js.org/) 库被用作高效Redux开发的工具集. [Redux](https://redux.js.org/) 被用作状态管理库. [Redux Toolkit](https://redux-toolkit.js.org/) 库被用作高效Redux开发的工具集.
在 `src/store` 文件夹中创建 Actions, reducers, sagas, selectors. 存储文件夹如下: 在 `src/store` 文件夹中创建 Actions, reducers, sagas, selectors. 存储文件夹如下:
@ -387,41 +387,41 @@ Screens 是通过在 `src/screens` 文件夹中创建将名称分开的文件夹
* [**Store**](https://redux.js.org/basics/store) 在 `src/store/index.js` 文件中定义. * [**Store**](https://redux.js.org/basics/store) 在 `src/store/index.js` 文件中定义.
* [**Actions**](https://redux.js.org/basics/actions/) 是将数据从应用程序发送到存储的有效信息负载. * [**Actions**](https://redux.js.org/basics/actions/) 是将数据从应用程序发送到存储的有效信息负载.
* [**Reducers**](https://redux.js.org/basics/reducers) 指定应用程序的状态如何更改以响应发送到存储的操作. * [**Reducers**](https://redux.js.org/basics/reducers) 指定应用程序的状态如何更改以响应发送到存储的操作.
* [**Redux-Saga**](https://redux-saga.js.org/) 是一个库, 旨在使应用程序的副作用(即异步的事情, 如数据获取和不纯的事情, 如访问浏览器缓存)更容易管理. Sagas 是在 `src/store/sagas` 文件夹中创建的. * [**Redux-Saga**](https://redux-saga.js.org/) 是一个库, 旨在使应用程序的副作用(即异步的事情, 如数据获取和不纯的事情, 如访问浏览器缓存)更容易管理. Sagas 是在 `src/store/sagas` 文件夹中创建的.
* [**Reselect**](https://github.com/reduxjs/reselect) 库用于创建缓存的选择器. 选择器是在 `src/store/selectors` 文件夹中创建的. * [**Reselect**](https://github.com/reduxjs/reselect) 库用于创建缓存的选择器. 选择器是在 `src/store/selectors` 文件夹中创建的.
#### APIs #### APIs
[Axios](https://github.com/axios/axios) 用作HTTP客户端库. Axios 实例从 `src/api/API.js` 导出 . 使用相同的配置进行HTTP调用. `src/api` 文件夹中还有为 API 调用创建的 API 文件. [Axios](https://github.com/axios/axios) 用作HTTP客户端库. Axios 实例从 `src/api/API.js` 导出 . 使用相同的配置进行HTTP调用. `src/api` 文件夹中还有为 API 调用创建的 API 文件.
#### Theming(主题) #### Theming(主题)
[Native Base](https://nativebase.io/) 被用作UI组件库. 本地基本组件可以很容易地进行自定义。参见 [Native Base customize](https://docs.nativebase.io/Customize.html#Customize) 文档。我们沿着同样的路走。 [Native Base](https://nativebase.io/) 被用作UI组件库. 本地基本组件可以很容易地进行自定义.参见[Native Base customize](https://docs.nativebase.io/Customize.html#Customize) 文档.我们沿着同样的路走.
* Native Base 主题变量在 `src/theme/variables` 文件夹中。 * Native Base 主题变量在 `src/theme/variables` 文件夹中.
* Native Base 组件样式在 `src/theme/components` 文件夹中。这些文件是用 Native Base's `ejectTheme` 脚本生成的。 * Native Base 组件样式在 `src/theme/components` 文件夹中.这些文件是用 Native Base's `ejectTheme` 脚本生成的.
* 组件样式用 `src/theme/overrides` 文件夹下的文件覆盖。 * 组件样式用 `src/theme/overrides` 文件夹下的文件覆盖.
#### Testing(单元测试) #### Testing(单元测试)
将创建单元测试。 将创建单元测试.
参见[测试概述](https://reactjs.org/docs/testing.html)文档。 参见[测试概述](https://reactjs.org/docs/testing.html)文档.
#### Depended Libraries(依赖库) #### Depended Libraries(依赖库)
* [Native Base](https://nativebase.io/) 用作UI组件库。 * [Native Base](https://nativebase.io/) 用作UI组件库.
* [React Navigation](https://reactnavigation.org/) 用作导航库。 * [React Navigation](https://reactnavigation.org/) 用作导航库.
* [Axios](https://github.com/axios/axios) 用作HTTP客户端库。 * [Axios](https://github.com/axios/axios) 用作HTTP客户端库.
* [Redux](https://redux.js.org/) 用作状态管理库。 * [Redux](https://redux.js.org/) 用作状态管理库.
* [Redux Toolkit](https://redux-toolkit.js.org/) 库被用作高效Redux开发的工具集。 * [Redux Toolkit](https://redux-toolkit.js.org/) 库被用作高效Redux开发的工具集.
* [Redux-Saga](https://redux-saga.js.org/) 用于管理异步进程。 * [Redux-Saga](https://redux-saga.js.org/) 用于管理异步进程.
* [Redux Persist](https://github.com/rt2zz/redux-persist) 被用作状态持久化。 * [Redux Persist](https://github.com/rt2zz/redux-persist) 被用作状态持久化.
* [Reselect](https://github.com/reduxjs/reselect) 用于创建缓存的选择器。 * [Reselect](https://github.com/reduxjs/reselect) 用于创建缓存的选择器.
* [i18n-js](https://github.com/fnando/i18n-js) 作为国际化库使用。 * [i18n-js](https://github.com/fnando/i18n-js) 作为国际化库使用.
* [expo-font](https://docs.expo.io/versions/latest/sdk/font/) 库可以轻松加载字体。 * [expo-font](https://docs.expo.io/versions/latest/sdk/font/) 库可以轻松加载字体.
* [Formik](https://github.com/jaredpalmer/formik) 用于构建表单。 * [Formik](https://github.com/jaredpalmer/formik) 用于构建表单.
* [Yup](https://github.com/jquense/yup) 用于表单验证。 * [Yup](https://github.com/jquense/yup) 用于表单验证.
## 下一步是什么? ## 下一步是什么?

3
docs/zh-Hans/UI/Angular/AddingSettingTab.md

@ -1,3 +0,0 @@
## Creating a Settings Tab
TODO...

293
docs/zh-Hans/UI/Angular/Config-State.md

@ -1,3 +1,294 @@
## 配置状态 ## 配置状态
TODO... `ConfigStateService` 是一个单例服务,即在应用程序的根级别提供,用于与 `Store` 中的应用程序配置状态进行交互.
## 使用前
为了使用 `ConfigStateService`,你必须将其注入到你的类中.
```js
import { ConfigStateService } from '@abp/ng.core';
@Component({
/* class metadata here */
})
class DemoComponent {
constructor(private config: ConfigStateService) {}
}
```
你不必在模块或组件/指令级别提供 `ConfigStateService`,因为它已经在**根中**提供.
## 选择器方法
`ConfigStateService` 有许多选择器方法允许你从 `Store` 获取特定或所有的配置.
### 如何从Store获取所有的配置
你可以使用 `ConfigStateService` 的 `getAll` 方法从Store获取所有的配置对象. 用法如下:
```js
// this.config is instance of ConfigStateService
const config = this.config.getAll();
```
### 如何从Store获取特定的配置
你可以使用 `ConfigStateService` 的 `getOne` 方法从Store获取特定的配置属性. 你需要将属性名做为参数传递给方法:
```js
// this.config is instance of ConfigStateService
const currentUser = this.config.getOne("currentUser");
```
有时你想要获取具体信息,而不是当前用户. 例如你只想获取到 `tenantId`:
```js
const tenantId = this.config.getDeep("currentUser.tenantId");
```
或通过提供键数组作为参数:
```js
const tenantId = this.config.getDeep(["currentUser", "tenantId"]);
```
`getDeep` 可以执行 `getOne` 的所有操作. 但 `getOne` 的执行效率要高一些.
#### 配置状态属性
请参阅 `Config.State` 类型,你可以通过 `getOne` 和 `getDeep` 获取所有属性. 你可以在[config.ts 文件](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L7)中找到.
### 如何从Store获取应用程序信息
`getApplicationInfo` 方法从存储为配置状态存储的环境变量中获取应用程序信息. 你可以这样使用它:
```js
// this.config is instance of ConfigStateService
const appInfo = this.config.getApplicationInfo();
```
该方法不会返回 `undefined` 或 `null`,而是会返回一个空对象(`{}`). 换句话说,当你使用上面代码中的 `appInfo` 属性时,永远不会出现错误.
#### 应用程序信息属性
请参阅 `Config.State` 类型,你可以通过 `getApplicationInfo` 获取所有属性. 你可以在[config.ts 文件](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L21)中找到.
### 如何从Store获取
`getApplicationInfo` 方法从存储为配置状态存储的环境变量中获取特定的API URL. 你可以这样使用它:
```js
// this.config is instance of ConfigStateService
const apiUrl = this.config.getApiUrl();
// environment.apis.default.url
const searchUrl = this.config.getApiUrl("search");
// environment.apis.search.url
```
该方法返回给定键的特定的API `url`. 如果没有Key,则使用 `default`.
### 如何从Store获取所有的设置
你可以使用 `ConfigStateService` 的 `getSettings` 获取配置状态所有的设置对象. 你可以这样使用它:
```js
// this.config is instance of ConfigStateService
const settings = this.config.getSettings();
```
实际上该方法可以通过**传递关键字**来搜索设置.
```js
const localizationSettings = this.config.getSettings("Localization");
/*
{
'Abp.Localization.DefaultLanguage': 'en'
}
*/
```
请注意, **设置搜索区分大小写**.
### 如何从Store获取特定的设置
你可以使用 `ConfigStateService` 的 `getSetting` 获取配置状态特定的设置. 你可以这样使用它:
```js
// this.config is instance of ConfigStateService
const defaultLang = this.config.getSetting("Abp.Localization.DefaultLanguage");
// 'en'
```
### 如何从Store获取特定的权限
你可以使用 `ConfigStateService` 的 `getGrantedPolicy` 获取配置状态特定的权限. 你应该将策略key做为参数传递给方法:
```js
// this.config is instance of ConfigStateService
const hasIdentityPermission = this.config.getGrantedPolicy("Abp.Identity");
// true
```
你还可以使用 **组合策略key** 来微调你的选择:
```js
// this.config is instance of ConfigStateService
const hasIdentityAndAccountPermission = this.config.getGrantedPolicy(
"Abp.Identity && Abp.Account"
);
// false
const hasIdentityOrAccountPermission = this.config.getGrantedPolicy(
"Abp.Identity || Abp.Account"
);
// true
```
创建权限选择器时,请考虑以下**规则**:
- 最多可组合两个键.
- `&&` 操作符查找两个键.
- `||` 操作符查找任意一个键.
- 空字符串 `''` 做为键将返回 `true`
- 使用没有第二个键的操作符将返回 `false`
### 如何从Store中获取翻译
`ConfigStateService` 的 `getLocalization` 用法翻译. 这里有一些示例:
```js
// this.config is instance of ConfigStateService
const identity = this.config.getLocalization("AbpIdentity::Identity");
// 'identity'
const notFound = this.config.getLocalization("AbpIdentity::IDENTITY");
// 'AbpIdentity::IDENTITY'
const defaultValue = this.config.getLocalization({
key: "AbpIdentity::IDENTITY",
defaultValue: "IDENTITY"
});
// 'IDENTITY'
```
请参阅[本地化文档](./Localization.md)了解详情.
## 分发方法
`ConfigStateService` 有几种分发方法,让你方便地将预定义操作分发到 `Store`.
### 如何从服务器获取应用程序配置
`dispatchGetAppConfiguration` 触发对端点的请求,该端点使用应用程序状态进行响应,然后将此响应作为配置状态放置到 `Store`中.
```js
// this.config is instance of ConfigStateService
this.config.dispatchGetAppConfiguration();
// returns a state stream which emits after dispatch action is complete
```
请注意,**你不必在应用程序启动时调用此方法**,因为在启动时已经从服务器收到了应用程序配置.
### 如何修补路由配置
`dispatchPatchRouteByName` 根据名称查找路由, 并将其在 `Store` 中的配置替换为作为第二个参数传递的新配置.
```js
// this.config is instance of ConfigStateService
const newRouteConfig: Partial<ABP.Route> = {
name: "Home",
path: "home",
children: [
{
name: "Dashboard",
path: "dashboard"
}
]
};
this.config.dispatchPatchRouteByName("::Menu:Home", newRouteConfig);
// returns a state stream which emits after dispatch action is complete
```
### 如何添加新路由配置
`dispatchAddRoute` 向 `Store` 的配置状态添加一个新路由. 应该将路由配置做为方法参数传递.
```js
// this.config is instance of ConfigStateService
const newRoute: ABP.Route = {
name: "My New Page",
iconClass: "fa fa-dashboard",
path: "page",
invisible: false,
order: 2,
requiredPolicy: "MyProjectName::MyNewPage"
};
this.config.dispatchAddRoute(newRoute);
// returns a state stream which emits after dispatch action is complete
```
`newRoute` 将被放置在根级别,没有任何父路由,并且其url将存储为 `'/path'`.
如果你想要**添加一个子路由,您可以这样做:**
```js
// this.config is instance of ConfigStateService
const newRoute: ABP.Route = {
parentName: "AbpAccount::Login",
name: "My New Page",
iconClass: "fa fa-dashboard",
path: "page",
invisible: false,
order: 2,
requiredPolicy: "MyProjectName::MyNewPage"
};
this.config.dispatchAddRoute(newRoute);
// returns a state stream which emits after dispatch action is complete
```
`newRoute` 做为 `'AbpAccount::Login'` 父路由的子路由被放置,它的url被设置为 `'/account/login/page'`.
#### 路由配置属性
请参阅 `ABP.Route` 类型,获取可在参数中传递给 `dispatchSetEnvironment` 的所有属性. 你可以在[common.ts 文件](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/common.ts#L27)中找到.
### 如何设置环境
`dispatchSetEnvironment` 将传递给它的环境变量放在 `Store` 中的配置状态下. 使用方法如下:
```js
// this.config is instance of ConfigStateService
this.config.dispatchSetEnvironment({
/* environment properties here */
});
// returns a state stream which emits after dispatch action is complete
```
注意,**你不必在应用程序启动时调用此方法**,因为环境变量已经在启动时存储了.
#### 环境属性
请参阅 `Config.Environment` 类型,获取可在参数中传递给 `dispatchSetEnvironment` 的所有属性. 你可以在[config.ts 文件](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/config.ts#L13)中找到.
## 下一步是什么?
* [组件替换]](./Component-Replacement.md)

129
docs/zh-Hans/UI/Angular/Dom-Insertion-Service.md

@ -1,3 +1,130 @@
# Dom插入(Scripts与Styles) # Dom插入(Scripts与Styles)
TODO... 你可以使用@abp/ng.core包提供的 `DomInsertionService` 以简单的方式的插入脚本与样式.
## 入门
你不必在模块或组件级别提供 `DomInsertionService` ,因为它已经在**根中**提供. 你可以在组件,指令或服务中直接注入并使用它.
```js
import { DomInsertionService } from '@abp/ng.core';
@Component({
/* class metadata here */
})
class DemoComponent {
constructor(private domInsertionService: DomInsertionService) {}
}
```
## 用法
你可以使用 `DomInsertionService` 提供的 `insertContent` 方法去创建一个 `<script>` 或 `<style>` 元素到DOM的指定位置. 还有 `projectContent` 方法用于渲染组件和模板.
### 如何插入Scripts
`insertContent` 方法的第一个参数需要一个 `ContentStrategy`. 如果传递 `ScriptContentStrategy` 实例, `DomInsertionService` 将创建具有给定内容的 `<script>` 元素并放置在指定的DOM位置.
```js
import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core';
@Component({
/* class metadata here */
})
class DemoComponent {
constructor(private domInsertionService: DomInsertionService) {}
ngOnInit() {
const scriptElement = this.domInsertionService.insertContent(
CONTENT_STRATEGY.AppendScriptToBody('alert()')
);
}
}
```
在上面的示例中,将 `<script>alert()</script>` 元素放置在 `<body>`的末尾, `scriptElement` 类型是一个 `HTMLScriptElement`.
请参考[ContentStrategy](./Content-Strategy.md)查看所有可用的内容策略以及如何构建自己的内容策略.
> 重要说明: `DomInsertionService` 不会两次插入相同的内容. 为了再次添加内容你首先应该使用 `removeContent` 方法删除旧内容.
### 如何插入Styles
`insertContent` 方法的第一个参数需要一个 `ContentStrategy`. 如果传递 `StyleContentStrategy` 实例, `DomInsertionService` 将创建具有给定内容的 `<style>` 元素并放置在指定的DOM位置.
```js
import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core';
@Component({
/* class metadata here */
})
class DemoComponent {
constructor(private domInsertionService: DomInsertionService) {}
ngOnInit() {
const styleElement = this.domInsertionService.insertContent(
CONTENT_STRATEGY.AppendStyleToHead('body {margin: 0;}')
);
}
}
```
在上面的示例中,将 `<style>body {margin: 0;}</style>` 元素放置在 `<head>`的末尾, `styleElement` 类型是一个 `HTMLStyleElement`.
请参考[ContentStrategy](./Content-Strategy.md)查看所有可用的内容策略以及如何构建自己的内容策略.
.
> 重要说明: `DomInsertionService` 不会两次插入相同的内容. 为了再次添加内容你首先应该使用 `removeContent` 方法删除旧内容.
### 如何删除已插入的 Scripts & Styles
如果你传递 `HTMLScriptElement` 或 `HTMLStyleElement` 做为 `removeContent` 方法的第一个参数, `DomInsertionService` 将删除给定的元素.
```js
import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core';
@Component({
/* class metadata here */
})
class DemoComponent {
private styleElement: HTMLStyleElement;
constructor(private domInsertionService: DomInsertionService) {}
ngOnInit() {
this.styleElement = this.domInsertionService.insertContent(
CONTENT_STRATEGY.AppendStyleToHead('body {margin: 0;}')
);
}
ngOnDestroy() {
this.domInsertionService.removeContent(this.styleElement);
}
}
```
在上面的示例中,销毁组件时,将从 `<head>` 中删除 `<style>body {margin: 0;}</style>` 元素.
## API
### insertContent
```js
insertContent<T extends HTMLScriptElement | HTMLStyleElement>(
contentStrategy: ContentStrategy<T>,
): T
```
- `contentStrategy` 是方法的重要参数,已经在上方进行说明.
- 根据给定的策略返回 `HTMLScriptElement` 或 `HTMLStyleElement`.
### removeContent
```js
removeContent(element: HTMLScriptElement | HTMLStyleElement): void
```
- `element` 参数是已插入的 `HTMLScriptElement` 或 `HTMLStyleElement` 元素,它们应由 `insertContent` 方法返回.
## 下一步是什么?
- [ContentProjectionService](./Content-Projection-Service.md)

80
docs/zh-Hans/UI/Angular/Permission-Management.md

@ -1,3 +1,79 @@
# Permission Management # 权限管理
TODO... 权限是为特定用户,角色或客户端授予或禁止的简单策略. 你可以在[ABP授权文档](../../Authorization.md)中阅读更多信息.
您可以使用 `ConfigState` 的 `getGrantedPolicy` 选择器获取经过身份验证的用户的权限.
你可以从Store中获取权限的布尔值:
```js
import { Store } from '@ngxs/store';
import { ConfigState } from '../states';
export class YourComponent {
constructor(private store: Store) {}
ngOnInit(): void {
const canCreate = this.store.selectSnapshot(ConfigState.getGrantedPolicy('AbpIdentity.Roles.Create'));
}
// ...
}
```
或者你可以通过 `ConfigStateService` 获取它:
```js
import { ConfigStateService } from '../services/config-state.service';
export class YourComponent {
constructor(private configStateService: ConfigStateService) {}
ngOnInit(): void {
const canCreate = this.configStateService.getGrantedPolicy('AbpIdentity.Roles.Create');
}
// ...
}
```
## 权限指令
你可以使用 `PermissionDirective` 来根据用户的权限控制DOM元素是否可见.
```html
<div *abpPermission="AbpIdentity.Roles">
仅当用户具有`AbpIdentity.Roles`权限时,此内容才可见.
</div>
```
如上所示,你可以使用 `abpPermission` 结构指令从DOM中删除元素.
该指令也可以用作属性指令,但是我们建议你将其用作结构指令.
## 权限守卫
如果你想要在导航过程中控制经过身份验证的用户对路由的访问权限,可以使用 `PermissionGuard`.
将 `requiredPolicy` 添加到路由模块中的 `routes`属性.
```js
const routes: Routes = [
{
path: 'path',
component: YourComponent,
canActivate: [PermissionGuard],
data: {
routes: {
requiredPolicy: 'AbpIdentity.Roles.Create',
},
},
},
];
```
授予的策略存储在 `ConfigState` 的 `auth` 属性中.
## 下一步是什么?
* [Config State](./Config-State.md)

8
docs/zh-Hans/UI/AspNetCore/Tag-Helpers/Index.md

@ -12,18 +12,18 @@ ABP框架还向标准bootstrap组件添加了一些**实用的功能**.
这里是ABP框架包装的组件列表: 这里是ABP框架包装的组件列表:
* [Alerts](Alerts.md)
* [Buttons](Buttons.md) * [Buttons](Buttons.md)
* [Cards](Cards.md) * [Cards](Cards.md)
* [Alerts](Alerts.md)
* [Tabs](Tabs.md)
* [Grids](Grids.md)
* [Modals](Modals.md)
* [Collapse](Collapse.md) * [Collapse](Collapse.md)
* [Dropdowns](Dropdowns.md) * [Dropdowns](Dropdowns.md)
* [Grids](Grids.md)
* [List Groups](List-Groups.md) * [List Groups](List-Groups.md)
* [Modals](Modals.md)
* [Paginator](Paginator.md) * [Paginator](Paginator.md)
* [Popovers](Popovers.md) * [Popovers](Popovers.md)
* [Progress Bars](Progress-Bars.md) * [Progress Bars](Progress-Bars.md)
* [Tabs](Tabs.md)
* [Tooltips](Tooltips.md) * [Tooltips](Tooltips.md)
* ... * ...

BIN
docs/zh-Hans/images/bookstore-home.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/zh-Hans/images/bookstore-login.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/zh-Hans/images/db-migrator-output.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/zh-Hans/images/package-manager-console-update-database.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/zh-Hans/images/rn-environment-local-ip.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
docs/zh-Hans/images/rn-expo-interface.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
docs/zh-Hans/images/rn-host-local-ip.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

BIN
docs/zh-Hans/images/rn-login-iphone.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
docs/zh-Hans/images/rn-tiered-local-ip.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
docs/zh-Hans/images/solution-files-mvc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

BIN
docs/zh-Hans/images/solution-files-non-mvc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
docs/zh-Hans/images/swagger-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
docs/zh-Hans/images/vs-app-solution-structure-mongodb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

BIN
docs/zh-Hans/images/vs-app-solution-structure-tiered.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

BIN
docs/zh-Hans/images/vs-app-solution-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

BIN
docs/zh-Hans/images/vs-spa-app-backend-structure-mongodb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

BIN
docs/zh-Hans/images/vs-spa-app-backend-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

2
framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj

@ -15,7 +15,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.8" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.7.11" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

600
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js

@ -0,0 +1,600 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('just-compare')) :
typeof define === 'function' && define.amd ? define('@abp/utils', ['exports', 'just-compare'], factory) :
(global = global || self, factory((global.abp = global.abp || {}, global.abp.utils = global.abp.utils || {}, global.abp.utils.common = {}), global.compare));
}(this, (function (exports, compare) { 'use strict';
compare = compare && Object.prototype.hasOwnProperty.call(compare, 'default') ? compare['default'] : compare;
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __exportStar(m, exports) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function __importStar(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result.default = mod;
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
function __classPrivateFieldGet(receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
}
function __classPrivateFieldSet(receiver, privateMap, value) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
privateMap.set(receiver, value);
return value;
}
/* tslint:disable:no-non-null-assertion */
var ListNode = /** @class */ (function () {
function ListNode(value) {
this.value = value;
}
return ListNode;
}());
var LinkedList = /** @class */ (function () {
function LinkedList() {
this.size = 0;
}
Object.defineProperty(LinkedList.prototype, "head", {
get: function () {
return this.first;
},
enumerable: true,
configurable: true
});
Object.defineProperty(LinkedList.prototype, "tail", {
get: function () {
return this.last;
},
enumerable: true,
configurable: true
});
Object.defineProperty(LinkedList.prototype, "length", {
get: function () {
return this.size;
},
enumerable: true,
configurable: true
});
LinkedList.prototype.attach = function (value, previousNode, nextNode) {
if (!previousNode)
return this.addHead(value);
if (!nextNode)
return this.addTail(value);
var node = new ListNode(value);
node.previous = previousNode;
previousNode.next = node;
node.next = nextNode;
nextNode.previous = node;
this.size++;
return node;
};
LinkedList.prototype.attachMany = function (values, previousNode, nextNode) {
if (!values.length)
return [];
if (!previousNode)
return this.addManyHead(values);
if (!nextNode)
return this.addManyTail(values);
var list = new LinkedList();
list.addManyTail(values);
list.first.previous = previousNode;
previousNode.next = list.first;
list.last.next = nextNode;
nextNode.previous = list.last;
this.size += values.length;
return list.toNodeArray();
};
LinkedList.prototype.detach = function (node) {
if (!node.previous)
return this.dropHead();
if (!node.next)
return this.dropTail();
node.previous.next = node.next;
node.next.previous = node.previous;
this.size--;
return node;
};
LinkedList.prototype.add = function (value) {
var _this = this;
return {
after: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addAfter).call.apply(_a, __spread([_this, value], params));
},
before: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addBefore).call.apply(_a, __spread([_this, value], params));
},
byIndex: function (position) { return _this.addByIndex(value, position); },
head: function () { return _this.addHead(value); },
tail: function () { return _this.addTail(value); },
};
};
LinkedList.prototype.addMany = function (values) {
var _this = this;
return {
after: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addManyAfter).call.apply(_a, __spread([_this, values], params));
},
before: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addManyBefore).call.apply(_a, __spread([_this, values], params));
},
byIndex: function (position) { return _this.addManyByIndex(values, position); },
head: function () { return _this.addManyHead(values); },
tail: function () { return _this.addManyTail(values); },
};
};
LinkedList.prototype.addAfter = function (value, previousValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var previous = this.find(function (node) { return compareFn(node.value, previousValue); });
return previous ? this.attach(value, previous, previous.next) : this.addTail(value);
};
LinkedList.prototype.addBefore = function (value, nextValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var next = this.find(function (node) { return compareFn(node.value, nextValue); });
return next ? this.attach(value, next.previous, next) : this.addHead(value);
};
LinkedList.prototype.addByIndex = function (value, position) {
if (position < 0)
position += this.size;
else if (position >= this.size)
return this.addTail(value);
if (position <= 0)
return this.addHead(value);
var next = this.get(position);
return this.attach(value, next.previous, next);
};
LinkedList.prototype.addHead = function (value) {
var node = new ListNode(value);
node.next = this.first;
if (this.first)
this.first.previous = node;
else
this.last = node;
this.first = node;
this.size++;
return node;
};
LinkedList.prototype.addTail = function (value) {
var node = new ListNode(value);
if (this.first) {
node.previous = this.last;
this.last.next = node;
this.last = node;
}
else {
this.first = node;
this.last = node;
}
this.size++;
return node;
};
LinkedList.prototype.addManyAfter = function (values, previousValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var previous = this.find(function (node) { return compareFn(node.value, previousValue); });
return previous ? this.attachMany(values, previous, previous.next) : this.addManyTail(values);
};
LinkedList.prototype.addManyBefore = function (values, nextValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var next = this.find(function (node) { return compareFn(node.value, nextValue); });
return next ? this.attachMany(values, next.previous, next) : this.addManyHead(values);
};
LinkedList.prototype.addManyByIndex = function (values, position) {
if (position < 0)
position += this.size;
if (position <= 0)
return this.addManyHead(values);
if (position >= this.size)
return this.addManyTail(values);
var next = this.get(position);
return this.attachMany(values, next.previous, next);
};
LinkedList.prototype.addManyHead = function (values) {
var _this = this;
return values.reduceRight(function (nodes, value) {
nodes.unshift(_this.addHead(value));
return nodes;
}, []);
};
LinkedList.prototype.addManyTail = function (values) {
var _this = this;
return values.map(function (value) { return _this.addTail(value); });
};
LinkedList.prototype.drop = function () {
var _this = this;
return {
byIndex: function (position) { return _this.dropByIndex(position); },
byValue: function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return _this.dropByValue.apply(_this, params);
},
byValueAll: function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return _this.dropByValueAll.apply(_this, params);
},
head: function () { return _this.dropHead(); },
tail: function () { return _this.dropTail(); },
};
};
LinkedList.prototype.dropMany = function (count) {
var _this = this;
return {
byIndex: function (position) { return _this.dropManyByIndex(count, position); },
head: function () { return _this.dropManyHead(count); },
tail: function () { return _this.dropManyTail(count); },
};
};
LinkedList.prototype.dropByIndex = function (position) {
if (position < 0)
position += this.size;
var current = this.get(position);
return current ? this.detach(current) : undefined;
};
LinkedList.prototype.dropByValue = function (value, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var position = this.findIndex(function (node) { return compareFn(node.value, value); });
return position < 0 ? undefined : this.dropByIndex(position);
};
LinkedList.prototype.dropByValueAll = function (value, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var dropped = [];
for (var current = this.first, position = 0; current; position++, current = current.next) {
if (compareFn(current.value, value)) {
dropped.push(this.dropByIndex(position - dropped.length));
}
}
return dropped;
};
LinkedList.prototype.dropHead = function () {
var head = this.first;
if (head) {
this.first = head.next;
if (this.first)
this.first.previous = undefined;
else
this.last = undefined;
this.size--;
return head;
}
return undefined;
};
LinkedList.prototype.dropTail = function () {
var tail = this.last;
if (tail) {
this.last = tail.previous;
if (this.last)
this.last.next = undefined;
else
this.first = undefined;
this.size--;
return tail;
}
return undefined;
};
LinkedList.prototype.dropManyByIndex = function (count, position) {
if (count <= 0)
return [];
if (position < 0)
position = Math.max(position + this.size, 0);
else if (position >= this.size)
return [];
count = Math.min(count, this.size - position);
var dropped = [];
while (count--) {
var current = this.get(position);
dropped.push(this.detach(current));
}
return dropped;
};
LinkedList.prototype.dropManyHead = function (count) {
if (count <= 0)
return [];
count = Math.min(count, this.size);
var dropped = [];
while (count--)
dropped.unshift(this.dropHead());
return dropped;
};
LinkedList.prototype.dropManyTail = function (count) {
if (count <= 0)
return [];
count = Math.min(count, this.size);
var dropped = [];
while (count--)
dropped.push(this.dropTail());
return dropped;
};
LinkedList.prototype.find = function (predicate) {
for (var current = this.first, position = 0; current; position++, current = current.next) {
if (predicate(current, position, this))
return current;
}
return undefined;
};
LinkedList.prototype.findIndex = function (predicate) {
for (var current = this.first, position = 0; current; position++, current = current.next) {
if (predicate(current, position, this))
return position;
}
return -1;
};
LinkedList.prototype.forEach = function (callback) {
for (var node = this.first, position = 0; node; position++, node = node.next) {
callback(node, position, this);
}
};
LinkedList.prototype.get = function (position) {
return this.find(function (_, index) { return position === index; });
};
LinkedList.prototype.indexOf = function (value, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
return this.findIndex(function (node) { return compareFn(node.value, value); });
};
LinkedList.prototype.toArray = function () {
var array = new Array(this.size);
this.forEach(function (node, index) { return (array[index] = node.value); });
return array;
};
LinkedList.prototype.toNodeArray = function () {
var array = new Array(this.size);
this.forEach(function (node, index) { return (array[index] = node); });
return array;
};
LinkedList.prototype.toString = function (mapperFn) {
if (mapperFn === void 0) { mapperFn = JSON.stringify; }
return this.toArray()
.map(function (value) { return mapperFn(value); })
.join(' <-> ');
};
// Cannot use Generator type because of ng-packagr
LinkedList.prototype[Symbol.iterator] = function () {
var node, position;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
node = this.first, position = 0;
_a.label = 1;
case 1:
if (!node) return [3 /*break*/, 4];
return [4 /*yield*/, node.value];
case 2:
_a.sent();
_a.label = 3;
case 3:
position++, node = node.next;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
return LinkedList;
}());
exports.LinkedList = LinkedList;
exports.ListNode = ListNode;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=abp-utils.umd.js.map

1
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js.map

File diff suppressed because one or more lines are too long

2
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js

File diff suppressed because one or more lines are too long

1
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js.map

File diff suppressed because one or more lines are too long

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/AbpAspNetCoreMvcUiThemeBasicDemoModule.cs

@ -1,13 +1,13 @@
using System.IO; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using System.IO;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Menus;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.UI;
using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;

58
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/BasicThemeDemoMenuContributor.cs

@ -1,58 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo
{
public class BasicThemeDemoMenuContributor : IMenuContributor
{
public Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if(context.Menu.Name == StandardMenus.Main)
{
AddMainMenuItems(context);
}
return Task.CompletedTask;
}
private void AddMainMenuItems(MenuConfigurationContext context)
{
var menuItem = new ApplicationMenuItem("BasicThemeDemo.Components", "Components");
var items = new List<ApplicationMenuItem>()
{
new ApplicationMenuItem("BasicThemeDemo.Components.Alerts", "Alerts", url: "/Components/Alerts"),
new ApplicationMenuItem("BasicThemeDemo.Components.Badges", "Badges", url: "/Components/Badges"),
new ApplicationMenuItem("BasicThemeDemo.Components.Borders", "Borders", url: "/Components/Borders"),
new ApplicationMenuItem("BasicThemeDemo.Components.Breadcrumbs", "Breadcrumbs", url: "/Components/Breadcrumbs"),
new ApplicationMenuItem("BasicThemeDemo.Components.Buttons", "Buttons", url: "/Components/Buttons"),
new ApplicationMenuItem("BasicThemeDemo.Components.ButtonGroups", "ButtonGroups", url: "/Components/ButtonGroups"),
new ApplicationMenuItem("BasicThemeDemo.Components.Cards", "Cards", url: "/Components/Cards"),
new ApplicationMenuItem("BasicThemeDemo.Components.Carousel", "Carousel", url: "/Components/Carousel"),
new ApplicationMenuItem("BasicThemeDemo.Components.Collapse", "Collapse", url: "/Components/Collapse"),
new ApplicationMenuItem("BasicThemeDemo.Components.Dropdowns", "Dropdowns", url: "/Components/Dropdowns"),
new ApplicationMenuItem("BasicThemeDemo.Components.DynamicForms", "DynamicForms", url: "/Components/DynamicForms"),
new ApplicationMenuItem("BasicThemeDemo.Components.FormElements", "FormElements", url: "/Components/FormElements"),
new ApplicationMenuItem("BasicThemeDemo.Components.Grids", "Grids", url: "/Components/Grids"),
new ApplicationMenuItem("BasicThemeDemo.Components.ListGroups", "List Groups", url: "/Components/ListGroups"),
new ApplicationMenuItem("BasicThemeDemo.Components.Modals", "Modals", url: "/Components/Modals"),
new ApplicationMenuItem("BasicThemeDemo.Components.Navs", "Navs", url: "/Components/Navs"),
new ApplicationMenuItem("BasicThemeDemo.Components.Navbars", "Navbars", url: "/Components/Navbars"),
new ApplicationMenuItem("BasicThemeDemo.Components.Paginator", "Paginator", url: "/Components/Paginator"),
new ApplicationMenuItem("BasicThemeDemo.Components.Popovers", "Popovers", url: "/Components/Popovers"),
new ApplicationMenuItem("BasicThemeDemo.Components.ProgressBars", "Progress Bars", url: "/Components/ProgressBars"),
new ApplicationMenuItem("BasicThemeDemo.Components.Tables", "Tables", url: "/Components/Tables"),
new ApplicationMenuItem("BasicThemeDemo.Components.Tabs", "Tabs", url: "/Components/Tabs"),
new ApplicationMenuItem("BasicThemeDemo.Components.Tooltips", "Tooltips", url: "/Components/Tooltips")
};
items.OrderBy(x => x.Name)
.ToList()
.ForEach(x => menuItem.AddItem(x));
context.Menu.AddItem(menuItem);
}
}
}

58
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Menus/BasicThemeDemoMenuContributor.cs

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Menus
{
public class BasicThemeDemoMenuContributor : IMenuContributor
{
public Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if(context.Menu.Name == StandardMenus.Main)
{
AddMainMenuItems(context);
}
return Task.CompletedTask;
}
private void AddMainMenuItems(MenuConfigurationContext context)
{
var menuItem = new ApplicationMenuItem(BasicThemeDemoMenus.Components.Root, "Components");
var items = new List<ApplicationMenuItem>()
{
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Alerts, "Alerts", url: "/Components/Alerts"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Badges, "Badges", url: "/Components/Badges"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Borders, "Borders", url: "/Components/Borders"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Breadcrumbs, "Breadcrumbs", url: "/Components/Breadcrumbs"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Buttons, "Buttons", url: "/Components/Buttons"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.ButtonGroups, "Button Groups", url: "/Components/ButtonGroups"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Cards, "Cards", url: "/Components/Cards"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Carousel, "Carousel", url: "/Components/Carousel"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Collapse, "Collapse", url: "/Components/Collapse"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Dropdowns, "Dropdowns", url: "/Components/Dropdowns"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.DynamicForms, "Dynamic Forms", url: "/Components/DynamicForms"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.FormElements, "Form Elements", url: "/Components/FormElements"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Grids, "Grids", url: "/Components/Grids"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.ListGroups, "List Groups", url: "/Components/ListGroups"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Modals, "Modals", url: "/Components/Modals"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Navs, "Navs", url: "/Components/Navs"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Navbars, "Navbars", url: "/Components/Navbars"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Paginator, "Paginator", url: "/Components/Paginator"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Popovers, "Popovers", url: "/Components/Popovers"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.ProgressBars, "Progress Bars", url: "/Components/ProgressBars"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Tables, "Tables", url: "/Components/Tables"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Tabs, "Tabs", url: "/Components/Tabs"),
new ApplicationMenuItem(BasicThemeDemoMenus.Components.Tooltips, "Tooltips", url: "/Components/Tooltips")
};
items.OrderBy(x => x.Name)
.ToList()
.ForEach(x => menuItem.AddItem(x));
context.Menu.AddItem(menuItem);
}
}
}

36
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Menus/BasicThemeDemoMenus.cs

@ -0,0 +1,36 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Menus
{
public class BasicThemeDemoMenus
{
private const string Prefix = "BasicThemeDemo";
public const string Home = Prefix + ".Home";
public static class Components
{
public const string Root = Prefix + ".Components";
public const string Alerts = Root + ".Alerts";
public const string Badges = Root + ".Badges";
public const string Borders = Root + ".Borders";
public const string Breadcrumbs = Root + ".Breadcrumbs";
public const string ButtonGroups = Root + ".ButtonGroups";
public const string Buttons = Root + ".Buttons";
public const string Cards = Root + ".Cards";
public const string Carousel = Root + ".Carousel";
public const string Collapse = Root + ".Collapse";
public const string Dropdowns = Root + ".Dropdowns";
public const string DynamicForms = Root + ".DynamicForms";
public const string FormElements = Root + ".FormElements";
public const string Grids = Root + ".Grids";
public const string ListGroups = Root + ".ListGroups";
public const string Modals = Root + ".Modals";
public const string Navbars = Root + ".Navbars";
public const string Navs = Root + ".Navs";
public const string Paginator = Root + ".Paginator";
public const string Popovers = Root + ".Popovers";
public const string ProgressBars = Root + ".ProgressBars";
public const string Tables = Root + ".Tables";
public const string Tabs = Root + ".Tabs";
public const string Tooltips = Root + ".Tooltips";
}
}
}

7
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Alerts/Index.cshtml

@ -1,7 +1,14 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.AlertsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.AlertsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Alerts.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Alerts.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Alerts";
}
<h2>Alerts</h2> <h2>Alerts</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/alerts/" target="_blank"> Bootstrap Alert</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/alerts/" target="_blank"> Bootstrap Alert</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Alerts" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(AlertsDemoViewComponent)) @await Component.InvokeAsync(typeof(AlertsDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Badges/Index.cshtml

@ -1,7 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BadgesDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BadgesDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Badges.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Badges.IndexModel
<h2>Badges</h2> <h2>Badges</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/badge/" target="_blank"> Bootstrap Badge</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/badge/" target="_blank"> Bootstrap Badge</a>.</p>
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Badges";
}
@await Component.InvokeAsync(typeof(BadgesDemoViewComponent)) @await Component.InvokeAsync(typeof(BadgesDemoViewComponent))

19
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Borders/Index.cshtml

@ -1,15 +1,20 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BordersDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BordersDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Borders.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Borders.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Borders";
}
<h2>Borders</h2> <h2>Borders</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/border/" target="_blank"> Bootstrap Border</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/border/" target="_blank"> Bootstrap Border</a>.</p>
<style> <style>
span { span {
display: inline-block; display: inline-block;
width: 5rem; width: 5rem;
height: 5rem; height: 5rem;
margin: .25rem; margin: .25rem;
background-color: #f5f5f5; background-color: #f5f5f5;
} }
</style> </style>
@await Component.InvokeAsync(typeof(BordersDemoViewComponent)) @await Component.InvokeAsync(typeof(BordersDemoViewComponent))

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Breadcrumbs/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BreadcrumbsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.BreadcrumbsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Breadcrumbs.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Breadcrumbs.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Breadcrumbs";
}
<h2>Breadcrumbs</h2> <h2>Breadcrumbs</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/breadcrumbs/" target="_blank"> Bootstrap Breadcrumb</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/breadcrumbs/" target="_blank"> Bootstrap Breadcrumb</a>.</p>

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/ButtonGroups/Index.cshtml

@ -1,6 +1,12 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ButtonGroupsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ButtonGroupsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.ButtonGroups.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.ButtonGroups.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Button Groups";
}
<h2>Button Groups</h2> <h2>Button Groups</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/button-group/" target="_blank"> Bootstrap Button group</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/button-group/" target="_blank"> Bootstrap Button group</a>.</p>

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Buttons/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ButtonsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ButtonsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Buttons.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Buttons.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Buttons";
}
<h1>Buttons</h1> <h1>Buttons</h1>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/buttons/" target="_blank"> Bootstrap Buttons</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/buttons/" target="_blank"> Bootstrap Buttons</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Buttons" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(ButtonsDemoViewComponent)) @await Component.InvokeAsync(typeof(ButtonsDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Cards/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CardsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CardsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Cards.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Cards.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Cards";
}
<h2>Cards</h2> <h2>Cards</h2>
<p>Based on <a href="http://getbootstrap.com/docs/4.1/components/card/" target="_blank"> Bootstrap card</a>.</p> <p>Based on <a href="http://getbootstrap.com/docs/4.1/components/card/" target="_blank"> Bootstrap card</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Cards" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(CardsDemoViewComponent)) @await Component.InvokeAsync(typeof(CardsDemoViewComponent))

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Carousel/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CarouselDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CarouselDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Carousel.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Carousel.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Carousel";
}
<h2>Carousel</h2> <h2>Carousel</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.0/components/carousel/" target="_blank"> Bootstrap carousel</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.0/components/carousel/" target="_blank"> Bootstrap carousel</a>.</p>

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Collapse/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CollapseDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.CollapseDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Collapse.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Collapse.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Collapse";
}
<h2>Collapse</h2> <h2>Collapse</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/collapse/" target="_blank"> Bootstrap Collapse</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/collapse/" target="_blank"> Bootstrap Collapse</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Collapse" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(CollapseDemoViewComponent)) @await Component.InvokeAsync(typeof(CollapseDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Dropdowns/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.DropdownsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.DropdownsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Dropdowns.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Dropdowns.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "DrowDowns";
}
<h2>Cards</h2> <h2>Cards</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/dropdowns/" target="_blank"> Bootstrap button</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/dropdowns/" target="_blank"> Bootstrap button</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Dropdowns" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(DropdownsDemoViewComponent)) @await Component.InvokeAsync(typeof(DropdownsDemoViewComponent))

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/DynamicForms/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.DynamicFormsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.DynamicFormsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.DynamicForms.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.DynamicForms.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "DynamicForms";
}
<h2>Dynamic Forms</h2> <h2>Dynamic Forms</h2>
@await Component.InvokeAsync(typeof(DynamicFormsDemoViewComponent)) @await Component.InvokeAsync(typeof(DynamicFormsDemoViewComponent))

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/FormElements/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.FormElementsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.FormElementsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.FormElements.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.FormElements.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Form Elements";
}
<h2>Form Elements</h2> <h2>Form Elements</h2>
@await Component.InvokeAsync(typeof(FormElementsDemoViewComponent)) @await Component.InvokeAsync(typeof(FormElementsDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Grids/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.GridsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.GridsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Grids.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Grids.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Grids";
}
<h2>Grids</h2> <h2>Grids</h2>
<p>Based on <a href="http://getbootstrap.com/docs/4.1/layout/grid/" target="_blank"> Bootstrap grid</a>.</p> <p>Based on <a href="http://getbootstrap.com/docs/4.1/layout/grid/" target="_blank"> Bootstrap grid</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Grids" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(GridsDemoViewComponent)) @await Component.InvokeAsync(typeof(GridsDemoViewComponent))

22
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Index.cshtml

@ -0,0 +1,22 @@
@page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Menus
@using Volo.Abp.UI.Navigation
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Components";
}
<h1>Components</h1>
Here is the ABP Component List
<ul>
@foreach (var menu in (await Model._menuManager.GetAsync(StandardMenus.Main)).Items.First(x => x.Name == BasicThemeDemoMenus.Components.Root).Items)
{
<li><a href="@menu.Url">@menu.DisplayName</a></li>
}
</ul>

22
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Index.cshtml.cs

@ -0,0 +1,22 @@
using System.Linq;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Menus;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components
{
public class IndexModel : AbpPageModel
{
public readonly IMenuManager _menuManager;
public IndexModel(IMenuManager menuManager)
{
_menuManager = menuManager;
}
public void OnGet()
{
}
}
}

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/ListGroups/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ListGroupsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ListGroupsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.ListGroups.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.ListGroups.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "List Groups";
}
<h2>List Groups</h2> <h2>List Groups</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/list-group/" target="_blank"> Bootstrap List Group</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/list-group/" target="_blank"> Bootstrap List Group</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/List-Groups" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(ListGroupsDemoViewComponent)) @await Component.InvokeAsync(typeof(ListGroupsDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Modals/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ModalsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ModalsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Modals.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Modals.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Modals";
}
<h2>Modals</h2> <h2>Modals</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/modal/" target="_blank"> Bootstrap Modal</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/modal/" target="_blank"> Bootstrap Modal</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Modals" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(ModalsDemoViewComponent)) @await Component.InvokeAsync(typeof(ModalsDemoViewComponent))

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Navbars/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.NavbarsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.NavbarsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Modals.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Modals.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Navbars";
}
<h2>Navbars</h2> <h2>Navbars</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/navbar/" target="_blank"> Bootstrap Navbar</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/navbar/" target="_blank"> Bootstrap Navbar</a>.</p>

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Navs/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.NavsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.NavsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Navs.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Navs.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Navs";
}
<h2>Navs</h2> <h2>Navs</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/navs/" target="_blank"> Bootstrap Navs</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/navs/" target="_blank"> Bootstrap Navs</a>.</p>

8
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Paginator/Index.cshtml

@ -1,8 +1,12 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.PaginatorDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.PaginatorDemo
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Paginator @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Paginator
@model IndexModel @model IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Paginator";
}
@section scripts { @section scripts {
<abp-script-bundle name="@typeof(IndexModel).FullName"> <abp-script-bundle name="@typeof(IndexModel).FullName">
<abp-script src="/Pages/Components/Paginator/index.js" /> <abp-script src="/Pages/Components/Paginator/index.js" />
@ -11,4 +15,6 @@
<h2>Paginator</h2> <h2>Paginator</h2>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Paginator" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(PaginatorDemoViewComponent), new { pagerModel = Model.PagerModel }) @await Component.InvokeAsync(typeof(PaginatorDemoViewComponent), new { pagerModel = Model.PagerModel })

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Popovers/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.PopoversDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.PopoversDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Popovers.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Popovers.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Popovers";
}
<h2>Popovers</h2> <h2>Popovers</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/Popovers/" target="_blank"> Bootstrap Popovers</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/Popovers/" target="_blank"> Bootstrap Popovers</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Popovers" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(PopoversDemoViewComponent)) @await Component.InvokeAsync(typeof(PopoversDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/ProgressBars/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ProgressBarsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.ProgressBarsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.ProgressBars.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.ProgressBars.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Progress Bars";
}
<h2>Progress Bars</h2> <h2>Progress Bars</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/progress/" target="_blank"> Bootstrap Progress Bars</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/progress/" target="_blank"> Bootstrap Progress Bars</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Progress-Bars" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(ProgressBarsDemoViewComponent)) @await Component.InvokeAsync(typeof(ProgressBarsDemoViewComponent))

5
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Tables/Index.cshtml

@ -1,6 +1,11 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TablesDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TablesDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Tables.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Tables.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Tables";
}
<h2>Tables</h2> <h2>Tables</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/content/Tables/" target="_blank"> Bootstrap Tables</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/content/Tables/" target="_blank"> Bootstrap Tables</a>.</p>

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Tabs/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TabsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TabsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Tabs.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Tabs.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Tabs";
}
<h2>Tabs</h2> <h2>Tabs</h2>
<p>Based on <a href="http://getbootstrap.com/docs/4.1/components/navs/#tabs" target="_blank"> Bootstrap tab</a>.</p> <p>Based on <a href="http://getbootstrap.com/docs/4.1/components/navs/#tabs" target="_blank"> Bootstrap tab</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Tabs" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(TabsDemoViewComponent)) @await Component.InvokeAsync(typeof(TabsDemoViewComponent))

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Components/Tooltips/Index.cshtml

@ -1,7 +1,13 @@
@page @page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TooltipsDemo @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.Shared.Demos.TooltipsDemo
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Tooltips.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.Components.Tooltips.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = "Tooltips";
}
<h2>Tooltips</h2> <h2>Tooltips</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/tooltips/" target="_blank"> Bootstrap Tooltips</a>.</p> <p>Based on <a href="https://getbootstrap.com/docs/4.1/components/tooltips/" target="_blank"> Bootstrap Tooltips</a>.</p>
<p>Check the <a href="https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Tooltips" target="_blank">ABP Documentation</a>.</p>
@await Component.InvokeAsync(typeof(TooltipsDemoViewComponent)) @await Component.InvokeAsync(typeof(TooltipsDemoViewComponent))

4
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Pages/Index.cshtml

@ -1,3 +1,5 @@
@page @page
@model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.IndexModel @model Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.Pages.IndexModel
<h1>Basic Theme Demo</h1> <h1>Basic Theme Demo</h1>
<p>Check the <a href="/Components">Components</a>.</p>

2
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Program.cs

@ -12,7 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo
{ {
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug() .MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext() .Enrich.FromLogContext()
.WriteTo.File("Logs/logs.txt") .WriteTo.File("Logs/logs.txt")
.CreateLogger(); .CreateLogger();

600
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js

@ -0,0 +1,600 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('just-compare')) :
typeof define === 'function' && define.amd ? define('@abp/utils', ['exports', 'just-compare'], factory) :
(global = global || self, factory((global.abp = global.abp || {}, global.abp.utils = global.abp.utils || {}, global.abp.utils.common = {}), global.compare));
}(this, (function (exports, compare) { 'use strict';
compare = compare && Object.prototype.hasOwnProperty.call(compare, 'default') ? compare['default'] : compare;
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __exportStar(m, exports) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function __importStar(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result.default = mod;
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
function __classPrivateFieldGet(receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
}
function __classPrivateFieldSet(receiver, privateMap, value) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
privateMap.set(receiver, value);
return value;
}
/* tslint:disable:no-non-null-assertion */
var ListNode = /** @class */ (function () {
function ListNode(value) {
this.value = value;
}
return ListNode;
}());
var LinkedList = /** @class */ (function () {
function LinkedList() {
this.size = 0;
}
Object.defineProperty(LinkedList.prototype, "head", {
get: function () {
return this.first;
},
enumerable: true,
configurable: true
});
Object.defineProperty(LinkedList.prototype, "tail", {
get: function () {
return this.last;
},
enumerable: true,
configurable: true
});
Object.defineProperty(LinkedList.prototype, "length", {
get: function () {
return this.size;
},
enumerable: true,
configurable: true
});
LinkedList.prototype.attach = function (value, previousNode, nextNode) {
if (!previousNode)
return this.addHead(value);
if (!nextNode)
return this.addTail(value);
var node = new ListNode(value);
node.previous = previousNode;
previousNode.next = node;
node.next = nextNode;
nextNode.previous = node;
this.size++;
return node;
};
LinkedList.prototype.attachMany = function (values, previousNode, nextNode) {
if (!values.length)
return [];
if (!previousNode)
return this.addManyHead(values);
if (!nextNode)
return this.addManyTail(values);
var list = new LinkedList();
list.addManyTail(values);
list.first.previous = previousNode;
previousNode.next = list.first;
list.last.next = nextNode;
nextNode.previous = list.last;
this.size += values.length;
return list.toNodeArray();
};
LinkedList.prototype.detach = function (node) {
if (!node.previous)
return this.dropHead();
if (!node.next)
return this.dropTail();
node.previous.next = node.next;
node.next.previous = node.previous;
this.size--;
return node;
};
LinkedList.prototype.add = function (value) {
var _this = this;
return {
after: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addAfter).call.apply(_a, __spread([_this, value], params));
},
before: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addBefore).call.apply(_a, __spread([_this, value], params));
},
byIndex: function (position) { return _this.addByIndex(value, position); },
head: function () { return _this.addHead(value); },
tail: function () { return _this.addTail(value); },
};
};
LinkedList.prototype.addMany = function (values) {
var _this = this;
return {
after: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addManyAfter).call.apply(_a, __spread([_this, values], params));
},
before: function () {
var _a;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return (_a = _this.addManyBefore).call.apply(_a, __spread([_this, values], params));
},
byIndex: function (position) { return _this.addManyByIndex(values, position); },
head: function () { return _this.addManyHead(values); },
tail: function () { return _this.addManyTail(values); },
};
};
LinkedList.prototype.addAfter = function (value, previousValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var previous = this.find(function (node) { return compareFn(node.value, previousValue); });
return previous ? this.attach(value, previous, previous.next) : this.addTail(value);
};
LinkedList.prototype.addBefore = function (value, nextValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var next = this.find(function (node) { return compareFn(node.value, nextValue); });
return next ? this.attach(value, next.previous, next) : this.addHead(value);
};
LinkedList.prototype.addByIndex = function (value, position) {
if (position < 0)
position += this.size;
else if (position >= this.size)
return this.addTail(value);
if (position <= 0)
return this.addHead(value);
var next = this.get(position);
return this.attach(value, next.previous, next);
};
LinkedList.prototype.addHead = function (value) {
var node = new ListNode(value);
node.next = this.first;
if (this.first)
this.first.previous = node;
else
this.last = node;
this.first = node;
this.size++;
return node;
};
LinkedList.prototype.addTail = function (value) {
var node = new ListNode(value);
if (this.first) {
node.previous = this.last;
this.last.next = node;
this.last = node;
}
else {
this.first = node;
this.last = node;
}
this.size++;
return node;
};
LinkedList.prototype.addManyAfter = function (values, previousValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var previous = this.find(function (node) { return compareFn(node.value, previousValue); });
return previous ? this.attachMany(values, previous, previous.next) : this.addManyTail(values);
};
LinkedList.prototype.addManyBefore = function (values, nextValue, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var next = this.find(function (node) { return compareFn(node.value, nextValue); });
return next ? this.attachMany(values, next.previous, next) : this.addManyHead(values);
};
LinkedList.prototype.addManyByIndex = function (values, position) {
if (position < 0)
position += this.size;
if (position <= 0)
return this.addManyHead(values);
if (position >= this.size)
return this.addManyTail(values);
var next = this.get(position);
return this.attachMany(values, next.previous, next);
};
LinkedList.prototype.addManyHead = function (values) {
var _this = this;
return values.reduceRight(function (nodes, value) {
nodes.unshift(_this.addHead(value));
return nodes;
}, []);
};
LinkedList.prototype.addManyTail = function (values) {
var _this = this;
return values.map(function (value) { return _this.addTail(value); });
};
LinkedList.prototype.drop = function () {
var _this = this;
return {
byIndex: function (position) { return _this.dropByIndex(position); },
byValue: function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return _this.dropByValue.apply(_this, params);
},
byValueAll: function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return _this.dropByValueAll.apply(_this, params);
},
head: function () { return _this.dropHead(); },
tail: function () { return _this.dropTail(); },
};
};
LinkedList.prototype.dropMany = function (count) {
var _this = this;
return {
byIndex: function (position) { return _this.dropManyByIndex(count, position); },
head: function () { return _this.dropManyHead(count); },
tail: function () { return _this.dropManyTail(count); },
};
};
LinkedList.prototype.dropByIndex = function (position) {
if (position < 0)
position += this.size;
var current = this.get(position);
return current ? this.detach(current) : undefined;
};
LinkedList.prototype.dropByValue = function (value, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var position = this.findIndex(function (node) { return compareFn(node.value, value); });
return position < 0 ? undefined : this.dropByIndex(position);
};
LinkedList.prototype.dropByValueAll = function (value, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
var dropped = [];
for (var current = this.first, position = 0; current; position++, current = current.next) {
if (compareFn(current.value, value)) {
dropped.push(this.dropByIndex(position - dropped.length));
}
}
return dropped;
};
LinkedList.prototype.dropHead = function () {
var head = this.first;
if (head) {
this.first = head.next;
if (this.first)
this.first.previous = undefined;
else
this.last = undefined;
this.size--;
return head;
}
return undefined;
};
LinkedList.prototype.dropTail = function () {
var tail = this.last;
if (tail) {
this.last = tail.previous;
if (this.last)
this.last.next = undefined;
else
this.first = undefined;
this.size--;
return tail;
}
return undefined;
};
LinkedList.prototype.dropManyByIndex = function (count, position) {
if (count <= 0)
return [];
if (position < 0)
position = Math.max(position + this.size, 0);
else if (position >= this.size)
return [];
count = Math.min(count, this.size - position);
var dropped = [];
while (count--) {
var current = this.get(position);
dropped.push(this.detach(current));
}
return dropped;
};
LinkedList.prototype.dropManyHead = function (count) {
if (count <= 0)
return [];
count = Math.min(count, this.size);
var dropped = [];
while (count--)
dropped.unshift(this.dropHead());
return dropped;
};
LinkedList.prototype.dropManyTail = function (count) {
if (count <= 0)
return [];
count = Math.min(count, this.size);
var dropped = [];
while (count--)
dropped.push(this.dropTail());
return dropped;
};
LinkedList.prototype.find = function (predicate) {
for (var current = this.first, position = 0; current; position++, current = current.next) {
if (predicate(current, position, this))
return current;
}
return undefined;
};
LinkedList.prototype.findIndex = function (predicate) {
for (var current = this.first, position = 0; current; position++, current = current.next) {
if (predicate(current, position, this))
return position;
}
return -1;
};
LinkedList.prototype.forEach = function (callback) {
for (var node = this.first, position = 0; node; position++, node = node.next) {
callback(node, position, this);
}
};
LinkedList.prototype.get = function (position) {
return this.find(function (_, index) { return position === index; });
};
LinkedList.prototype.indexOf = function (value, compareFn) {
if (compareFn === void 0) { compareFn = compare; }
return this.findIndex(function (node) { return compareFn(node.value, value); });
};
LinkedList.prototype.toArray = function () {
var array = new Array(this.size);
this.forEach(function (node, index) { return (array[index] = node.value); });
return array;
};
LinkedList.prototype.toNodeArray = function () {
var array = new Array(this.size);
this.forEach(function (node, index) { return (array[index] = node); });
return array;
};
LinkedList.prototype.toString = function (mapperFn) {
if (mapperFn === void 0) { mapperFn = JSON.stringify; }
return this.toArray()
.map(function (value) { return mapperFn(value); })
.join(' <-> ');
};
// Cannot use Generator type because of ng-packagr
LinkedList.prototype[Symbol.iterator] = function () {
var node, position;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
node = this.first, position = 0;
_a.label = 1;
case 1:
if (!node) return [3 /*break*/, 4];
return [4 /*yield*/, node.value];
case 2:
_a.sent();
_a.label = 3;
case 3:
position++, node = node.next;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
return LinkedList;
}());
exports.LinkedList = LinkedList;
exports.ListNode = ListNode;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=abp-utils.umd.js.map

1
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.js.map

File diff suppressed because one or more lines are too long

2
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js

File diff suppressed because one or more lines are too long

1
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/wwwroot/libs/abp/utils/abp-utils.umd.min.js.map

File diff suppressed because one or more lines are too long

2
modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.csproj

@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Hangfire.SqlServer" Version="1.7.8" /> <PackageReference Include="Hangfire.SqlServer" Version="1.7.11" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> <ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.BackgroundJobs.HangFire\Volo.Abp.BackgroundJobs.HangFire.csproj" /> <ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.BackgroundJobs.HangFire\Volo.Abp.BackgroundJobs.HangFire.csproj" />
<ProjectReference Include="..\Volo.Abp.BackgroundJobs.DemoApp.Shared\Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj" /> <ProjectReference Include="..\Volo.Abp.BackgroundJobs.DemoApp.Shared\Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj" />

9
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/ClearCacheInput.cs

@ -0,0 +1,9 @@
using System;
namespace Volo.Docs.Admin.Documents
{
public class ClearCacheInput
{
public Guid ProjectId { get; set; }
}
}

2
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs

@ -5,6 +5,8 @@ namespace Volo.Docs.Admin.Documents
{ {
public interface IDocumentAdminAppService : IApplicationService public interface IDocumentAdminAppService : IApplicationService
{ {
Task ClearCacheAsync(ClearCacheInput input);
Task PullAllAsync(PullAllDocumentInput input); Task PullAllAsync(PullAllDocumentInput input);
Task PullAsync(PullDocumentInput input); Task PullAsync(PullDocumentInput input);

35
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs

@ -7,8 +7,10 @@ using Newtonsoft.Json;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Docs.Caching;
using Volo.Docs.Documents; using Volo.Docs.Documents;
using Volo.Docs.Documents.FullSearch.Elastic; using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Localization;
using Volo.Docs.Projects; using Volo.Docs.Projects;
using Volo.Extensions; using Volo.Extensions;
@ -21,19 +23,52 @@ namespace Volo.Docs.Admin.Documents
private readonly IDocumentRepository _documentRepository; private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory; private readonly IDocumentSourceFactory _documentStoreFactory;
private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache; private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache;
private readonly IDistributedCache<List<VersionInfo>> _versionCache;
private readonly IDistributedCache<LanguageConfig> _languageCache;
private readonly IDistributedCache<DocumentResource> _resourceCache;
private readonly IDocumentFullSearch _documentFullSearch; private readonly IDocumentFullSearch _documentFullSearch;
public DocumentAdminAppService(IProjectRepository projectRepository, public DocumentAdminAppService(IProjectRepository projectRepository,
IDocumentRepository documentRepository, IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory, IDocumentSourceFactory documentStoreFactory,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache, IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IDistributedCache<List<VersionInfo>> versionCache,
IDistributedCache<LanguageConfig> languageCache,
IDistributedCache<DocumentResource> resourceCache,
IDocumentFullSearch documentFullSearch) IDocumentFullSearch documentFullSearch)
{ {
_projectRepository = projectRepository; _projectRepository = projectRepository;
_documentRepository = documentRepository; _documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory; _documentStoreFactory = documentStoreFactory;
_documentUpdateCache = documentUpdateCache; _documentUpdateCache = documentUpdateCache;
_versionCache = versionCache;
_languageCache = languageCache;
_resourceCache = resourceCache;
_documentFullSearch = documentFullSearch; _documentFullSearch = documentFullSearch;
LocalizationResource = typeof(DocsResource);
}
public async Task ClearCacheAsync(ClearCacheInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
var languageCacheKey = CacheKeyGenerator.GenerateProjectLanguageCacheKey(project);
await _languageCache.RemoveAsync(languageCacheKey, true);
var versionCacheKey = CacheKeyGenerator.GenerateProjectVersionsCacheKey(project);
await _versionCache.RemoveAsync(versionCacheKey, true);
var documents = await _documentRepository.GetListByProjectId(project.Id);
foreach (var document in documents)
{
var documentUpdateInfoCacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, document.Name, document.LanguageCode, document.LanguageCode);
await _documentUpdateCache.RemoveAsync(documentUpdateInfoCacheKey);
document.LastCachedTime = DateTime.MinValue;
await _documentRepository.UpdateAsync(document);
}
} }
public async Task PullAllAsync(PullAllDocumentInput input) public async Task PullAllAsync(PullAllDocumentInput input)

7
modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs

@ -19,6 +19,13 @@ namespace Volo.Docs.Admin
_documentAdminAppService = documentAdminAppService; _documentAdminAppService = documentAdminAppService;
} }
[HttpPost]
[Route("ClearCache")]
public Task ClearCacheAsync(ClearCacheInput input)
{
return _documentAdminAppService.ClearCacheAsync(input);
}
[HttpPost] [HttpPost]
[Route("PullAll")] [Route("PullAll")]
public Task PullAllAsync(PullAllDocumentInput input) public Task PullAllAsync(PullAllDocumentInput input)

12
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/index.js

@ -62,6 +62,18 @@
Id: data.record.id Id: data.record.id
}); });
} }
},
{
text: l('ClearCache'),
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('ClearCacheConfirmationMessage', data.record.name); },
action: function (data) {
volo.docs.admin.documentsAdmin
.clearCache({ projectId: data.record.id})
.then(function () {
_dataTable.ajax.reload();
});
}
} }
] ]
} }

46
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs

@ -11,6 +11,7 @@ using Nest;
using Newtonsoft.Json; using Newtonsoft.Json;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Docs.Caching;
using Volo.Docs.Documents.FullSearch.Elastic; using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Projects; using Volo.Docs.Projects;
using Volo.Extensions; using Volo.Extensions;
@ -22,8 +23,7 @@ namespace Volo.Docs.Documents
private readonly IProjectRepository _projectRepository; private readonly IProjectRepository _projectRepository;
private readonly IDocumentRepository _documentRepository; private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory; private readonly IDocumentSourceFactory _documentStoreFactory;
protected IDistributedCache<LanguageConfig> LanguageCache { get; } protected IDistributedCache<DocumentResource> ResourceCache { get; }
protected IDistributedCache<DocumentResourceDto> ResourceCache { get; }
protected IDistributedCache<DocumentUpdateInfo> DocumentUpdateCache { get; } protected IDistributedCache<DocumentUpdateInfo> DocumentUpdateCache { get; }
protected IHostEnvironment HostEnvironment { get; } protected IHostEnvironment HostEnvironment { get; }
private readonly IDocumentFullSearch _documentFullSearch; private readonly IDocumentFullSearch _documentFullSearch;
@ -37,8 +37,7 @@ namespace Volo.Docs.Documents
IProjectRepository projectRepository, IProjectRepository projectRepository,
IDocumentRepository documentRepository, IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory, IDocumentSourceFactory documentStoreFactory,
IDistributedCache<LanguageConfig> languageCache, IDistributedCache<DocumentResource> resourceCache,
IDistributedCache<DocumentResourceDto> resourceCache,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache, IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IHostEnvironment hostEnvironment, IHostEnvironment hostEnvironment,
IDocumentFullSearch documentFullSearch, IDocumentFullSearch documentFullSearch,
@ -48,7 +47,6 @@ namespace Volo.Docs.Documents
_projectRepository = projectRepository; _projectRepository = projectRepository;
_documentRepository = documentRepository; _documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory; _documentStoreFactory = documentStoreFactory;
LanguageCache = languageCache;
ResourceCache = resourceCache; ResourceCache = resourceCache;
DocumentUpdateCache = documentUpdateCache; DocumentUpdateCache = documentUpdateCache;
HostEnvironment = hostEnvironment; HostEnvironment = hostEnvironment;
@ -70,7 +68,7 @@ namespace Volo.Docs.Documents
input.LanguageCode, input.LanguageCode,
input.Version input.Version
); );
} }
public virtual async Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input) public virtual async Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input)
{ {
@ -106,7 +104,7 @@ namespace Volo.Docs.Documents
foreach (var leaf in leafs) foreach (var leaf in leafs)
{ {
var cacheKey = $"DocumentUpdateInfo{project.Id}#{leaf.Path}#{input.LanguageCode}#{input.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, leaf.Path, input.LanguageCode, input.Version);
var documentUpdateInfo = await DocumentUpdateCache.GetAsync(cacheKey); var documentUpdateInfo = await DocumentUpdateCache.GetAsync(cacheKey);
if (documentUpdateInfo != null) if (documentUpdateInfo != null)
{ {
@ -122,31 +120,31 @@ namespace Volo.Docs.Documents
public async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input) public async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input)
{ {
var project = await _projectRepository.GetAsync(input.ProjectId); var project = await _projectRepository.GetAsync(input.ProjectId);
var cacheKey = $"Resource@{project.ShortName}#{input.LanguageCode}#{input.Name}#{input.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentResourceCacheKey(project, input.Name, input.LanguageCode, input.Version);
input.Version = string.IsNullOrWhiteSpace(input.Version) ? project.LatestVersionBranchName : input.Version; input.Version = string.IsNullOrWhiteSpace(input.Version) ? project.LatestVersionBranchName : input.Version;
async Task<DocumentResourceDto> GetResourceAsync() async Task<DocumentResource> GetResourceAsync()
{ {
var source = _documentStoreFactory.Create(project.DocumentStoreType); var source = _documentStoreFactory.Create(project.DocumentStoreType);
var documentResource = await source.GetResource(project, input.Name, input.LanguageCode, input.Version); return await source.GetResource(project, input.Name, input.LanguageCode, input.Version);
return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(documentResource);
} }
if (HostEnvironment.IsDevelopment()) if (HostEnvironment.IsDevelopment())
{ {
return await GetResourceAsync(); return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(await GetResourceAsync());
} }
return await ResourceCache.GetOrAddAsync( return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(
cacheKey, await ResourceCache.GetOrAddAsync(
GetResourceAsync, cacheKey,
() => new DistributedCacheEntryOptions GetResourceAsync,
{ () => new DistributedCacheEntryOptions
AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration, {
SlidingExpiration = _documentResourceSlidingExpiration AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration,
} SlidingExpiration = _documentResourceSlidingExpiration
); }
)
);
} }
public async Task<List<DocumentSearchOutput>> SearchAsync(DocumentSearchInput input) public async Task<List<DocumentSearchOutput>> SearchAsync(DocumentSearchInput input)
@ -229,7 +227,7 @@ namespace Volo.Docs.Documents
return await GetDocumentAsync(documentName, project, languageCode, version, document); return await GetDocumentAsync(documentName, project, languageCode, version, document);
} }
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, document.Name, document.LanguageCode, document.Version);
await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{ {
Name = document.Name, Name = document.Name,
@ -261,7 +259,7 @@ namespace Volo.Docs.Documents
Logger.LogInformation($"Document retrieved: {documentName}"); Logger.LogInformation($"Document retrieved: {documentName}");
var cacheKey = $"DocumentUpdateInfo{sourceDocument.ProjectId}#{sourceDocument.Name}#{sourceDocument.LanguageCode}#{sourceDocument.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, sourceDocument.Name, sourceDocument.LanguageCode, sourceDocument.Version);
await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{ {
Name = sourceDocument.Name, Name = sourceDocument.Name,

5
modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs

@ -7,6 +7,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Docs.Caching;
using Volo.Docs.Documents; using Volo.Docs.Documents;
namespace Volo.Docs.Projects namespace Volo.Docs.Projects
@ -51,7 +52,7 @@ namespace Volo.Docs.Projects
var project = await _projectRepository.GetByShortNameAsync(shortName); var project = await _projectRepository.GetByShortNameAsync(shortName);
var versions = await _versionCache.GetOrAddAsync( var versions = await _versionCache.GetOrAddAsync(
project.ShortName, CacheKeyGenerator.GenerateProjectVersionsCacheKey(project),
() => GetVersionsAsync(project), () => GetVersionsAsync(project),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
@ -116,7 +117,7 @@ namespace Volo.Docs.Projects
} }
return await LanguageCache.GetOrAddAsync( return await LanguageCache.GetOrAddAsync(
project.ShortName, CacheKeyGenerator.GenerateProjectLanguageCacheKey(project),
GetLanguagesAsync, GetLanguagesAsync,
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {

27
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Caching/CacheKeyGenerator.cs

@ -0,0 +1,27 @@
using Volo.Docs.Projects;
namespace Volo.Docs.Caching
{
public static class CacheKeyGenerator
{
public static string GenerateProjectLanguageCacheKey(Project project)
{
return project.ShortName;
}
public static string GenerateProjectVersionsCacheKey(Project project)
{
return project.ShortName;
}
public static string GenerateDocumentResourceCacheKey(Project project, string resourceName, string languageCode, string version)
{
return $"Resource@{project.ShortName}#{languageCode}#{resourceName}#{version}";
}
public static string GenerateDocumentUpdateInfoCacheKey(Project project, string documentName, string languageCode, string version)
{
return $"DocumentUpdateInfo{project.Id}#{documentName}#{languageCode}#{version}";
}
}
}

4
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
@ -7,6 +8,9 @@ namespace Volo.Docs.Documents
{ {
public interface IDocumentRepository : IBasicRepository<Document> public interface IDocumentRepository : IBasicRepository<Document>
{ {
Task<List<Document>> GetListByProjectId(Guid projectId,
CancellationToken cancellationToken = default);
Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version, Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true, bool includeDetails = true,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);

4
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json

@ -9,6 +9,8 @@
"Edit": "Edit", "Edit": "Edit",
"LastEditTime": "Last edit", "LastEditTime": "Last edit",
"Delete": "Delete", "Delete": "Delete",
"ClearCache": "Clear cache",
"ClearCacheConfirmationMessage": "Are you sure to clear all caches for project \"{0}\"",
"InThisDocument": "In this document", "InThisDocument": "In this document",
"GoToTop": "Go to top", "GoToTop": "Go to top",
"Projects": "Project(s)", "Projects": "Project(s)",
@ -26,4 +28,4 @@
"UpdatedExplanation": "Updated in the last two weeks.", "UpdatedExplanation": "Updated in the last two weeks.",
"Volo.Docs.Domain:010002": "ShortName {ShortName} already exists." "Volo.Docs.Domain:010002": "ShortName {ShortName} already exists."
} }
} }

8
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -15,6 +17,12 @@ namespace Volo.Docs.Documents
{ {
} }
public async Task<List<Document>> GetListByProjectId(Guid projectId,
CancellationToken cancellationToken = default)
{
return await DbSet.Where(d => d.ProjectId == projectId).ToListAsync(cancellationToken: cancellationToken);
}
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version, public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true, bool includeDetails = true,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)

7
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq; using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
@ -15,6 +17,11 @@ namespace Volo.Docs.Documents
{ {
} }
public async Task<List<Document>> GetListByProjectId(Guid projectId, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().Where(d => d.ProjectId == projectId).ToListAsync(cancellationToken);
}
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version, public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true, bool includeDetails = true,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)

4
modules/docs/test/Volo.Docs.Application.Tests/Volo/Docs/ApplicationService_Tests.cs

@ -28,9 +28,9 @@ namespace Volo.Docs
[Fact] [Fact]
public async Task GetAsync() public async Task GetAsync()
{ {
var project = await _projectAppService.GetAsync("ABP"); var project = await _projectAppService.GetAsync("abp");
project.ShouldNotBeNull(); project.ShouldNotBeNull();
project.ShortName.ShouldBe("ABP"); project.ShortName.ShouldBe("abp");
} }
[Fact] [Fact]

2
modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/Document/DocumentRepository_Tests.cs

@ -1,7 +1,9 @@
using Volo.Docs.MongoDB; using Volo.Docs.MongoDB;
using Xunit;
namespace Volo.Docs.Document namespace Volo.Docs.Document
{ {
[Collection(MongoTestCollection.Name)]
public class DocumentRepository_Tests : DocumentRepository_Tests<DocsMongoDBTestModule> public class DocumentRepository_Tests : DocumentRepository_Tests<DocsMongoDBTestModule>
{ {

4
modules/docs/test/Volo.Docs.TestBase/Volo/Docs/ProjectRepository_Tests.cs

@ -27,10 +27,10 @@ namespace Volo.Docs
[Fact] [Fact]
public async Task GetByShortNameAsync() public async Task GetByShortNameAsync()
{ {
var project = await ProjectRepository.GetByShortNameAsync("ABP"); var project = await ProjectRepository.GetByShortNameAsync("abp");
project.ShouldNotBeNull(); project.ShouldNotBeNull();
project.ShortName.ShouldBe("ABP"); project.ShortName.ShouldBe("abp");
} }
} }
} }

2
npm/lerna.json

@ -1,5 +1,5 @@
{ {
"version": "2.5.0", "version": "2.6.0",
"packages": [ "packages": [
"packs/*" "packs/*"
], ],

2
npm/ng-packs/lerna.version.json

@ -1,5 +1,5 @@
{ {
"version": "2.5.0", "version": "2.6.0",
"packages": [ "packages": [
"packages/*" "packages/*"
], ],

6
npm/ng-packs/package.json

@ -24,11 +24,11 @@
"devDependencies": { "devDependencies": {
"@abp/ng.account": "^2.5.0", "@abp/ng.account": "^2.5.0",
"@abp/ng.account.config": "^2.5.0", "@abp/ng.account.config": "^2.5.0",
"@abp/ng.core": "^2.5.0", "@abp/ng.core": "~2.5.0",
"@abp/ng.feature-management": "^2.5.0", "@abp/ng.feature-management": "~2.5.0",
"@abp/ng.identity": "^2.5.0", "@abp/ng.identity": "^2.5.0",
"@abp/ng.identity.config": "^2.5.0", "@abp/ng.identity.config": "^2.5.0",
"@abp/ng.permission-management": "^2.5.0", "@abp/ng.permission-management": "~2.5.0",
"@abp/ng.setting-management": "^2.5.0", "@abp/ng.setting-management": "^2.5.0",
"@abp/ng.setting-management.config": "^2.5.0", "@abp/ng.setting-management.config": "^2.5.0",
"@abp/ng.tenant-management": "^2.5.0", "@abp/ng.tenant-management": "^2.5.0",

2
npm/ng-packs/packages/account-config/package.json

@ -1,6 +1,6 @@
{ {
"name": "@abp/ng.account.config", "name": "@abp/ng.account.config",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",

6
npm/ng-packs/packages/account/package.json

@ -1,14 +1,14 @@
{ {
"name": "@abp/ng.account", "name": "@abp/ng.account",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/abpframework/abp.git" "url": "https://github.com/abpframework/abp.git"
}, },
"dependencies": { "dependencies": {
"@abp/ng.account.config": "~2.5.0", "@abp/ng.account.config": "^2.6.0",
"@abp/ng.theme.shared": "~2.5.0" "@abp/ng.theme.shared": "^2.6.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

2
npm/ng-packs/packages/core/package.json

@ -1,6 +1,6 @@
{ {
"name": "@abp/ng.core", "name": "@abp/ng.core",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",

4
npm/ng-packs/packages/feature-management/package.json

@ -1,13 +1,13 @@
{ {
"name": "@abp/ng.feature-management", "name": "@abp/ng.feature-management",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/abpframework/abp.git" "url": "https://github.com/abpframework/abp.git"
}, },
"dependencies": { "dependencies": {
"@abp/ng.theme.shared": "~2.5.0" "@abp/ng.theme.shared": "^2.6.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

2
npm/ng-packs/packages/identity-config/package.json

@ -1,6 +1,6 @@
{ {
"name": "@abp/ng.identity.config", "name": "@abp/ng.identity.config",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",

8
npm/ng-packs/packages/identity/package.json

@ -1,15 +1,15 @@
{ {
"name": "@abp/ng.identity", "name": "@abp/ng.identity",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/abpframework/abp.git" "url": "https://github.com/abpframework/abp.git"
}, },
"dependencies": { "dependencies": {
"@abp/ng.identity.config": "~2.5.0", "@abp/ng.identity.config": "^2.6.0",
"@abp/ng.permission-management": "~2.5.0", "@abp/ng.permission-management": "^2.6.0",
"@abp/ng.theme.shared": "~2.5.0" "@abp/ng.theme.shared": "^2.6.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

4
npm/ng-packs/packages/permission-management/package.json

@ -1,13 +1,13 @@
{ {
"name": "@abp/ng.permission-management", "name": "@abp/ng.permission-management",
"version": "2.5.0", "version": "2.6.0",
"homepage": "https://abp.io", "homepage": "https://abp.io",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/abpframework/abp.git" "url": "https://github.com/abpframework/abp.git"
}, },
"dependencies": { "dependencies": {
"@abp/ng.theme.shared": "~2.5.0" "@abp/ng.theme.shared": "^2.6.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save