From abf75f88953e6ac006a3a6fbff28bbedd1d23e5c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 8 Mar 2022 13:55:05 +0300 Subject: [PATCH 01/54] Blogging: Convert tags to lowercase resolves https://github.com/abpframework/abp/issues/11699 --- .../Volo/Blogging/Posts/PostAppService.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs b/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs index 457656291f..15506ecf70 100644 --- a/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs +++ b/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs @@ -231,11 +231,16 @@ namespace Volo.Blogging.Posts return url; } - private async Task SaveTags(ICollection newTags, Post post) + private async Task SaveTags(ICollection tags, Post post) { - await RemoveOldTags(newTags, post); - - await AddNewTags(newTags, post); + tags = tags + .Select(t => t.ToLowerInvariant()) + .Distinct() + .ToList(); + + await RemoveOldTags(tags, post); + + await AddNewTags(tags, post); } private async Task RemoveOldTags(ICollection newTags, Post post) From 6bd0c4bc0cd61e97f2dcdccb836067532a354efc Mon Sep 17 00:00:00 2001 From: malik masis Date: Wed, 9 Mar 2022 13:30:16 +0300 Subject: [PATCH 02/54] Documented the distributed lock for the Redis Provider --- docs/en/Distributed-Lock.md | 72 +++++++++++++++++++++++++++++++++++++ docs/en/docs-nav.json | 4 +++ 2 files changed, 76 insertions(+) create mode 100644 docs/en/Distributed-Lock.md diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Lock.md new file mode 100644 index 0000000000..ff337b75eb --- /dev/null +++ b/docs/en/Distributed-Lock.md @@ -0,0 +1,72 @@ +# Distributed Lock +Distributed locks are very useful to manage many processes that request the same object. +They are used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. + +# Providers +`MedallionAbpDistributedLock` +Distributed locks system provides an abstraction that can be implemented by any vendor/provider. +ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. + +This provider contains a method named TryAcquireAsync and this method returns null if the lock could not be handled. +> Name is a mandatory field. It keeps the locked provider name. +> Timeout is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. +>CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects + + +Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. + +````csharp +using Medallion.Threading; +using Medallion.Threading.Redis; +namespace AbpDemo +{ + public class MyModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + //the other configurations + var configuration = context.Services.GetConfiguration(); + + context.Services.AddSingleton(sp => + { + var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); + }); + } + } +} +```` + +Also, you should add your Redis configuration in appsetting.json +````json +"Redis": { + "Configuration": "127.0.0.1" +} +```` + +> To use in APB, you should download the below NuGet package. +It already contains DistributedLocking.Abstractions and no need to download as well. +````powershell +Install-Package Volo.Abp.DistributedLocking -Version 5.1.4 +```` + +````csharp +using Volo.Abp.DistributedLocking; +namespace AbpDemo +{ + public class MyService : ITransientDependency + { + private readonly IAbpDistributedLock _distributedLock; + public MyService(IAbpDistributedLock distributedLock) + { + _distributedLock = distributedLock; + } + + await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) + { + if (handle != null) + { + //your code + } + } +```` \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 6df98cb05a..f039d02f1b 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -300,6 +300,10 @@ "text": "Data Seeding", "path": "Data-Seeding.md" }, + { + "text": "Distributed Lock", + "path": "Distributed-Lock.md" + }, { "text": "Email Sending", "items": [ From ac01c5b3a181eda19dd029215e4dca42ba6e7c6a Mon Sep 17 00:00:00 2001 From: malik masis Date: Wed, 9 Mar 2022 16:36:51 +0300 Subject: [PATCH 03/54] Applied the advice of the reviewer More summarize NuGet package definiation type Forgotten method --- docs/en/Distributed-Lock.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Lock.md index ff337b75eb..8593560b3d 100644 --- a/docs/en/Distributed-Lock.md +++ b/docs/en/Distributed-Lock.md @@ -1,16 +1,20 @@ # Distributed Lock Distributed locks are very useful to manage many processes that request the same object. -They are used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. +In a normal case, accessing the same object from different threads or services can corrupt the value of objects. +In terms of accuracy, we may need to protect the value that's why a lock will be necessary. +On another hand, it will protect from more times triggered hence you will provide more efficiency. +To summarize, It's used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. # Providers -`MedallionAbpDistributedLock` Distributed locks system provides an abstraction that can be implemented by any vendor/provider. + + * `MedallionAbpDistributedLock` ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. This provider contains a method named TryAcquireAsync and this method returns null if the lock could not be handled. > Name is a mandatory field. It keeps the locked provider name. > Timeout is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. ->CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +> CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. @@ -44,10 +48,10 @@ Also, you should add your Redis configuration in appsetting.json } ```` -> To use in APB, you should download the below NuGet package. +> To use in ABP, you should download the below NuGet package. It already contains DistributedLocking.Abstractions and no need to download as well. ````powershell -Install-Package Volo.Abp.DistributedLocking -Version 5.1.4 +abp add-package Volo.Abp.DistributedLocking ```` ````csharp @@ -61,12 +65,17 @@ namespace AbpDemo { _distributedLock = distributedLock; } - - await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) + + public async Task MyMethodAsync() { - if (handle != null) + await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) { - //your code - } + if (handle != null) + { + //your code + } + } } + } +} ```` \ No newline at end of file From db7daeda5ba410837c7545a34955ade6250e66b1 Mon Sep 17 00:00:00 2001 From: rqx110 Date: Thu, 10 Mar 2022 13:55:07 +0800 Subject: [PATCH 04/54] feat(cms-kit): using codemirror as global resources editor --- .../Pages/CmsKit/GlobalResources/Index.cshtml | 8 ++++++++ .../Pages/CmsKit/GlobalResources/index.js | 19 +++++++++++++++++-- npm/packs/cms-kit.admin/package.json | 3 ++- npm/packs/codemirror/abp.resourcemapping.js | 5 ++++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/Index.cshtml index b67a147baa..615ef31477 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/Index.cshtml @@ -2,6 +2,7 @@ @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror @using Volo.CmsKit.Admin.Web.Pages.CmsKit.GlobalResources @using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Localization @@ -17,8 +18,15 @@ PageLayout.Content.MenuItemName = CmsKitAdminMenus.GlobalResources.GlobalResourcesMenu; } +@section styles{ + +} + @section scripts { + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/index.js index 72fb11e8dc..c58447b22d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/index.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/index.js @@ -3,11 +3,26 @@ $(function (){ var service = volo.cmsKit.admin.globalResources.globalResourceAdmin; + var scriptEditor = CodeMirror.fromTextArea(document.getElementById("ScriptContent"),{ + mode:"javascript", + lineNumbers:true + }); + + var styleEditor = CodeMirror.fromTextArea(document.getElementById("StyleContent"),{ + mode:"css", + lineNumbers:true + }); + + $('.nav-tabs a').on('shown.bs.tab', function() { + scriptEditor.refresh(); + styleEditor.refresh(); + }); + $('#SaveResourcesButton').on('click','',function(){ service.setGlobalResources( { - style: $('#StyleContent').val(), - script: $('#ScriptContent').val() + style: styleEditor.getValue(), + script: scriptEditor.getValue() } ).then(function () { abp.message.success(l("SavedSuccessfully")); diff --git a/npm/packs/cms-kit.admin/package.json b/npm/packs/cms-kit.admin/package.json index 528bdb3ac0..524583a187 100644 --- a/npm/packs/cms-kit.admin/package.json +++ b/npm/packs/cms-kit.admin/package.json @@ -8,7 +8,8 @@ "@abp/jstree": "~5.2.0-rc.1", "@abp/slugify": "~5.2.0-rc.1", "@abp/tui-editor": "~5.2.0-rc.1", - "@abp/uppy": "~5.2.0-rc.1" + "@abp/uppy": "~5.2.0-rc.1", + "@abp/codemirror": "~5.2.0-rc.1" }, "gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431" } diff --git a/npm/packs/codemirror/abp.resourcemapping.js b/npm/packs/codemirror/abp.resourcemapping.js index 71731c389b..d7f349b54a 100644 --- a/npm/packs/codemirror/abp.resourcemapping.js +++ b/npm/packs/codemirror/abp.resourcemapping.js @@ -1,5 +1,8 @@ module.exports = { mappings: { - "@node_modules/codemirror/lib/*.*": "@libs/codemirror/" + "@node_modules/codemirror/lib/*.*": "@libs/codemirror/", + "@node_modules/codemirror/mode/**/*.*": "@libs/codemirror/mode/", + "@node_modules/codemirror/theme/**/*.*": "@libs/codemirror/theme/", + "@node_modules/codemirror/addon/**/*.*": "@libs/codemirror/addon/" } } \ No newline at end of file From 50b66102c8ac0f4b03bec4e52b60d0f17f089e92 Mon Sep 17 00:00:00 2001 From: malik masis Date: Thu, 10 Mar 2022 09:12:42 +0300 Subject: [PATCH 05/54] Added quotes According to the reviewer, added quotes for method and parameters name --- docs/en/Distributed-Lock.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Lock.md index 8593560b3d..ae1d5b9232 100644 --- a/docs/en/Distributed-Lock.md +++ b/docs/en/Distributed-Lock.md @@ -11,10 +11,10 @@ Distributed locks system provides an abstraction that can be implemented by any * `MedallionAbpDistributedLock` ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. -This provider contains a method named TryAcquireAsync and this method returns null if the lock could not be handled. -> Name is a mandatory field. It keeps the locked provider name. -> Timeout is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. -> CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. +> `Name` is a mandatory field. It keeps the locked provider name. +> `Timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. +> `CancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. From f986f14aeb98ef064cdfd23061a7b0f6aa55c085 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 10 Mar 2022 11:18:00 +0300 Subject: [PATCH 06/54] Add 5.2 Migration Guide --- docs/en/Migration-Guides/Abp-5_2.md | 45 ++++++++++++++++++++++++++++- docs/en/Migration-Guides/Index.md | 1 + 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/en/Migration-Guides/Abp-5_2.md b/docs/en/Migration-Guides/Abp-5_2.md index 3a98e948ae..f0c7a4eaac 100644 --- a/docs/en/Migration-Guides/Abp-5_2.md +++ b/docs/en/Migration-Guides/Abp-5_2.md @@ -1,3 +1,46 @@ # ABP Version 5.2 Migration Guide -TODO \ No newline at end of file +This document is a guide for upgrading ABP 5.1 solutions to ABP 5.2. Please read them all since 5.2 has some important breaking changes. + + +## Blazor UI +If you use Blazor WASM or Blazor Server UI, you should follow this section. + +### Blazorise 1.0 +We've upgraded to Blazorise 1.0 stable version. So there is some breaking changes that you have to apply in your project. + +Also You can review that pull request [#11649 - Blazorise 1.0 Migration](https://github.com/abpframework/abp/pull/11649) + +- `NumericEdit` is now made around the native `input type="number"` so a lot of its formating features are moved to the new `NumericPicker` component. Replace NumericEdit with NumericPicker. +- Rename `DecimalsSeparator` to `DecimalSeparator` on the `DataGridColumn` and `NumericPicker`. +- Rename `MaxMessageSize` to `MaxChunkSize`. +- Remove `Fullscreen` parameter on `` and replace it with `Size="ModalSize.Fullscreen"` parameter. +- Remove `NotificationType`, `Message`, and `Title` parameter from `` component. +- Move `RightAligned` parameter from `` to `` component. +- Rename any usage of the `ChangeTextOnKeyPress` parameter into `Immediate`. +- Rename any usage of `DelayTextOnKeyPress` parameter into `Debounce` and `DelayTextOnKeyPressInterval` into DebounceInterval. +- Replace all `Left` and `Right` enums with `Start` and `End` for the following enum types: `Direction`, `Float`, `Placement`, `NotificationLocation`, `Side`, `SnackbarLocation`, `SnackbarStackLocation`, `TabPosition`, and `TextAlignment`. +- Replace all `FromLeft`, `FromRight`, `RoundedLeft`, and `RoundedRight` enums with `FromStart`, `FromEnd`, `RoundedStart`, and `RoundedEnd` for the `Border` utilities. +- Replace all `FromLeft` and `FromRight` with `FromStart`, `FromEnd` for the Margin and `Padding` utilities. +- Replace all `AddLabel` with `AddLabels` method on chart instance. +- Change enum value from `None` to `Default` for the following enum types: `Color`, `Background`, `TextColor`, `Alignment`, `BorderRadius`, `BorderSize`, `Direction`, `DisplayDirection`, `FigureSize`, `IconSize`, `JustifyContent`, `OverflowType`, `SnackbarColor`, `Target`, `TextAlignment`, `TextOverflow`, `TextTransform`, `TextWeight`, `VerticalAlignment`, `Visibility`, `Size`, and `SnackbarLocation`. +- Obsolete typography parameters `Alignment`, `Color`, `Transform`, and `Weight` are removed in favor of `TextAlignment`, `TextColor`, `TextTransform`, and `TextWeight`. +- Remove any use of an obsolete component ``. +- The Datagrid's obsolete `Direction` parameter has now been removed. Instead, please use the `SortDirection` parameter if you weren't already.. +- Rename `` `Mode` parameter into `RenderMode`. + +> _Check out [Blazorise Release Notes](https://preview.blazorise.com/news/release-notes/100) for more information._ + +--- + +## MVC - Razor Pages UI + +If you use MVC Razor Pages UI, you should follow this section. + +### Client libraries +The `libs` folder no longer exists in templates after v5.2. That change greatly reduced the size of templates and brought some other advantages. + +You can use `abp install-libs` command for installing or updating client libraries. You should run this command after updating v5.2. + +> If you're creating a new project, you don't have to be concerned about it, ABP CLI installs client libraries after automatically. + diff --git a/docs/en/Migration-Guides/Index.md b/docs/en/Migration-Guides/Index.md index 909f6c0998..e2647d8b0e 100644 --- a/docs/en/Migration-Guides/Index.md +++ b/docs/en/Migration-Guides/Index.md @@ -1,5 +1,6 @@ # ABP Framework Migration Guides +- [5.1 to 5.2](Abp-5_2.md) - [4.x to 5.0](Abp-5_0.md) - [4.2 to 4.3](Abp-4_3.md) - [4.x to 4.2](Abp-4_2.md) From dd49ea69917d5f18a3a21d3752ef94cc5d546953 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 10 Mar 2022 11:31:52 +0300 Subject: [PATCH 07/54] Add IMongoDbRepositoryFilterer breaking-change --- docs/en/Migration-Guides/Abp-5_2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/Migration-Guides/Abp-5_2.md b/docs/en/Migration-Guides/Abp-5_2.md index f0c7a4eaac..fbd49df21f 100644 --- a/docs/en/Migration-Guides/Abp-5_2.md +++ b/docs/en/Migration-Guides/Abp-5_2.md @@ -3,6 +3,10 @@ This document is a guide for upgrading ABP 5.1 solutions to ABP 5.2. Please read them all since 5.2 has some important breaking changes. +## MongoDB + +- `IMongoDbRepositoryFilterer.AddGlobalFilters()` method is replaced with async one `IMongoDbRepositoryFilterer.AddGlobalFiltersAsync()` + ## Blazor UI If you use Blazor WASM or Blazor Server UI, you should follow this section. From bbe899ac66a2f2930566925a7421c1afa7420e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 10 Mar 2022 12:18:29 +0300 Subject: [PATCH 08/54] Update Abp-5_2.md --- docs/en/Migration-Guides/Abp-5_2.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/en/Migration-Guides/Abp-5_2.md b/docs/en/Migration-Guides/Abp-5_2.md index fbd49df21f..d0cbf80aad 100644 --- a/docs/en/Migration-Guides/Abp-5_2.md +++ b/docs/en/Migration-Guides/Abp-5_2.md @@ -1,6 +1,6 @@ # ABP Version 5.2 Migration Guide -This document is a guide for upgrading ABP 5.1 solutions to ABP 5.2. Please read them all since 5.2 has some important breaking changes. +This document is a guide for upgrading ABP v5.x solutions to ABP v5.2. Please read them all since v5.2 has some changes you should take care. ## MongoDB @@ -35,8 +35,6 @@ Also You can review that pull request [#11649 - Blazorise 1.0 Migration](https:/ > _Check out [Blazorise Release Notes](https://preview.blazorise.com/news/release-notes/100) for more information._ ---- - ## MVC - Razor Pages UI If you use MVC Razor Pages UI, you should follow this section. @@ -48,3 +46,7 @@ You can use `abp install-libs` command for installing or updating client librari > If you're creating a new project, you don't have to be concerned about it, ABP CLI installs client libraries after automatically. +## See Also + +* [Official blog post for the 5.2 release](https://blog.abp.io/abp/ABP.IO-Platform-5-2-RC-Has-Been-Published) + From f3aa932b3e00ad73804453b30d88b22f3a993116 Mon Sep 17 00:00:00 2001 From: malik masis Date: Thu, 10 Mar 2022 14:17:12 +0300 Subject: [PATCH 09/54] Made changes on the document It will be continued enhancement --- ...ributed-Lock.md => Distributed-Locking.md} | 85 +++++++++---------- docs/en/docs-nav.json | 2 +- 2 files changed, 41 insertions(+), 46 deletions(-) rename docs/en/{Distributed-Lock.md => Distributed-Locking.md} (58%) diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Locking.md similarity index 58% rename from docs/en/Distributed-Lock.md rename to docs/en/Distributed-Locking.md index ae1d5b9232..d79dff8674 100644 --- a/docs/en/Distributed-Lock.md +++ b/docs/en/Distributed-Locking.md @@ -1,23 +1,47 @@ -# Distributed Lock -Distributed locks are very useful to manage many processes that request the same object. -In a normal case, accessing the same object from different threads or services can corrupt the value of objects. +# Distributed Locking +Distributed locking is very useful to manage many processes that request the same object. +In a normal case, accessing the same object from different applications can corrupt the value of resources. In terms of accuracy, we may need to protect the value that's why a lock will be necessary. -On another hand, it will protect from more times triggered hence you will provide more efficiency. -To summarize, It's used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. -# Providers -Distributed locks system provides an abstraction that can be implemented by any vendor/provider. +> To use in ABP, you should download the below NuGet package or can open any command apps and run the below command. +````powershell +abp add-package Volo.Abp.DistributedLocking +```` - * `MedallionAbpDistributedLock` -ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. +````csharp +using Volo.Abp.DistributedLocking; +namespace AbpDemo +{ + public class MyService : ITransientDependency + { + private readonly IAbpDistributedLock _distributedLock; + public MyService(IAbpDistributedLock distributedLock) + { + _distributedLock = distributedLock; + } + + public async Task MyMethodAsync() + { + await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) + { + if (handle != null) + { + //your code + } + } + } + } +} +```` This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. -> `Name` is a mandatory field. It keeps the locked provider name. -> `Timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. -> `CancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise it will be seen as a different lock. +`timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. +`cancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. ABP implements the Redis provider for you and you may customize the others yourselves. -Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. +Firstly, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. ````csharp using Medallion.Threading; @@ -41,41 +65,12 @@ namespace AbpDemo } ```` -Also, you should add your Redis configuration in appsetting.json +Also, you should add your Redis configuration in appsetting.json. +You may change the structure of the JSON file but it must match with the above configuration code. ````json "Redis": { "Configuration": "127.0.0.1" } ```` -> To use in ABP, you should download the below NuGet package. -It already contains DistributedLocking.Abstractions and no need to download as well. -````powershell -abp add-package Volo.Abp.DistributedLocking -```` - -````csharp -using Volo.Abp.DistributedLocking; -namespace AbpDemo -{ - public class MyService : ITransientDependency - { - private readonly IAbpDistributedLock _distributedLock; - public MyService(IAbpDistributedLock distributedLock) - { - _distributedLock = distributedLock; - } - - public async Task MyMethodAsync() - { - await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) - { - if (handle != null) - { - //your code - } - } - } - } -} -```` \ No newline at end of file +As mentioned the above, this implemantition is for Redis and for more detail you can visit [the official site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index f039d02f1b..16edb1a7cc 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -302,7 +302,7 @@ }, { "text": "Distributed Lock", - "path": "Distributed-Lock.md" + "path": "Distributed-Locking.md" }, { "text": "Email Sending", From 2081f49dad325c9c9aa8b34f1393a2239632152f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 10 Mar 2022 18:48:44 +0300 Subject: [PATCH 10/54] Update POST.md --- docs/en/Blog-Posts/2022-03-08 v5_2_Preview/POST.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/en/Blog-Posts/2022-03-08 v5_2_Preview/POST.md b/docs/en/Blog-Posts/2022-03-08 v5_2_Preview/POST.md index 5699328d89..b78e3235a2 100644 --- a/docs/en/Blog-Posts/2022-03-08 v5_2_Preview/POST.md +++ b/docs/en/Blog-Posts/2022-03-08 v5_2_Preview/POST.md @@ -34,6 +34,13 @@ See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all t You can use any IDE that supports .NET 6.x, like **[Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)**. +## Migration Guides + +Please see the migration guides if you are upgrading from 5.x versions: + +* [ABP Framework 5.x to 5.2 migration guide](https://docs.abp.io/en/abp/5.2/Migration-Guides/Abp-5_2) +* [ABP Commercial 5.x to 5.2 migration guide](https://docs.abp.io/en/commercial/5.2/migration-guides/index) + ## What's New with ABP Framework 5.2? In this section, I will introduce some major features released with this version. Here, a brief list of titles explained in the next sections: @@ -45,7 +52,7 @@ In this section, I will introduce some major features released with this version * Custom Global CSS and JavaScript for the CMS Kit module * Other news -Let's begin with the first section: +Let's begin with the first section. ### Single-layer Solution Template @@ -171,7 +178,7 @@ With this new feature, you can automatically generate advanced user interfaces w ## Community News -We organized the 3rd live [ABP Community Talks](https://community.abp.io/talks) event on February 23rd. ABP community has a good interest in these events and we will continue to organize such a live event in every month. March's event will be announced in a few days. [Follow us on twitter](https://twitter.com/abpframework). +We organized the 3rd live [ABP Community Talks](https://community.abp.io/events) event on February 23rd. ABP community has a good interest in these events and we will continue to organize such a live event in every month. March's event will be announced in a few days. [Follow us on twitter](https://twitter.com/abpframework). [ABP Community](https://community.abp.io/) website is being a huge resource of articles and video tutorials on the ABP Framework and .NET. There have been 93 articles/tutorials submitted so far. Here's a list of a few contents posted in the last weeks: From 7317e493279e09d2f11322b04310c7442916bf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 10 Mar 2022 18:49:39 +0300 Subject: [PATCH 11/54] Increment version --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 12a177739b..facc92f0bc 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 5.2.0-rc.1 + 5.3.0 $(NoWarn);CS1591;CS0436 https://abp.io/assets/abp_nupkg.png https://abp.io/ From 76d0f618d773aacd652fc613dd5f035d2e8813f7 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 11 Mar 2022 11:28:16 +0800 Subject: [PATCH 12/54] Upgrade to Blazorise 1.0.1 --- .../src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj | 8 ++++---- ...MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj | 4 ++-- .../MyCompanyName.MyProjectName.Blazor.Server.csproj | 4 ++-- ...yCompanyName.MyProjectName.Blazor.Server.Tiered.csproj | 4 ++-- .../MyCompanyName.MyProjectName.Blazor.Server.csproj | 4 ++-- .../MyCompanyName.MyProjectName.Blazor.csproj | 4 ++-- .../MyCompanyName.MyProjectName.Blazor.Host.csproj | 4 ++-- .../MyCompanyName.MyProjectName.Blazor.Server.Host.csproj | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj index cc9a7c2e99..d3cbf11b28 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj +++ b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj @@ -14,10 +14,10 @@ - - - - + + + + diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj index bd9b9db796..2803a605a3 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj index 3b28660902..124902bb24 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj index 8e33d8e828..75c373acad 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj index dffe94ce7d..89cc860ab6 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj index 96e0925201..fe34414fa1 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/MyCompanyName.MyProjectName.Blazor.Host.csproj b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/MyCompanyName.MyProjectName.Blazor.Host.csproj index 092d9f461a..8e510431f4 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/MyCompanyName.MyProjectName.Blazor.Host.csproj +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/MyCompanyName.MyProjectName.Blazor.Host.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyCompanyName.MyProjectName.Blazor.Server.Host.csproj b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyCompanyName.MyProjectName.Blazor.Server.Host.csproj index 8c79116720..3ad973c9a7 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyCompanyName.MyProjectName.Blazor.Server.Host.csproj +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyCompanyName.MyProjectName.Blazor.Server.Host.csproj @@ -12,8 +12,8 @@ - - + + From eb7fa083356f10c5f251379093b90d3fb92bba5d Mon Sep 17 00:00:00 2001 From: William Obando Date: Thu, 10 Mar 2022 22:49:14 -0500 Subject: [PATCH 13/54] Add option to disable service bus --- .../Abp/EventBus/Azure/AbpAzureEventBusOptions.cs | 2 ++ .../Abp/EventBus/Azure/AbpEventBusAzureModule.cs | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpAzureEventBusOptions.cs b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpAzureEventBusOptions.cs index a6aa2f9857..57fa4b7f48 100644 --- a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpAzureEventBusOptions.cs +++ b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpAzureEventBusOptions.cs @@ -7,4 +7,6 @@ public class AbpAzureEventBusOptions public string SubscriberName { get; set; } public string TopicName { get; set; } + + public bool IsServiceBusDisabled { get; set; } } diff --git a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpEventBusAzureModule.cs b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpEventBusAzureModule.cs index 64c8b2fcd3..129004c871 100644 --- a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpEventBusAzureModule.cs +++ b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AbpEventBusAzureModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.AzureServiceBus; using Volo.Abp.Modularity; @@ -19,9 +20,15 @@ public class AbpEventBusAzureModule : AbpModule public override void OnApplicationInitialization(ApplicationInitializationContext context) { - context - .ServiceProvider - .GetRequiredService() - .Initialize(); + var options = context.ServiceProvider.GetRequiredService>().Value; + + if (!options.IsServiceBusDisabled) + { + context + .ServiceProvider + .GetRequiredService() + .Initialize(); + } + } } From 23ee9704bee39ef6215f944daf8643de01efbe5a Mon Sep 17 00:00:00 2001 From: braim23 <94292623+braim23@users.noreply.github.com> Date: Fri, 11 Mar 2022 16:03:54 +0300 Subject: [PATCH 14/54] Fixing broken links in Community and Blog-posts --- docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md | 2 +- .../POST.md | 2 +- .../POST.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md b/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md index 59bd172f47..a07928a116 100644 --- a/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md +++ b/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md @@ -79,7 +79,7 @@ For example, -We've covered the initial features, installation and configuration steps in this post. You can read the [open-source](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit) and [commercial](https://docs.abp.io/en/commercial/latest/modules/CMS-Kit) documentation to get further information about features and the CMS Kit module. CMS Kit's initial version contains lots of features that you can easily integrate and use in your applications. We're planning to improve the existing features, fixing bugs and adding new features in upcoming releases. If you want to give some feedback or have a feature request, please reach out to us from [GitHub](https://github.com/abpframework/abp) or [support.abp.io](https://support.abp.io). We will be happy to plan the CMS Kit module's future together. +We've covered the initial features, installation and configuration steps in this post. You can read the [open-source](https://docs.abp.io/en/abp/latest/Modules/Cms-Kit/Index) and [commercial](https://docs.abp.io/en/commercial/latest/modules/CMS-Kit) documentation to get further information about features and the CMS Kit module. CMS Kit's initial version contains lots of features that you can easily integrate and use in your applications. We're planning to improve the existing features, fixing bugs and adding new features in upcoming releases. If you want to give some feedback or have a feature request, please reach out to us from [GitHub](https://github.com/abpframework/abp) or [support.abp.io](https://support.abp.io). We will be happy to plan the CMS Kit module's future together. Thank you! diff --git a/docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/POST.md b/docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/POST.md index edaeaf46db..4095c62092 100644 --- a/docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/POST.md +++ b/docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/POST.md @@ -178,7 +178,7 @@ module.exports = { }; ``` -> ABP copies related packages from **node_modules** folder to the **libs** folder by examining this file. You can read this [document](docs.abp.io/en/abp/latest/UI/AspNetCore/Client-Side-Package-Management#mapping-the-library-resources) for more info. +> ABP copies related packages from **node_modules** folder to the **libs** folder by examining this file. You can read this [document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Client-Side-Package-Management#mapping-the-library-resources) for more info. * Then run the `abp install-libs` to install the dependencies and copy them into the libs folder by your mappings configuration. After running this command, in your **libs** folder it should be a folder named **syncfusion** folder. diff --git a/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md b/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md index 5c9c576e9c..056c14c6e7 100644 --- a/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md +++ b/docs/en/Community-Articles/2022-02-06-How-to-Hide-ABP-Related-Endpoints-on-Swagger-UI/POST.md @@ -108,7 +108,7 @@ public class SwaggerSettingConsts We've created a class with a constant variable to avoid using the magic strings. This variable will be our setting name. -ABP provides us a [Settings System](https://docs.abp.io/en/abp/latest/Setting) to easily define settings for our applications. We only need to create a class that derives from the `SettingDefinitionProvider` class, but we don't even need to do this because the ABP startup templates come with a pre-defined setting provider class. +ABP provides us a [Settings System](https://docs.abp.io/en/abp/latest/Settings) to easily define settings for our applications. We only need to create a class that derives from the `SettingDefinitionProvider` class, but we don't even need to do this because the ABP startup templates come with a pre-defined setting provider class. * So open the setting definition provider class (`SwaggerSettingsDemoSettingDefinitionProvider` in our case, it's under the /Settings folder of your domain layer) and update the class: From 41cd83240f09bda635b2a00e56945d77f735db2d Mon Sep 17 00:00:00 2001 From: hpstory <33348162+hpstory@users.noreply.github.com> Date: Fri, 11 Mar 2022 21:22:44 +0800 Subject: [PATCH 15/54] Update abp/docs/zh-Hans/Modules/Background-Jobs.md --- docs/zh-Hans/Modules/Background-Jobs.md | 56 ++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/Modules/Background-Jobs.md b/docs/zh-Hans/Modules/Background-Jobs.md index b183febd80..87c57acde7 100644 --- a/docs/zh-Hans/Modules/Background-Jobs.md +++ b/docs/zh-Hans/Modules/Background-Jobs.md @@ -1,3 +1,55 @@ -# Background Jobs Module +# 后台作业模块 -待添加 \ No newline at end of file +后台作业模块实现了 `IBackgroundJobStore` 接口,并且可以使用ABP框架的默认后台作业管理。如果你不想使用这个模块,那么你需要自己实现 `IBackgroundJobStore` 接口。 + +> 本文档仅介绍后台作业模块,该模块将后台作业持久化到数据库。有关后台作业系统的更多信息,请参阅[后台作业](../Background-Jobs.md)文档。 + +## 如何使用 + +当您使用ABP框架[创建一个新的解决方案](https://abp.io/get-started)时,这个模块是(作为NuGet/NPM包)预先安装的。您可以继续将其作为软件包使用并轻松获取更新,也可以将其源代码包含到解决方案中(请参阅 `get-source` [CLI](../CLI.md)命令)以开发自定义模块。 + +### 源代码 + +此模块的源代码可在[此处](https://github.com/abpframework/abp/tree/dev/modules/background-jobs)访问。源代码是由[麻省理工学院](https://choosealicense.com/licenses/mit/)授权的,所以你可以自由使用和定制它。 + +## 内部结构 + +### 领域层 + +#### 聚合 + +- `BackgroundJobRecord` (聚合根): 表示后台工作记录. + +#### 仓储 + +为该模块定义了以下自定义仓储: + +- `IBackgroundJobRepository` + +### 数据库提供程序 + +#### 通用 + +##### 表/集合的前缀与架构 + +默认情况下,所有表/集合都使用 `Abp` 前缀。如果需要更改表前缀或设置架构名称(如果数据库提供程序支持),请在 `BackgroundJobsDbProperties` 类上设置静态属性。 + +##### 连接字符串 + +此模块使用 `AbpBackgroundJobs` 作为连接字符串名称。如果不使用此名称定义连接字符串,它将返回 `Default` 连接字符串。有关详细信息,请参阅[连接字符串](https://docs.abp.io/en/abp/latest/Connection-Strings)文档。 + +#### Entity Framework Core + +##### 表 + +- **AbpBackgroundJobs** + +#### MongoDB + +##### 集合 + +- **AbpBackgroundJobs** + +## 另请参阅 + +* [后台作业系统](../Background-Jobs.md) From 1a4d44ce9fb3185019001f5dab70cb6b44345dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 11 Mar 2022 16:41:21 +0300 Subject: [PATCH 16/54] Added discord channel link --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dbf8bce537..1d7b7e51a7 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,10 @@ ABP is a community-driven open source project. See [the contribution guide](http Love ABP Framework? **Please give a star** to this repository :star: +## Discord Channel + +You can use this link to join the ABP Community Discord Server: https://discord.gg/uVGt6hyhcm + ## ABP Commercial See also [ABP Commercial](https://commercial.abp.io/) if you are looking for pre-built application modules, professional themes, code generation tooling and premium support for the ABP Framework. From 533a59536f74084beeb31bf88b5d9ee362836bf8 Mon Sep 17 00:00:00 2001 From: malik masis Date: Fri, 11 Mar 2022 17:06:41 +0300 Subject: [PATCH 17/54] Reworked on summarize Completed working on changes according to the feedback of the reviewer. --- docs/en/Distributed-Locking.md | 11 ++++++----- docs/en/docs-nav.json | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index d79dff8674..7a87132fa6 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -1,7 +1,8 @@ # Distributed Locking -Distributed locking is very useful to manage many processes that request the same object. -In a normal case, accessing the same object from different applications can corrupt the value of resources. -In terms of accuracy, we may need to protect the value that's why a lock will be necessary. +Distributed locking is very useful to manage many applications that trying to access the same resource. +The main purpose is to allow only one of many applications to access the same resource at the same time. +Otherwise accessing the same object from various applications may corrupt the value of resources. +On this occasion, distributed locking protects the correct value throughout the applications. > To use in ABP, you should download the below NuGet package or can open any command apps and run the below command. ````powershell @@ -35,7 +36,7 @@ namespace AbpDemo ```` This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. -`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise it will be seen as a different lock. +`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise, it will be seen as a different lock. `timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. `cancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects @@ -73,4 +74,4 @@ You may change the structure of the JSON file but it must match with the above c } ```` -As mentioned the above, this implemantition is for Redis and for more detail you can visit [the official site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file +As mentioned above, this implementation is for Redis and for more detail you can visit [the GitHub site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 16edb1a7cc..1fdc6f510a 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -301,7 +301,7 @@ "path": "Data-Seeding.md" }, { - "text": "Distributed Lock", + "text": "Distributed Locking", "path": "Distributed-Locking.md" }, { From 4c67d1a1dc8a63108d1d21d7def67effbe1f12b7 Mon Sep 17 00:00:00 2001 From: hpstory <33348162+hpstory@users.noreply.github.com> Date: Fri, 11 Mar 2022 22:45:11 +0800 Subject: [PATCH 18/54] Update Specification.md --- docs/zh-Hans/Specifications.md | 258 ++++++++++++++++++++++++++++++++- 1 file changed, 256 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/Specifications.md b/docs/zh-Hans/Specifications.md index f927c80255..bc5c67101b 100644 --- a/docs/zh-Hans/Specifications.md +++ b/docs/zh-Hans/Specifications.md @@ -1,3 +1,257 @@ -## 规约 +## 规范 -TODO.. \ No newline at end of file +规范模式用于为实体和其他业务对象定义 **命名、可复用、可组合和可测试的过滤器** 。 + +> 规范是领域层的一部分。 + +## 安装 + +> 这个包 **已经安装** 在启动模板中。所以,大多数时候你不需要手动去安装。 + +添加 [Volo.Abp.Specifications](https://abp.io/package-detail/Volo.Abp.Specifications) 包到你的项目. 如果当前文件夹是您的项目的根目录(`.csproj`)时,您可以在命令行终端中使用 [ABP CLI](CLI.md) *add package* 命令: + +````bash +abp add-package Volo.Abp.Specifications +```` + +## 定义规范 + +假设您定义了如下的顾客实体: + +````csharp +using System; +using Volo.Abp.Domain.Entities; + +namespace MyProject +{ + public class Customer : AggregateRoot + { + public string Name { get; set; } + + public byte Age { get; set; } + + public long Balance { get; set; } + + public string Location { get; set; } + } +} +```` + +您可以创建一个由 `Specification` 派生的新规范类。 + +**例如:规定选择一个18岁以上的顾客** + +````csharp +using System; +using System.Linq.Expressions; +using Volo.Abp.Specifications; + +namespace MyProject +{ + public class Age18PlusCustomerSpecification : Specification + { + public override Expression> ToExpression() + { + return c => c.Age >= 18; + } + } +} +```` + +您只需通过定义一个lambda[表达式](https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/lambda-expressions)来定义规范。 + +> 您也可以直接实现`ISpecification`接口,但是基类`Specification`做了大量简化。 + +## 使用规范 + +这里有两种常见的规范用例。 + +### IsSatisfiedBy + +`IsSatisfiedBy` 方法可以用于检查单个对象是否满足规范。 + +**例如:如果顾客不满足年龄规定,则抛出异常** + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace MyProject +{ + public class CustomerService : ITransientDependency + { + public async Task BuyAlcohol(Customer customer) + { + if (!new Age18PlusCustomerSpecification().IsSatisfiedBy(customer)) + { + throw new Exception( + "这位顾客不满足年龄规定!" + ); + } + + //TODO... + } + } +} +```` + +### ToExpression & Repositories + +`ToExpression()` 方法可用于将规范转化为表达式。通过这种方式,您可以使用规范在**数据库查询时过滤实体**。 + +````csharp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Services; + +namespace MyProject +{ + public class CustomerManager : DomainService, ITransientDependency + { + private readonly IRepository _customerRepository; + + public CustomerManager(IRepository customerRepository) + { + _customerRepository = customerRepository; + } + + public async Task> GetCustomersCanBuyAlcohol() + { + var queryable = await _customerRepository.GetQueryableAsync(); + var query = queryable.Where( + new Age18PlusCustomerSpecification().ToExpression() + ); + + return await AsyncExecuter.ToListAsync(query); + } + } +} +```` + +> 规范被正确地转换为SQL/数据库查询语句,并且在DBMS端高效执行。虽然它与规范无关,但如果您想了解有关 `AsyncExecuter` 的更多信息,请参阅[仓储](Repositories.md)文档。 + +实际上,没有必要使用 `ToExpression()` 方法,因为规范会自动转换为表达式。这也会起作用: + +````csharp +var queryable = await _customerRepository.GetQueryableAsync(); +var query = queryable.Where( + new Age18PlusCustomerSpecification() +); +```` + +## 编写规范 + +规范有一个强大的功能是,它们可以与`And`、`Or`、`Not`以及`AndNot`扩展方法组合使用。 + +假设您有另一个规范,定义如下: + +```csharp +using System; +using System.Linq.Expressions; +using Volo.Abp.Specifications; + +namespace MyProject +{ + public class PremiumCustomerSpecification : Specification + { + public override Expression> ToExpression() + { + return (customer) => (customer.Balance >= 100000); + } + } +} +``` + +您可以将 `PremiumCustomerSpecification` 和 `Age18PlusCustomerSpecification` 结合起来,查询优质成人顾客的数量,如下所示: + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Services; +using Volo.Abp.Specifications; + +namespace MyProject +{ + public class CustomerManager : DomainService, ITransientDependency + { + private readonly IRepository _customerRepository; + + public CustomerManager(IRepository customerRepository) + { + _customerRepository = customerRepository; + } + + public async Task GetAdultPremiumCustomerCountAsync() + { + return await _customerRepository.CountAsync( + new Age18PlusCustomerSpecification() + .And(new PremiumCustomerSpecification()).ToExpression() + ); + } + } +} +```` + +如果你想让这个组合成为一个可复用的规范,你可以创建这样一个组合的规范类,它派生自`AndSpecification`: + +````csharp +using Volo.Abp.Specifications; + +namespace MyProject +{ + public class AdultPremiumCustomerSpecification : AndSpecification + { + public AdultPremiumCustomerSpecification() + : base(new Age18PlusCustomerSpecification(), + new PremiumCustomerSpecification()) + { + } + } +} +```` + +现在,您就可以向下面一样重新编写 `GetAdultPremiumCustomerCountAsync` 方法: + +````csharp +public async Task GetAdultPremiumCustomerCountAsync() +{ + return await _customerRepository.CountAsync( + new AdultPremiumCustomerSpecification() + ); +} +```` + +> 你可以从这些例子中看到规范的强大之处。如果您之后想要更改 `PremiumCustomerSpecification` ,比如将余额从 `100.000` 修改为 `200.000` ,所有查询语句和合并的规范都将受到本次更改的影响。这是减少代码重复的好方法! + +## 讨论 + +虽然规范模式通常与C#的lambda表达式相比较,算是一种更老的方式。一些开发人员可能认为不再需要它,我们可以直接将表达式传入到仓储或领域服务中,如下所示: + +````csharp +var count = await _customerRepository.CountAsync(c => c.Balance > 100000 && c.Age => 18); +```` + +自从ABP的[仓储](Repositories.md)支持表达式,这是一个完全有效的用法。您不必在应用程序中定义或使用任何规范,可以直接使用表达式。 + +所以,规范的意义是什么?为什么或者应该在什么时候考虑去使用它? + +### 何时使用? + +使用规范的一些好处: + +- **可复用**:假设您在代码库的许多地方都需要用到优质顾客过滤器。如果使用表达式而不创建规范,那么如果以后更改“优质顾客”的定义会发生什么?假设您想将最低余额从100000美元更改为250000美元,并添加另一个条件,成为顾客超过3年。如果使用了规范,只需修改一个类。如果在任何其他地方重复(复制/粘贴)相同的表达式,则需要更改所有的表达式。 +- **可组合**:可以组合多个规范来创建新规范。这是另一种可复用性。 +- **命名**:`PremiumCustomerSpecification` 更好地解释了为什么使用规范,而不是复杂的表达式。因此,如果在您的业务中使用了一个有意义的表达式,请考虑使用规范。 +- **可测试**:规范是一个单独(且易于)测试的对象。 + +### 什么时侯不要使用? + +- **没有业务含义的表达式**:不要对与业务无关的表达式和操作使用规范。 +- **报表**:如果只是创建报表,不要创建规范,而是直接使用 `IQueryable` 和LINQ表达式。您甚至可以使用普通SQL、视图或其他工具生成报表。DDD不关心报表,因此从性能角度来看,查询底层数据存储的方式可能很重要。 From 8d5dd8260a1c2dee6d49d88d85901a5261fb3bf3 Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Fri, 11 Mar 2022 17:59:43 +0300 Subject: [PATCH 19/54] Move some localizations in AdminResources to BaseResources --- .../Admin/Localization/Resources/en.json | 12 ------------ .../Base/Localization/Resources/en.json | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index d2702c83b9..023a4b18ed 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -337,18 +337,6 @@ "Expired": "Expired", "TrialLicenseDeletionWarningMessage": "Are you sure you want to delete the trial license? Trial license, organization, support accounts will be deleted!", "LicenseCategoryFilter": "License category", - "Volo.AbpIo.Commercial:030000": "You already used your trial period.", - "Volo.AbpIo.Commercial:030001": "This organization name already exists.", - "Volo.AbpIo.Commercial:030002": "Once activated, trial license cannot be set to requested!", - "Volo.AbpIo.Commercial:030003": "There is no such status!", - "Volo.AbpIo.Commercial:030004": "Status could not be changed due to an unexpected error!", - "Volo.AbpIo.Commercial:030005": "Start and end date can be updated when the trial license is in the -activated- status!", - "Volo.AbpIo.Commercial:030006": "End date must always be greater than start date!", - "Volo.AbpIo.Commercial:030007": "This trial license has already been activated once!", - "Volo.AbpIo.Commercial:030008": "Purchase date can be set only when status is Purchased!", - "Volo.AbpIo.Commercial:030009": "User not found!", - "Volo.AbpIo.Commercial:030010": "To purchase the trial license, first you need to activate your trial license!", - "Volo.AbpIo.Commercial:030011": "You cannot delete a trial license when it is purchased!", "Permission:SendWelcomeEmail": "Send Welcome Email", "SendWelcomeEmail": "Send Welcome Email", "SendWelcomeEmailWarningMessage": "Are you sure you want to send welcome email to the organization members?", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index a214e251af..bfb5da247b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -14,6 +14,18 @@ "Volo.AbpIo.Domain:020002": "Could not delete this NPM Package because \"{Modules}\" Modules are using this package.", "Volo.AbpIo.Domain:020003": "Could not delete this NPM Package because \"{Modules}\" Modules are using this package and \"{NugetPackages}\" Nuget Packages are dependent to this package.", "Volo.AbpIo.Domain:020004": "Could not delete this Nuget Package because \"{Modules}\" Modules are using this package.", + "Volo.AbpIo.Domain:030000": "You already used your trial period.", + "Volo.AbpIo.Domain:030001": "This organization name already exists.", + "Volo.AbpIo.Domain:030002": "Once activated, trial license cannot be set to requested!", + "Volo.AbpIo.Domain:030003": "There is no such status!", + "Volo.AbpIo.Domain:030004": "Status could not be changed due to an unexpected error!", + "Volo.AbpIo.Domain:030005": "Start and end date can be updated when the trial license is in the -activated- status!", + "Volo.AbpIo.Domain:030006": "End date must always be greater than start date!", + "Volo.AbpIo.Domain:030007": "This trial license has already been activated once!", + "Volo.AbpIo.Domain:030008": "Purchase date can be set only when status is Purchased!", + "Volo.AbpIo.Domain:030009": "User not found!", + "Volo.AbpIo.Domain:030010": "To purchase the trial license, first you need to activate your trial license!", + "Volo.AbpIo.Domain:030011": "You cannot delete a trial license when it is purchased!", "WantToLearn?": "Want to learn?", "ReadyToGetStarted?": "Ready to get started?", "JoinOurCommunity": "Join our community", From 0a6d01454c714d3eb3b89488484fe7aa0b663033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 11 Mar 2022 22:11:16 +0300 Subject: [PATCH 20/54] Revised the distributed locking document. --- docs/en/Distributed-Locking.md | 107 +++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index 7a87132fa6..cbcff02a48 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -1,77 +1,104 @@ # Distributed Locking -Distributed locking is very useful to manage many applications that trying to access the same resource. +Distributed locking is technique to manage many applications that trying to access the same resource. The main purpose is to allow only one of many applications to access the same resource at the same time. Otherwise accessing the same object from various applications may corrupt the value of resources. -On this occasion, distributed locking protects the correct value throughout the applications. -> To use in ABP, you should download the below NuGet package or can open any command apps and run the below command. +> ABP's current distributed locking implementation is based on the [DistributedLock](https://github.com/madelson/DistributedLock) library. + +## Installation + +You can open a command-line terminal and type the following command to install the [Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking) package it into your project: + ````powershell abp add-package Volo.Abp.DistributedLocking ```` -````csharp -using Volo.Abp.DistributedLocking; -namespace AbpDemo -{ - public class MyService : ITransientDependency - { - private readonly IAbpDistributedLock _distributedLock; - public MyService(IAbpDistributedLock distributedLock) - { - _distributedLock = distributedLock; - } - - public async Task MyMethodAsync() - { - await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) - { - if (handle != null) - { - //your code - } - } - } - } -} -```` +This package provides the necessary API to use the distributed locking system, however, you should configure a provider before using it. -This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. -`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise, it will be seen as a different lock. -`timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. -`cancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +### Configuring a provider -ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. ABP implements the Redis provider for you and you may customize the others yourselves. +The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md). -Firstly, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. +For example, if you want to use the [Redis provider](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md), you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the `ConfigureServices` method of your ABP [module](Module-Development-Basics.md) class: ````csharp using Medallion.Threading; using Medallion.Threading.Redis; + namespace AbpDemo { public class MyModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - //the other configurations var configuration = context.Services.GetConfiguration(); context.Services.AddSingleton(sp => { - var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); + var connection = ConnectionMultiplexer + .Connect(configuration["Redis:Configuration"]); + return new + RedisDistributedSynchronizationProvider(connection.GetDatabase()); }); } } } ```` -Also, you should add your Redis configuration in appsetting.json. -You may change the structure of the JSON file but it must match with the above configuration code. +This code gets the Redis connection string from the [configuration](Configuration.md), so you can add the following lines to your `appsettings.json` file: + ````json "Redis": { "Configuration": "127.0.0.1" } ```` -As mentioned above, this implementation is for Redis and for more detail you can visit [the GitHub site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file +## Usage + +There are two ways to use the distributed locking API: ABP's `IAbpDistributedLock` abstraction and [DistributedLock](https://github.com/madelson/DistributedLock) library's API. + +### Using the IAbpDistributedLock service + +`IAbpDistributedLock` is a simple service provided by the ABP framework for simple usage of distributed locking. + +**Example: Using `IAbpDistributedLock.TryAcquireAsync` method** + +````csharp +using Volo.Abp.DistributedLocking; + +namespace AbpDemo +{ + public class MyService : ITransientDependency + { + private readonly IAbpDistributedLock _distributedLock; + public MyService(IAbpDistributedLock distributedLock) + { + _distributedLock = distributedLock; + } + + public async Task MyMethodAsync() + { + await using (var handle = + await _distributedLock.TryAcquireAsync("MyLockName")) + { + if (handle != null) + { + // your code that access the shared resource + } + } + } + } +} +```` + +`TryAcquireAsync` may not acquire the lock. It returns `null` if the lock could not be acquired. In this case, you shouldn't access the resource. If the handle is not `null`, it means that you've obtained the lock and can safely access the resource. + +`TryAcquireAsync` method gets the following parameters: + +* `name` (`string`, required): Unique name of your lock. Different named locks are used to access different resources. +* `timeout` (`TimeSpan`): A timeout value to wait to obtain the lock. Default value is `TimeSpan.Zero`, which means it doesn't wait if the lock is already owned by another application. +* `cancellationToken`: A cancellation token that can be triggered later to cancel the operation. + +### Using DistributedLock library's API + +ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. \ No newline at end of file From edf68354bc87abde35da2acd9745f49c5b0e3adf Mon Sep 17 00:00:00 2001 From: Gianpiero Caretti Date: Sat, 12 Mar 2022 01:04:54 +0100 Subject: [PATCH 21/54] Documentation fix for AddBackgroundWorkerAsync Fixed the code sample by correctly call AddBackgroundWorkerAsync instead of AddBackgroundWorker --- docs/en/Background-Workers.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/Background-Workers.md b/docs/en/Background-Workers.md index 0c9e26e409..726a8817ab 100644 --- a/docs/en/Background-Workers.md +++ b/docs/en/Background-Workers.md @@ -86,20 +86,20 @@ After creating a background worker class, you should add it to the `IBackgroundW [DependsOn(typeof(AbpBackgroundWorkersModule))] public class MyModule : AbpModule { - public override void OnApplicationInitialization( + public override Task OnApplicationInitializationAsync( ApplicationInitializationContext context) { - context.AddBackgroundWorker(); + context.AddBackgroundWorkerAsync(); } } ```` -`context.AddBackgroundWorker(...)` is a shortcut extension method for the expression below: +`context.AddBackgroundWorkerAsync(...)` is a shortcut extension method for the expression below: ````csharp -context.ServiceProvider +await context.ServiceProvider .GetRequiredService() - .Add( + .AddAsync( context .ServiceProvider .GetRequiredService() From 1263bf51e6a82494d77926513bdfc4dca913640e Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Sat, 12 Mar 2022 13:27:44 +0800 Subject: [PATCH 22/54] Update Background-Jobs.md --- docs/zh-Hans/Modules/Background-Jobs.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/zh-Hans/Modules/Background-Jobs.md b/docs/zh-Hans/Modules/Background-Jobs.md index 87c57acde7..fe021f1a56 100644 --- a/docs/zh-Hans/Modules/Background-Jobs.md +++ b/docs/zh-Hans/Modules/Background-Jobs.md @@ -1,16 +1,16 @@ # 后台作业模块 -后台作业模块实现了 `IBackgroundJobStore` 接口,并且可以使用ABP框架的默认后台作业管理。如果你不想使用这个模块,那么你需要自己实现 `IBackgroundJobStore` 接口。 +后台作业模块实现了 `IBackgroundJobStore` 接口,并且可以使用ABP框架的默认后台作业管理.如果你不想使用这个模块,那么你需要自己实现 `IBackgroundJobStore` 接口. -> 本文档仅介绍后台作业模块,该模块将后台作业持久化到数据库。有关后台作业系统的更多信息,请参阅[后台作业](../Background-Jobs.md)文档。 +> 本文档仅介绍后台作业模块,该模块将后台作业持久化到数据库.有关后台作业系统的更多信息,请参阅[后台作业](../Background-Jobs.md)文档. ## 如何使用 -当您使用ABP框架[创建一个新的解决方案](https://abp.io/get-started)时,这个模块是(作为NuGet/NPM包)预先安装的。您可以继续将其作为软件包使用并轻松获取更新,也可以将其源代码包含到解决方案中(请参阅 `get-source` [CLI](../CLI.md)命令)以开发自定义模块。 +当你使用ABP框架[创建一个新的解决方案](https://abp.io/get-started)时,这个模块是(作为NuGet/NPM包)预先安装的.你可以继续将其作为软件包使用并轻松获取更新,也可以将其源代码包含到解决方案中(请参阅 `get-source` [CLI](../CLI.md)命令)以开发自定义模块. ### 源代码 -此模块的源代码可在[此处](https://github.com/abpframework/abp/tree/dev/modules/background-jobs)访问。源代码是由[麻省理工学院](https://choosealicense.com/licenses/mit/)授权的,所以你可以自由使用和定制它。 +此模块的源代码可在[此处](https://github.com/abpframework/abp/tree/dev/modules/background-jobs)访问.源代码是由[MIT](https://choosealicense.com/licenses/mit/)授权的,所以你可以自由使用和定制它. ## 内部结构 @@ -32,11 +32,11 @@ ##### 表/集合的前缀与架构 -默认情况下,所有表/集合都使用 `Abp` 前缀。如果需要更改表前缀或设置架构名称(如果数据库提供程序支持),请在 `BackgroundJobsDbProperties` 类上设置静态属性。 +默认情况下,所有表/集合都使用 `Abp` 前缀.如果需要更改表前缀或设置架构名称(如果数据库提供程序支持),请在 `BackgroundJobsDbProperties` 类上设置静态属性. ##### 连接字符串 -此模块使用 `AbpBackgroundJobs` 作为连接字符串名称。如果不使用此名称定义连接字符串,它将返回 `Default` 连接字符串。有关详细信息,请参阅[连接字符串](https://docs.abp.io/en/abp/latest/Connection-Strings)文档。 +此模块使用 `AbpBackgroundJobs` 作为连接字符串名称.如果不使用此名称定义连接字符串,它将返回 `Default` 连接字符串.有关详细信息,请参阅[连接字符串](https://docs.abp.io/en/abp/latest/Connection-Strings)文档. #### Entity Framework Core From 00014eee2f58f50d5b3508cffe5b42ede6694e69 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Sat, 12 Mar 2022 13:30:19 +0800 Subject: [PATCH 23/54] Update Specifications.md --- docs/zh-Hans/Specifications.md | 70 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/zh-Hans/Specifications.md b/docs/zh-Hans/Specifications.md index bc5c67101b..40a473dbc0 100644 --- a/docs/zh-Hans/Specifications.md +++ b/docs/zh-Hans/Specifications.md @@ -1,22 +1,22 @@ -## 规范 +## 规约 -规范模式用于为实体和其他业务对象定义 **命名、可复用、可组合和可测试的过滤器** 。 +规约模式用于为实体和其他业务对象定义 **命名、可复用、可组合和可测试的过滤器** . -> 规范是领域层的一部分。 +> 规约是领域层的一部分. ## 安装 -> 这个包 **已经安装** 在启动模板中。所以,大多数时候你不需要手动去安装。 +> 这个包 **已经安装** 在启动模板中.所以,大多数时候你不需要手动去安装. -添加 [Volo.Abp.Specifications](https://abp.io/package-detail/Volo.Abp.Specifications) 包到你的项目. 如果当前文件夹是您的项目的根目录(`.csproj`)时,您可以在命令行终端中使用 [ABP CLI](CLI.md) *add package* 命令: +添加 [Volo.Abp.Specifications](https://abp.io/package-detail/Volo.Abp.Specifications) 包到你的项目. 如果当前文件夹是你的项目的根目录(`.csproj`)时,你可以在命令行终端中使用 [ABP CLI](CLI.md) *add package* 命令: ````bash abp add-package Volo.Abp.Specifications ```` -## 定义规范 +## 定义规约 -假设您定义了如下的顾客实体: +假设你定义了如下的顾客实体: ````csharp using System; @@ -37,9 +37,9 @@ namespace MyProject } ```` -您可以创建一个由 `Specification` 派生的新规范类。 +你可以创建一个由 `Specification` 派生的新规约类. -**例如:规定选择一个18岁以上的顾客** +**例如:规定选择一个18岁以上的顾客** ````csharp using System; @@ -58,19 +58,19 @@ namespace MyProject } ```` -您只需通过定义一个lambda[表达式](https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/lambda-expressions)来定义规范。 +你只需通过定义一个lambda[表达式](https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/lambda-expressions)来定义规约. -> 您也可以直接实现`ISpecification`接口,但是基类`Specification`做了大量简化。 +> 你也可以直接实现`ISpecification`接口,但是基类`Specification`做了大量简化. -## 使用规范 +## 使用规约 -这里有两种常见的规范用例。 +这里有两种常见的规约用例. ### IsSatisfiedBy -`IsSatisfiedBy` 方法可以用于检查单个对象是否满足规范。 +`IsSatisfiedBy` 方法可以用于检查单个对象是否满足规约. -**例如:如果顾客不满足年龄规定,则抛出异常** +**例如:如果顾客不满足年龄规定,则抛出异常** ````csharp using System; @@ -98,7 +98,7 @@ namespace MyProject ### ToExpression & Repositories -`ToExpression()` 方法可用于将规范转化为表达式。通过这种方式,您可以使用规范在**数据库查询时过滤实体**。 +`ToExpression()` 方法可用于将规约转化为表达式.通过这种方式,你可以使用规约在**数据库查询时过滤实体**. ````csharp using System; @@ -133,9 +133,9 @@ namespace MyProject } ```` -> 规范被正确地转换为SQL/数据库查询语句,并且在DBMS端高效执行。虽然它与规范无关,但如果您想了解有关 `AsyncExecuter` 的更多信息,请参阅[仓储](Repositories.md)文档。 +> 规约被正确地转换为SQL/数据库查询语句,并且在DBMS端高效执行.虽然它与规约无关,但如果你想了解有关 `AsyncExecuter` 的更多信息,请参阅[仓储](Repositories.md)文档. -实际上,没有必要使用 `ToExpression()` 方法,因为规范会自动转换为表达式。这也会起作用: +实际上,没有必要使用 `ToExpression()` 方法,因为规约会自动转换为表达式.这也会起作用: ````csharp var queryable = await _customerRepository.GetQueryableAsync(); @@ -144,11 +144,11 @@ var query = queryable.Where( ); ```` -## 编写规范 +## 编写规约 -规范有一个强大的功能是,它们可以与`And`、`Or`、`Not`以及`AndNot`扩展方法组合使用。 +规约有一个强大的功能是,它们可以与`And`、`Or`、`Not`以及`AndNot`扩展方法组合使用. -假设您有另一个规范,定义如下: +假设你有另一个规约,定义如下: ```csharp using System; @@ -167,7 +167,7 @@ namespace MyProject } ``` -您可以将 `PremiumCustomerSpecification` 和 `Age18PlusCustomerSpecification` 结合起来,查询优质成人顾客的数量,如下所示: +你可以将 `PremiumCustomerSpecification` 和 `Age18PlusCustomerSpecification` 结合起来,查询优质成人顾客的数量,如下所示: ````csharp using System; @@ -199,7 +199,7 @@ namespace MyProject } ```` -如果你想让这个组合成为一个可复用的规范,你可以创建这样一个组合的规范类,它派生自`AndSpecification`: +如果你想让这个组合成为一个可复用的规约,你可以创建这样一个组合的规约类,它派生自`AndSpecification`: ````csharp using Volo.Abp.Specifications; @@ -217,7 +217,7 @@ namespace MyProject } ```` -现在,您就可以向下面一样重新编写 `GetAdultPremiumCustomerCountAsync` 方法: +现在,你就可以向下面一样重新编写 `GetAdultPremiumCustomerCountAsync` 方法: ````csharp public async Task GetAdultPremiumCustomerCountAsync() @@ -228,30 +228,30 @@ public async Task GetAdultPremiumCustomerCountAsync() } ```` -> 你可以从这些例子中看到规范的强大之处。如果您之后想要更改 `PremiumCustomerSpecification` ,比如将余额从 `100.000` 修改为 `200.000` ,所有查询语句和合并的规范都将受到本次更改的影响。这是减少代码重复的好方法! +> 你可以从这些例子中看到规约的强大之处.如果你之后想要更改 `PremiumCustomerSpecification` ,比如将余额从 `100.000` 修改为 `200.000` ,所有查询语句和合并的规约都将受到本次更改的影响.这是减少代码重复的好方法! ## 讨论 -虽然规范模式通常与C#的lambda表达式相比较,算是一种更老的方式。一些开发人员可能认为不再需要它,我们可以直接将表达式传入到仓储或领域服务中,如下所示: +虽然规约模式通常与C#的lambda表达式相比较,算是一种更老的方式.一些开发人员可能认为不再需要它,我们可以直接将表达式传入到仓储或领域服务中,如下所示: ````csharp var count = await _customerRepository.CountAsync(c => c.Balance > 100000 && c.Age => 18); ```` -自从ABP的[仓储](Repositories.md)支持表达式,这是一个完全有效的用法。您不必在应用程序中定义或使用任何规范,可以直接使用表达式。 +自从ABP的[仓储](Repositories.md)支持表达式,这是一个完全有效的用法.你不必在应用程序中定义或使用任何规约,可以直接使用表达式. -所以,规范的意义是什么?为什么或者应该在什么时候考虑去使用它? +所以,规约的意义是什么?为什么或者应该在什么时候考虑去使用它? ### 何时使用? -使用规范的一些好处: +使用规约的一些好处: -- **可复用**:假设您在代码库的许多地方都需要用到优质顾客过滤器。如果使用表达式而不创建规范,那么如果以后更改“优质顾客”的定义会发生什么?假设您想将最低余额从100000美元更改为250000美元,并添加另一个条件,成为顾客超过3年。如果使用了规范,只需修改一个类。如果在任何其他地方重复(复制/粘贴)相同的表达式,则需要更改所有的表达式。 -- **可组合**:可以组合多个规范来创建新规范。这是另一种可复用性。 -- **命名**:`PremiumCustomerSpecification` 更好地解释了为什么使用规范,而不是复杂的表达式。因此,如果在您的业务中使用了一个有意义的表达式,请考虑使用规范。 -- **可测试**:规范是一个单独(且易于)测试的对象。 +- **可复用**:假设你在代码库的许多地方都需要用到优质顾客过滤器.如果使用表达式而不创建规约,那么如果以后更改“优质顾客”的定义会发生什么?假设你想将最低余额从100000美元更改为250000美元,并添加另一个条件,成为顾客超过3年.如果使用了规约,只需修改一个类.如果在任何其他地方重复(复制/粘贴)相同的表达式,则需要更改所有的表达式. +- **可组合**:可以组合多个规约来创建新规约.这是另一种可复用性. +- **命名**:`PremiumCustomerSpecification` 更好地解释了为什么使用规约,而不是复杂的表达式.因此,如果在你的业务中使用了一个有意义的表达式,请考虑使用规约. +- **可测试**:规约是一个单独(且易于)测试的对象. ### 什么时侯不要使用? -- **没有业务含义的表达式**:不要对与业务无关的表达式和操作使用规范。 -- **报表**:如果只是创建报表,不要创建规范,而是直接使用 `IQueryable` 和LINQ表达式。您甚至可以使用普通SQL、视图或其他工具生成报表。DDD不关心报表,因此从性能角度来看,查询底层数据存储的方式可能很重要。 +- **没有业务含义的表达式**:不要对与业务无关的表达式和操作使用规约. +- **报表**:如果只是创建报表,不要创建规约,而是直接使用 `IQueryable` 和LINQ表达式.你甚至可以使用普通SQL、视图或其他工具生成报表.DDD不关心报表,因此从性能角度来看,查询底层数据存储的方式可能很重要. From ea2b90a26e80fe00515e6e5eb3beb96cd990c231 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Sat, 12 Mar 2022 08:52:04 +0300 Subject: [PATCH 24/54] Update Distributed-Locking.md --- docs/en/Distributed-Locking.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index cbcff02a48..fd59a6a7c9 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -9,7 +9,7 @@ Otherwise accessing the same object from various applications may corrupt the va You can open a command-line terminal and type the following command to install the [Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking) package it into your project: -````powershell +````bash abp add-package Volo.Abp.DistributedLocking ```` @@ -17,7 +17,7 @@ This package provides the necessary API to use the distributed locking system, h ### Configuring a provider -The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md). +The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md). For example, if you want to use the [Redis provider](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md), you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the `ConfigureServices` method of your ABP [module](Module-Development-Basics.md) class: @@ -101,4 +101,4 @@ namespace AbpDemo ### Using DistributedLock library's API -ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. \ No newline at end of file +ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. From 848c4947b87cc88d3a18f6079ea2a21fefd6e62a Mon Sep 17 00:00:00 2001 From: albert <9526587+ebicoglu@users.noreply.github.com> Date: Sat, 12 Mar 2022 19:39:18 +0300 Subject: [PATCH 25/54] Update en.json --- .../Base/Localization/Resources/en.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index bfb5da247b..fe0947da89 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -14,17 +14,17 @@ "Volo.AbpIo.Domain:020002": "Could not delete this NPM Package because \"{Modules}\" Modules are using this package.", "Volo.AbpIo.Domain:020003": "Could not delete this NPM Package because \"{Modules}\" Modules are using this package and \"{NugetPackages}\" Nuget Packages are dependent to this package.", "Volo.AbpIo.Domain:020004": "Could not delete this Nuget Package because \"{Modules}\" Modules are using this package.", - "Volo.AbpIo.Domain:030000": "You already used your trial period.", + "Volo.AbpIo.Domain:030000": "You have already completed your trial period.", "Volo.AbpIo.Domain:030001": "This organization name already exists.", - "Volo.AbpIo.Domain:030002": "Once activated, trial license cannot be set to requested!", + "Volo.AbpIo.Domain:030002": "Once activated, you cannot switch the trial license to -requested- status!", "Volo.AbpIo.Domain:030003": "There is no such status!", "Volo.AbpIo.Domain:030004": "Status could not be changed due to an unexpected error!", "Volo.AbpIo.Domain:030005": "Start and end date can be updated when the trial license is in the -activated- status!", - "Volo.AbpIo.Domain:030006": "End date must always be greater than start date!", - "Volo.AbpIo.Domain:030007": "This trial license has already been activated once!", - "Volo.AbpIo.Domain:030008": "Purchase date can be set only when status is Purchased!", + "Volo.AbpIo.Domain:030006": "The end date must be greater than the start date!", + "Volo.AbpIo.Domain:030007": "This trial license has already been activated!", + "Volo.AbpIo.Domain:030008": "The purchase date can be set only when the status is -purchased-!", "Volo.AbpIo.Domain:030009": "User not found!", - "Volo.AbpIo.Domain:030010": "To purchase the trial license, first you need to activate your trial license!", + "Volo.AbpIo.Domain:030010": "To purchase the trial license, you first need to activate your trial license!", "Volo.AbpIo.Domain:030011": "You cannot delete a trial license when it is purchased!", "WantToLearn?": "Want to learn?", "ReadyToGetStarted?": "Ready to get started?", From 1d55148dd92bab085dd6b5ff24a0b52c86c6aebc Mon Sep 17 00:00:00 2001 From: braim23 <94292623+braim23@users.noreply.github.com> Date: Sun, 13 Mar 2022 22:44:12 +0300 Subject: [PATCH 26/54] Update Distributed-Locking.md --- docs/en/Distributed-Locking.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index fd59a6a7c9..bea10645ca 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -1,13 +1,13 @@ # Distributed Locking -Distributed locking is technique to manage many applications that trying to access the same resource. +Distributed locking is a technique to manage many applications that try to access the same resource. The main purpose is to allow only one of many applications to access the same resource at the same time. -Otherwise accessing the same object from various applications may corrupt the value of resources. +Otherwise, accessing the same object from various applications may corrupt the value of resources. > ABP's current distributed locking implementation is based on the [DistributedLock](https://github.com/madelson/DistributedLock) library. ## Installation -You can open a command-line terminal and type the following command to install the [Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking) package it into your project: +You can open a command-line terminal and type the following command to install the [Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking) package into your project: ````bash abp add-package Volo.Abp.DistributedLocking @@ -61,7 +61,7 @@ There are two ways to use the distributed locking API: ABP's `IAbpDistributedLoc `IAbpDistributedLock` is a simple service provided by the ABP framework for simple usage of distributed locking. -**Example: Using `IAbpDistributedLock.TryAcquireAsync` method** +**Example: Using the `IAbpDistributedLock.TryAcquireAsync` method** ````csharp using Volo.Abp.DistributedLocking; @@ -101,4 +101,4 @@ namespace AbpDemo ### Using DistributedLock library's API -ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. +ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use the DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. From 9c0993bb8b547fd2c3bb8d45a2af11e8b0318f22 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 14 Mar 2022 10:19:58 +0800 Subject: [PATCH 27/54] Update Features.md Close #11931 --- docs/en/Features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Features.md b/docs/en/Features.md index 3b1869a9a5..7e8802da96 100644 --- a/docs/en/Features.md +++ b/docs/en/Features.md @@ -308,7 +308,7 @@ The example above defines a *Reporting* feature with two children: *PDF Reportin ### Changing Features Definitions of a Depended Module -A class deriving from the `FeatureDefinitionProvider` (just like the example above) can also get the existing permission definitions (defined by the depended [modules](Module-Development-Basics.md)) and change their definitions. +A class deriving from the `FeatureDefinitionProvider` (just like the example above) can also get the existing feature definitions (defined by the depended [modules](Module-Development-Basics.md)) and change their definitions. **Example: Manipulate an existing feature definition** @@ -437,4 +437,4 @@ Use this code inside the `ConfigureServices` of your [module](Module-Development ### Feature Store -`IFeatureStore` is the only interface that needs to be implemented to read the value of features from a persistence source, generally a database system. The Feature Management module implements it and pre-installed in the application startup template. See the [feature management module documentation](https://docs.abp.io/en/abp/latest/Modules/Feature-Management) for more information \ No newline at end of file +`IFeatureStore` is the only interface that needs to be implemented to read the value of features from a persistence source, generally a database system. The Feature Management module implements it and pre-installed in the application startup template. See the [feature management module documentation](https://docs.abp.io/en/abp/latest/Modules/Feature-Management) for more information From b870fbe4769add75cab464791b546bad18f61af0 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 14 Mar 2022 08:54:31 +0300 Subject: [PATCH 28/54] Add code-mirror mapping for test app --- .../Volo.CmsKit.Web.Unified/abp.resourcemapping.js | 5 ++++- .../host/Volo.CmsKit.Web.Unified/package.json | 3 ++- .../cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock | 13 +++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js index 82b2d4b649..b473302023 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js @@ -7,6 +7,9 @@ module.exports = { "@libs" ], mappings: { - + "@node_modules/codemirror/lib/*.*": "@libs/codemirror/", + "@node_modules/codemirror/mode/**/*.*": "@libs/codemirror/mode/", + "@node_modules/codemirror/theme/**/*.*": "@libs/codemirror/theme/", + "@node_modules/codemirror/addon/**/*.*": "@libs/codemirror/addon/" } } \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json index c27b4dc457..909a876b9d 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@abp/aspnetcore.mvc.ui.theme.basic": "^5.2.0-rc.1", - "@abp/cms-kit": "5.2.0-rc.1" + "@abp/cms-kit": "5.2.0-rc.1", + "@abp/codemirror": "~5.2.0-rc.1" } } \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock index 47305a1cad..e69e2daced 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock @@ -90,6 +90,14 @@ "@abp/cms-kit.admin" "~5.2.0-rc.1" "@abp/cms-kit.public" "~5.2.0-rc.1" +"@abp/codemirror@~5.2.0-rc.1": + version "5.2.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-5.2.0-rc.1.tgz#0f06b4396056d1f3c854e67127d84781690d554f" + integrity sha512-iYl9LnHJTZFGUF/WJdGwXwTDUtfrodqr4RAEG+OBETe55yjGLmEW9cRjqgyZdX8UZvYGv9kSD3ScVUrv3woa/A== + dependencies: + "@abp/core" "~5.2.0-rc.1" + codemirror "^5.65.1" + "@abp/core@~5.2.0-rc.1": version "5.2.0-rc.1" resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.2.0-rc.1.tgz#28dd4949d6b45a2a75f4b76fe0b78b9fa809755d" @@ -987,6 +995,11 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +codemirror@^5.65.1: + version "5.65.2" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.2.tgz#5799a70cb3d706e10f60e267245e3a75205d3dd9" + integrity sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA== + collection-map@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" From 68194d7f85b736e5834aeab6700b4c97a1dcf8d1 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 14 Mar 2022 09:08:52 +0300 Subject: [PATCH 29/54] Add style & script editor for Page Create/Update --- .../Pages/CmsKit/Pages/Create.cshtml | 9 ++++++-- .../Pages/CmsKit/Pages/Update.cshtml | 5 +++++ .../Pages/CmsKit/Pages/create.js | 22 +++++++++++++++++-- .../Pages/CmsKit/Pages/update.js | 18 +++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml index 841576e761..4671cb2ca2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml @@ -1,6 +1,7 @@ @page @using System.Globalization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.CmsKit.Admin.Web.Pages @@ -22,6 +23,9 @@ + + + @@ -31,6 +35,7 @@ @section styles { + } @@ -56,11 +61,11 @@ - + - + diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml index 1271502946..499ad1b633 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml @@ -1,6 +1,7 @@ @page "{Id}" @using System.Globalization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify @@ -23,6 +24,9 @@ + + + @@ -32,6 +36,7 @@ @section styles { + } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js index ffe37fe5a8..1de6021a7d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js @@ -6,22 +6,40 @@ $(function () { var $slug = $('#ViewModel_Slug'); var $buttonSubmit = $('#button-page-create'); + var scriptEditor = CodeMirror.fromTextArea(document.getElementById("ViewModel_Script"), { + mode: "javascript", + lineNumbers: true + }); + + var styleEditor = CodeMirror.fromTextArea(document.getElementById("ViewModel_Style"), { + mode: "css", + lineNumbers: true + }); + + $('.nav-tabs a').on('shown.bs.tab', function () { + scriptEditor.refresh(); + styleEditor.refresh(); + }); + $createForm.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; $createForm.on('submit', function (e) { e.preventDefault(); - + if ($createForm.valid()) { abp.ui.setBusy(); + $("#ViewModel_Style").val(styleEditor.getValue()); + $("#ViewModel_Script").val(scriptEditor.getValue()); + $createForm.ajaxSubmit({ success: function (result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); location.href = "../Pages"; }, - error: function(result){ + error: function (result) { abp.ui.clearBusy(); abp.notify.error(result.responseJSON.error.message); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js index 99af38b70c..6bd90dd934 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js @@ -7,6 +7,21 @@ $(function () { $formUpdate.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; + var scriptEditor = CodeMirror.fromTextArea(document.getElementById("ViewModel_Script"), { + mode: "javascript", + lineNumbers: true + }); + + var styleEditor = CodeMirror.fromTextArea(document.getElementById("ViewModel_Style"), { + mode: "css", + lineNumbers: true + }); + + $('.nav-tabs a').on('shown.bs.tab', function () { + scriptEditor.refresh(); + styleEditor.refresh(); + }); + $formUpdate.on('submit', function (e) { e.preventDefault(); @@ -14,6 +29,9 @@ $(function () { abp.ui.setBusy(); + $("#ViewModel_Style").val(styleEditor.getValue()); + $("#ViewModel_Script").val(scriptEditor.getValue()); + $formUpdate.ajaxSubmit({ success: function (result) { abp.notify.success(l('SuccessfullySaved')); From 880d23357af54ef7afca428dedc6bac10a089d9a Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 14 Mar 2022 09:32:21 +0300 Subject: [PATCH 30/54] Revert local changes for Volo.CmsKit.Web.Unified --- .../host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js | 4 ---- modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js index b473302023..26cdc6aad9 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/abp.resourcemapping.js @@ -7,9 +7,5 @@ module.exports = { "@libs" ], mappings: { - "@node_modules/codemirror/lib/*.*": "@libs/codemirror/", - "@node_modules/codemirror/mode/**/*.*": "@libs/codemirror/mode/", - "@node_modules/codemirror/theme/**/*.*": "@libs/codemirror/theme/", - "@node_modules/codemirror/addon/**/*.*": "@libs/codemirror/addon/" } } \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json index 909a876b9d..c27b4dc457 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json @@ -4,7 +4,6 @@ "private": true, "dependencies": { "@abp/aspnetcore.mvc.ui.theme.basic": "^5.2.0-rc.1", - "@abp/cms-kit": "5.2.0-rc.1", - "@abp/codemirror": "~5.2.0-rc.1" + "@abp/cms-kit": "5.2.0-rc.1" } } \ No newline at end of file From e40dfb586e18ac522614e0180aafbdc31a36d5b4 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 14 Mar 2022 09:33:14 +0300 Subject: [PATCH 31/54] Update yarn.lock --- .../cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock index e69e2daced..47305a1cad 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock @@ -90,14 +90,6 @@ "@abp/cms-kit.admin" "~5.2.0-rc.1" "@abp/cms-kit.public" "~5.2.0-rc.1" -"@abp/codemirror@~5.2.0-rc.1": - version "5.2.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-5.2.0-rc.1.tgz#0f06b4396056d1f3c854e67127d84781690d554f" - integrity sha512-iYl9LnHJTZFGUF/WJdGwXwTDUtfrodqr4RAEG+OBETe55yjGLmEW9cRjqgyZdX8UZvYGv9kSD3ScVUrv3woa/A== - dependencies: - "@abp/core" "~5.2.0-rc.1" - codemirror "^5.65.1" - "@abp/core@~5.2.0-rc.1": version "5.2.0-rc.1" resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.2.0-rc.1.tgz#28dd4949d6b45a2a75f4b76fe0b78b9fa809755d" @@ -995,11 +987,6 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codemirror@^5.65.1: - version "5.65.2" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.2.tgz#5799a70cb3d706e10f60e267245e3a75205d3dd9" - integrity sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA== - collection-map@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" From d703bfedae34bd110d0cd0e387335f00fdad66be Mon Sep 17 00:00:00 2001 From: mehmetuken Date: Mon, 14 Mar 2022 09:50:51 +0300 Subject: [PATCH 32/54] add imports.razor --- .../_Imports.razor | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/_Imports.razor diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/_Imports.razor b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/_Imports.razor new file mode 100644 index 0000000000..fe27745143 --- /dev/null +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/_Imports.razor @@ -0,0 +1,13 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using MyCompanyName.MyProjectName.Blazor.Server +@using Blazorise +@using Blazorise.DataGrid +@using Volo.Abp.BlazoriseUI +@using Volo.Abp.BlazoriseUI.Components \ No newline at end of file From e4dfad0a9e3806a11d91c8cb8f42647f6663cf87 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 14 Mar 2022 15:17:43 +0800 Subject: [PATCH 33/54] Fix Cross-site scripting problem --- npm/packs/jquery-form/abp.resourcemapping.js | 3 +-- npm/packs/jquery-form/src/jquery.form.min.js | 22 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 npm/packs/jquery-form/src/jquery.form.min.js diff --git a/npm/packs/jquery-form/abp.resourcemapping.js b/npm/packs/jquery-form/abp.resourcemapping.js index 259206e7ea..14e54dfd8f 100644 --- a/npm/packs/jquery-form/abp.resourcemapping.js +++ b/npm/packs/jquery-form/abp.resourcemapping.js @@ -1,6 +1,5 @@ module.exports = { mappings: { - "@node_modules/jquery-form/dist/jquery.form.min.js": "@libs/jquery-form/", - "@node_modules/jquery-form/dist/jquery.form.min.js.map": "@libs/jquery-form/" + "@node_modules/@abp/jquery-form/src/*.*": "@libs/jquery-form/" } } \ No newline at end of file diff --git a/npm/packs/jquery-form/src/jquery.form.min.js b/npm/packs/jquery-form/src/jquery.form.min.js new file mode 100644 index 0000000000..c794a23e13 --- /dev/null +++ b/npm/packs/jquery-form/src/jquery.form.min.js @@ -0,0 +1,22 @@ +/*! + * jQuery Form Plugin + * version: 4.3.0 + * Requires jQuery v1.7.2 or later + * Project repository: https://github.com/jquery-form/form + + * Copyright 2017 Kevin Morris + * Copyright 2006 M. Alsup + + * Dual licensed under the LGPL-2.1+ or MIT licenses + * https://github.com/jquery-form/form#license + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,r){return void 0===r&&(r="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(r),r}:e(jQuery)}(function(e){"use strict";var t=/\r?\n/g,r={};r.fileapi=void 0!==e('').get(0).files,r.formdata=void 0!==window.FormData;var a=!!e.fn.prop;function n(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(t.target).closest("form").ajaxSubmit(r))}function i(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=r.form;if(i.clk=r,"image"===r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function o(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}e.fn.attr2=function(){if(!a)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t,n,i,s){if(!this.length)return o("ajaxSubmit: skipping submit process - no element selected"),this;var u,c,l,f,d=this;"function"==typeof t?t={success:t}:"string"==typeof t||!1===t&&arguments.length>0?(t={url:t,data:n,dataType:i},"function"==typeof s&&(t.success=s)):void 0===t&&(t={}),u=t.method||t.type||this.attr2("method"),(l=(l="string"==typeof(c=t.url||this.attr2("action"))?e.trim(c):"")||window.location.href||"")&&(l=(l.match(/^([^#]+)/)||[])[1]),f=/(MSIE|Trident)/.test(navigator.userAgent||"")&&/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",t=e.extend(!0,{url:l,success:e.ajaxSettings.success,type:u||e.ajaxSettings.type,iframeSrc:f},t);var m={};if(this.trigger("form-pre-serialize",[this,t,m]),m.veto)return o("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(t.beforeSerialize&&!1===t.beforeSerialize(this,t))return o("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var p=t.traditional;void 0===p&&(p=e.ajaxSettings.traditional);var h,v=[],g=this.formToArray(t.semantic,v,t.filtering);if(t.data){var x=e.isFunction(t.data)?t.data(g):t.data;t.extraData=x,h=e.param(x,p)}if(t.beforeSubmit&&!1===t.beforeSubmit(g,this,t))return o("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[g,this,t,m]),m.veto)return o("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var y=e.param(g,p);h&&(y=y?y+"&"+h:h),"GET"===t.type.toUpperCase()?(t.url+=(t.url.indexOf("?")>=0?"&":"?")+y,t.data=null):t.data=y;var b=[];if(t.resetForm&&b.push(function(){d.resetForm()}),t.clearForm&&b.push(function(){d.clearForm(t.includeHidden)}),!t.dataType&&t.target){var T=t.success||function(){};b.push(function(r,a,n){var i=arguments,o=t.replaceTarget?"replaceWith":"html";"html"==o&&(r=e.parseHTML(e("
").text(r).html())),e(t.target)[o](r).each(function(){T.apply(this,i)})})}else t.success&&(e.isArray(t.success)?e.merge(b,t.success):b.push(t.success));if(t.success=function(e,r,a){for(var n=t.context||this,i=0,o=b.length;i0,k="multipart/form-data",D=d.attr("enctype")===k||d.attr("encoding")===k,A=r.fileapi&&r.formdata;o("fileAPI :"+A);var F,L=(S||D)&&!A;!1!==t.iframe&&(t.iframe||L)?t.closeKeepAlive?e.get(t.closeKeepAlive,function(){F=M(g)}):F=M(g):F=(S||D)&&A?function(r){for(var a=new FormData,n=0;n',j)).css({position:"absolute",top:"-1000px",left:"-1000px"}),m=f[0],p={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(t){var r="timeout"===t?"timeout":"aborted";o("aborting upload... "+r),this.aborted=1;try{m.contentWindow.document.execCommand&&m.contentWindow.document.execCommand("Stop")}catch(e){}f.attr("src",s.iframeSrc),p.error=r,s.error&&s.error.call(s.context,p,r,t),c&&e.event.trigger("ajaxError",[p,s,r]),s.complete&&s.complete.call(s.context,p,r)}},(c=s.global)&&0==e.active++&&e.event.trigger("ajaxStart"),c&&e.event.trigger("ajaxSend",[p,s]),s.beforeSend&&!1===s.beforeSend.call(s.context,p,s))return s.global&&e.active--,T.reject(),T;if(p.aborted)return T.reject(),T;(h=b.clk)&&(g=h.name)&&!h.disabled&&(s.extraData=s.extraData||{},s.extraData[g]=h.value,"image"===h.type&&(s.extraData[g+".x"]=b.clk_x,s.extraData[g+".y"]=b.clk_y));var S=1,k=2;function D(e){var t=null;try{e.contentWindow&&(t=e.contentWindow.document)}catch(e){o("cannot get iframe.contentWindow document: "+e)}if(t)return t;try{t=e.contentDocument?e.contentDocument:e.document}catch(r){o("cannot get iframe.contentDocument: "+r),t=e.document}return t}var A=e("meta[name=csrf-token]").attr("content"),F=e("meta[name=csrf-param]").attr("content");function L(){var t=d.attr2("target"),r=d.attr2("action"),a=d.attr("enctype")||d.attr("encoding")||"multipart/form-data";b.setAttribute("target",l),u&&!/post/i.test(u)||b.setAttribute("method","POST"),r!==s.url&&b.setAttribute("action",s.url),s.skipEncodingOverride||u&&!/post/i.test(u)||d.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),s.timeout&&(y=setTimeout(function(){x=!0,C(S)},s.timeout));var n=[];try{if(s.extraData)for(var i in s.extraData)s.extraData.hasOwnProperty(i)&&(e.isPlainObject(s.extraData[i])&&s.extraData[i].hasOwnProperty("name")&&s.extraData[i].hasOwnProperty("value")?n.push(e('',j).val(s.extraData[i].value).appendTo(b)[0]):n.push(e('',j).val(s.extraData[i]).appendTo(b)[0]));s.iframeTarget||f.appendTo(w),m.attachEvent?m.attachEvent("onload",C):m.addEventListener("load",C,!1),setTimeout(function e(){try{var t=D(m).readyState;o("state = "+t),t&&"uninitialized"===t.toLowerCase()&&setTimeout(e,50)}catch(e){o("Server abort: ",e," (",e.name,")"),C(k),y&&clearTimeout(y),y=void 0}},15);try{b.submit()}catch(e){document.createElement("form").submit.apply(b)}}finally{b.setAttribute("action",r),b.setAttribute("enctype",a),t?b.setAttribute("target",t):d.removeAttr("target"),e(n).remove()}}F&&A&&(s.extraData=s.extraData||{},s.extraData[F]=A),s.forceSync?L():setTimeout(L,10);var E,M,O,X=50;function C(t){if(!p.aborted&&!O){if((M=D(m))||(o("cannot access response document"),t=k),t===S&&p)return p.abort("timeout"),void T.reject(p,"timeout");if(t===k&&p)return p.abort("server abort"),void T.reject(p,"error","server abort");if(M&&M.location.href!==s.iframeSrc||x){m.detachEvent?m.detachEvent("onload",C):m.removeEventListener("load",C,!1);var r,a="success";try{if(x)throw"timeout";var n="xml"===s.dataType||M.XMLDocument||e.isXMLDoc(M);if(o("isXml="+n),!n&&window.opera&&(null===M.body||!M.body.innerHTML)&&--X)return o("requeing onLoad callback, DOM not available"),void setTimeout(C,250);var i=M.body?M.body:M.documentElement;p.responseText=i?i.innerHTML:null,p.responseXML=M.XMLDocument?M.XMLDocument:M,n&&(s.dataType="xml"),p.getResponseHeader=function(e){return{"content-type":s.dataType}[e.toLowerCase()]},i&&(p.status=Number(i.getAttribute("status"))||p.status,p.statusText=i.getAttribute("statusText")||p.statusText);var u=(s.dataType||"").toLowerCase(),l=/(json|script|text)/.test(u);if(l||s.textarea){var d=M.getElementsByTagName("textarea")[0];if(d)p.responseText=d.value,p.status=Number(d.getAttribute("status"))||p.status,p.statusText=d.getAttribute("statusText")||p.statusText;else if(l){var h=M.getElementsByTagName("pre")[0],v=M.getElementsByTagName("body")[0];h?p.responseText=h.textContent?h.textContent:h.innerText:v&&(p.responseText=v.textContent?v.textContent:v.innerText)}}else"xml"===u&&!p.responseXML&&p.responseText&&(p.responseXML=q(p.responseText));try{E=_(p,u,s)}catch(e){a="parsererror",p.error=r=e||a}}catch(e){o("error caught: ",e),a="error",p.error=r=e||a}p.aborted&&(o("upload aborted"),a=null),p.status&&(a=p.status>=200&&p.status<300||304===p.status?"success":"error"),"success"===a?(s.success&&s.success.call(s.context,E,"success",p),T.resolve(p.responseText,"success",p),c&&e.event.trigger("ajaxSuccess",[p,s])):a&&(void 0===r&&(r=p.statusText),s.error&&s.error.call(s.context,p,a,r),T.reject(p,"error",r),c&&e.event.trigger("ajaxError",[p,s,r])),c&&e.event.trigger("ajaxComplete",[p,s]),c&&!--e.active&&e.event.trigger("ajaxStop"),s.complete&&s.complete.call(s.context,p,a),O=!0,s.timeout&&clearTimeout(y),setTimeout(function(){s.iframeTarget?f.attr("src",s.iframeSrc):f.remove(),p.responseXML=null},100)}}}var q=e.parseXML||function(e,t){return window.ActiveXObject?((t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!==t.documentElement.nodeName?t:null},N=e.parseJSON||function(e){return window.console.error("jquery.parseJSON is undefined"),null},_=function(t,r,a){var n=t.getResponseHeader("content-type")||"",i=("xml"===r||!r)&&n.indexOf("xml")>=0,o=i?t.responseXML:t.responseText;return i&&"parsererror"===o.documentElement.nodeName&&e.error&&e.error("parsererror"),a&&a.dataFilter&&(o=a.dataFilter(o,r)),"string"==typeof o&&(("json"===r||!r)&&n.indexOf("json")>=0?o=N(o):("script"===r||!r)&&n.indexOf("javascript")>=0&&e.globalEval(o)),o};return T}},e.fn.ajaxForm=function(t,r,a,s){if(("string"==typeof t||!1===t&&arguments.length>0)&&(t={url:t,data:r,dataType:a},"function"==typeof s&&(t.success=s)),(t=t||{}).delegation=t.delegation&&e.isFunction(e.fn.on),!t.delegation&&0===this.length){var u={s:this.selector,c:this.context};return!e.isReady&&u.s?(o("DOM not ready, queuing ajaxForm"),e(function(){e(u.s,u.c).ajaxForm(t)}),this):(o("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)")),this)}return t.delegation?(e(document).off("submit.form-plugin",this.selector,n).off("click.form-plugin",this.selector,i).on("submit.form-plugin",this.selector,t,n).on("click.form-plugin",this.selector,t,i),this):(t.beforeFormUnbind&&t.beforeFormUnbind(this,t),this.ajaxFormUnbind().on("submit.form-plugin",t,n).on("click.form-plugin",t,i))},e.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},e.fn.formToArray=function(t,a,n){var i=[];if(0===this.length)return i;var o,s,u,c,l,f,d,m,p=this[0],h=this.attr("id"),v=t||void 0===p.elements?p.getElementsByTagName("*"):p.elements;if(v&&(v=e.makeArray(v)),h&&(t||/(Edge|Trident)\//.test(navigator.userAgent))&&(o=e(':input[form="'+h+'"]').get()).length&&(v=(v||[]).concat(o)),!v||!v.length)return i;for(e.isFunction(n)&&(v=e.map(v,n)),s=0,d=v.length;s Date: Mon, 14 Mar 2022 15:23:55 +0800 Subject: [PATCH 34/54] update abp.resourcemapping.js --- npm/packs/jquery-form/abp.resourcemapping.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/packs/jquery-form/abp.resourcemapping.js b/npm/packs/jquery-form/abp.resourcemapping.js index 14e54dfd8f..4ec5565b0c 100644 --- a/npm/packs/jquery-form/abp.resourcemapping.js +++ b/npm/packs/jquery-form/abp.resourcemapping.js @@ -1,5 +1,5 @@ module.exports = { mappings: { - "@node_modules/@abp/jquery-form/src/*.*": "@libs/jquery-form/" + "@node_modules/@abp/jquery-form/src/jquery.form.min.js": "@libs/jquery-form/" } } \ No newline at end of file From d5961fe50f46aba05d239cbe8c032f2dee6ceb02 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 14 Mar 2022 12:10:30 +0300 Subject: [PATCH 35/54] Cli: Convert single back-slashes to double back-slashes in connection string resolves https://github.com/volosoft/volo/issues/9339 --- .../Building/Steps/ConnectionStringChangeStep.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ConnectionStringChangeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ConnectionStringChangeStep.cs index 2292fed8e5..0f50a443e7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ConnectionStringChangeStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ConnectionStringChangeStep.cs @@ -26,7 +26,7 @@ public class ConnectionStringChangeStep : ProjectBuildPipelineStep return; } - var newConnectionString = $"\"{DefaultConnectionStringKey}\": \"{context.BuildArgs.ConnectionString}\""; + var newConnectionString = $"\"{DefaultConnectionStringKey}\": \"{context.BuildArgs.ConnectionString.Replace(@"\\", @"\").Replace(@"\", @"\\")}\""; foreach (var appSettingsJson in appSettingsJsonFiles) { From d6157e632f75e5859e0b65f10cde06df2333a46c Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Mon, 14 Mar 2022 13:14:56 +0300 Subject: [PATCH 36/54] Add new localizations for abp.io website --- .../AbpIoLocalization/Base/Localization/Resources/en.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index fe0947da89..f772006632 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -84,7 +84,7 @@ "WouldLikeToReceiveMarketingMaterials": "I would like to receive marketing materials like product deals & special offers.", "JoinOurMarketingNewsletter": "Join our marketing newsletter", "CommunityPrivacyPolicyConfirmation": "I agree to the Terms & Conditions and Privacy Policy.", - "ABPIO-Common": "ABPIO-Common", + "WouldLikeToReceiveNotification": "I would like to receive the latest news from abp.io websites.", "CommercialNewsletterConfirmationMessage": "I agree to the Terms & Conditions and Privacy Policy.", "FreeDDDEBook": "Free DDD E-Book", "AdditionalServices": "Additional Services", @@ -118,6 +118,7 @@ "ThereIsNoEvent": "There is no event.", "Events": "Events", "Volo.AbpIo.Domain:080000": "There is already a purchase item named \"{Name}\"", - "MasteringAbpFrameworkBook": "Book: Mastering ABP Framework" + "MasteringAbpFrameworkBook": "Book: Mastering ABP Framework", + "ABPIO-CommonPreferenceDefinition": "Get latest news about ABP Platform like new posts, events and more." } } From c543dd5c6b27a588918f43bc15981659780c7280 Mon Sep 17 00:00:00 2001 From: hpstory <33348162+hpstory@users.noreply.github.com> Date: Mon, 14 Mar 2022 20:47:18 +0800 Subject: [PATCH 37/54] Update distributed-Event-Bus.md Update Distributed-Event-Bus-RabbitMQ-Integration.md --- .../zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md index ab7cb68bd7..1cd6b5b9dd 100644 --- a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md +++ b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md @@ -1,10 +1,10 @@ # 分布式事件总线RabbitMQ集成 -> 本文解释了**如何配置[RabbitMQ](https://www.rabbitmq.com/)**做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. +> 本文解释了 **如何配置[RabbitMQ](https://www.rabbitmq.com/)** 做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. ## 安装 -使用ABP CLI添加[Volo.Abp.EventBus.RabbitMQ[Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ)NuGet包到你的项目: +使用ABP CLI添加[Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ)NuGet包到你的项目: * 安装[ABP CLI](https://docs.abp.io/en/abp/latest/CLI),如果你还没有安装. * 在你想要安装 `Volo.Abp.EventBus.RabbitMQ` 包的 `.csproj` 文件目录打开命令行(终端). @@ -18,7 +18,7 @@ ### `appsettings.json` 文件配置 -这是配置RabbitMQ设置最简单的方法. 它也非常强大,因为你可以使用[由AspNet Core支持的](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)的任何其他配置源(如环境变量). +这是配置RabbitMQ设置最简单的方法. 它也非常强大,因为你可以使用[由AspNet Core支持](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)的任何其他配置源(如环境变量). **示例:最小化配置与默认配置连接到本地的RabbitMQ服务器** @@ -151,4 +151,4 @@ Configure(options => }); ```` -使用这些选项类可以与 `appsettings.json` 组合在一起. 在代码中配置选项属性会覆盖配置文件中的值. \ No newline at end of file +使用这些选项类可以与 `appsettings.json` 组合在一起. 在代码中配置选项属性会覆盖配置文件中的值. From d2e1863bbf9cbb5bcf4bbfd0d8ec75199d59eac4 Mon Sep 17 00:00:00 2001 From: hpstory <33348162+hpstory@users.noreply.github.com> Date: Mon, 14 Mar 2022 20:49:42 +0800 Subject: [PATCH 38/54] Update Rebus-Integration.md Update Distributed-Event-Bus-Rebus-Integration.md --- docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md index 409b935ace..64fce06d1b 100644 --- a/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md +++ b/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md @@ -1,10 +1,10 @@ # 分布式事件总线Rebus集成 -> 本文解释了**如何配置[Rebus](http://mookid.dk/category/rebus/)**做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. +> 本文解释了 **如何配置[Rebus](http://mookid.dk/category/rebus/)** 做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. ## 安装 -使用ABP CLI添加[Volo.Abp.EventBus.Rebus[Volo.Abp.EventBus.Rebus](https://www.nuget.org/packages/Volo.Abp.EventBus.Rebus)NuGet包到你的项目: +使用ABP CLI添加[Volo.Abp.EventBus.Rebus](https://www.nuget.org/packages/Volo.Abp.EventBus.Rebus)NuGet包到你的项目: * 安装[ABP CLI](https://docs.abp.io/en/abp/latest/CLI),如果你还没有安装. * 在你想要安装 `Volo.Abp.EventBus.Rebus` 包的 `.csproj` 文件目录打开命令行(终端). From 069c338dcbf0037b01cee7c2a999faf9c94b2e62 Mon Sep 17 00:00:00 2001 From: hpstory <33348162+hpstory@users.noreply.github.com> Date: Mon, 14 Mar 2022 20:51:29 +0800 Subject: [PATCH 39/54] Update Kafka-Integration.md Update Distributed-Event-Bus-Kafka-Integration.md --- docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md index f621a95fae..171fe3c23b 100644 --- a/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md +++ b/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md @@ -1,10 +1,10 @@ # 分布式事件总线Kafka集成 -> 本文解释了**如何配置[Kafka](https://kafka.apache.org/)**做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. +> 本文解释了 **如何配置[Kafka](https://kafka.apache.org/)** 做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. ## 安装 -使用ABP CLI添加[Volo.Abp.EventBus.Kafka[Volo.Abp.EventBus.Kafka](https://www.nuget.org/packages/Volo.Abp.EventBus.Kafka)NuGet包到你的项目: +使用ABP CLI添加[Volo.Abp.EventBus.Kafka](https://www.nuget.org/packages/Volo.Abp.EventBus.Kafka)NuGet包到你的项目: * 安装[ABP CLI](https://docs.abp.io/en/abp/latest/CLI),如果你还没有安装. * 在你想要安装 `Volo.Abp.EventBus.Kafka` 包的 `.csproj` 文件目录打开命令行(终端). @@ -18,7 +18,7 @@ ### `appsettings.json` 文件配置 -这是配置Kafka设置最简单的方法. 它也非常强大,因为你可以使用[由AspNet Core支持的](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)的任何其他配置源(如环境变量). +这是配置Kafka设置最简单的方法. 它也非常强大,因为你可以使用[由AspNet Core支持](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)的任何其他配置源(如环境变量). **示例:最小化配置与默认配置连接到本地的Kafka服务器** @@ -160,4 +160,4 @@ Configure(options => }); ```` -使用这些选项类可以与 `appsettings.json` 组合在一起. 在代码中配置选项属性会覆盖配置文件中的值. \ No newline at end of file +使用这些选项类可以与 `appsettings.json` 组合在一起. 在代码中配置选项属性会覆盖配置文件中的值. From 2bb482deec38d4916baebb4103e90f03ed89b544 Mon Sep 17 00:00:00 2001 From: hpstory <33348162+hpstory@users.noreply.github.com> Date: Mon, 14 Mar 2022 20:52:43 +0800 Subject: [PATCH 40/54] Update Distributed-Event-Bus.md --- docs/zh-Hans/Distributed-Event-Bus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-Hans/Distributed-Event-Bus.md b/docs/zh-Hans/Distributed-Event-Bus.md index f16aa0610f..e59fa5e726 100644 --- a/docs/zh-Hans/Distributed-Event-Bus.md +++ b/docs/zh-Hans/Distributed-Event-Bus.md @@ -264,7 +264,7 @@ Configure(options => 因此可以实现 `IDistributedEventHandler>` 订阅事件. 但是订阅这样的通用事件不是一个好方法,你可以为实体类型定义对应的ETO. -**示例: 为 `Product` 声明使用 `ProductDto`** +**示例: 为 `Product` 声明使用 `ProductEto`** ````csharp Configure(options => From 59a85df75f18b231517a9192bc53aa567c69aba3 Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 14 Mar 2022 16:38:39 +0300 Subject: [PATCH 41/54] Add initial state of autocomplete select documentation --- docs/en/UI/AspNetCore/AutoComplete-Select.md | 43 ++++++++++++++++++ docs/en/images/abp-select2-multiple.png | Bin 0 -> 5591 bytes docs/en/images/abp-select2-single.png | Bin 0 -> 3896 bytes .../Volo.CmsKit.Web.Unified/appsettings.json | 2 +- .../Tags/Components/TagEditor/Default.cshtml | 30 +++++++----- .../Tags/Components/TagEditor/default.js | 15 ++++++ 6 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 docs/en/UI/AspNetCore/AutoComplete-Select.md create mode 100644 docs/en/images/abp-select2-multiple.png create mode 100644 docs/en/images/abp-select2-single.png diff --git a/docs/en/UI/AspNetCore/AutoComplete-Select.md b/docs/en/UI/AspNetCore/AutoComplete-Select.md new file mode 100644 index 0000000000..1a4705627d --- /dev/null +++ b/docs/en/UI/AspNetCore/AutoComplete-Select.md @@ -0,0 +1,43 @@ +# ASP.NET Core MVC / Razor Pages: Auto-Complete Select +A simple select component sometimes isn't useful with huge amount of data. ABP Provides a select implementation that works with pagination and server-side search via using [Select2](https://select2.org/). It works with single or multiple choices well. + +A screenshot can be shown below. + +| Single | Multiple | +| --- | --- | +| ![autocomplete-select-example](../../images/abp-select2-single.png) |![autocomplete-select-example](../../images/abp-select2-multiple.png) | + +## Getting Started + +This is a core feature and it's used by ABP Framework. There is no custom installation or additional package required. + +## Usage + +A simple is usage is presented below. The select must have `auto-complete-select` class and following attributes: + +- `data-autocomplete-api-url`: * API Endpoint url to get select items. **GET** request will be sent to this url. +- `data-autocomplete-display-property`: * Property name to display. _(For example: `name` ot `title`. Property name of entity/dto.)_. +- `data-autocomplete-value-property`: * Identifier property name. _(For example: `id`)_. +- `data-autocomplete-items-property`: * Property name of collection in response object. _(For example: `items`)_ +- `data-autocomplete-filter-param-name`: * Filter text property name. _(For example: `filter`)_. +- `data-autocomplete-selected-item-name`: Text to display as selected item. +- `data-autocomplete-parent-selector`: jQuery selector expression for parent DOM. _(If it's in a modal, it's suggested to send modal selector as this parameter)_. + + ```html + + ``` + + +## Possible Issues + +### Permission Restriction +If the authenticated user doesn't have permission on given url, user will get an authorization error. Be careful while designing this kind of UIs. + +You may place a lookup method in the same AppService, so your page can retrieve lookup daha of dependent entity without giving a entire read permission to users. \ No newline at end of file diff --git a/docs/en/images/abp-select2-multiple.png b/docs/en/images/abp-select2-multiple.png new file mode 100644 index 0000000000000000000000000000000000000000..bdc2d7cc95f3e2e6a0ebda0ff6f261752d4f1f29 GIT binary patch literal 5591 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 literal 0 HcmV?d00001 diff --git a/docs/en/images/abp-select2-single.png b/docs/en/images/abp-select2-single.png new file mode 100644 index 0000000000000000000000000000000000000000..219355dd661a7bf780e0f044616715c24f4ada5b GIT binary patch literal 3896 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 L -
+ -
- - -
+
+ + + @**@ +
- @if (Model.DisplaySubmitButton) - { - - - - } -
\ No newline at end of file + @if (Model.DisplaySubmitButton) + { + + + + } + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js index 834aedf3d6..e3607d48fd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js @@ -1,5 +1,20 @@ $(function () { + var $selectTags = $("#tags"); + + function initSelectTagEditor() { + $selectTags.data('autocompleteApiUrl', '/api/cms-kit-admin/tags'); + $selectTags.data('autocompleteDisplayProperty', 'name'); + $selectTags.data('autocompleteValueProperty', 'id'); + $selectTags.data('autocompleteItemsProperty', 'items'); + $selectTags.data('autocompleteFilterParamName', 'filter'); + + abp.dom.initializers.initializeAutocompleteSelects($selectTags); + } + + initSelectTagEditor(); + + var $tagEditorForms = $('.tag-editor-form'); $tagEditorForms.on('submit', function (e) { From cce1be21ca29de53a879647c56df624ca71f818d Mon Sep 17 00:00:00 2001 From: Enis Necipoglu Date: Mon, 14 Mar 2022 16:38:51 +0300 Subject: [PATCH 42/54] Update AutoComplete-Select.md --- docs/en/UI/AspNetCore/AutoComplete-Select.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/UI/AspNetCore/AutoComplete-Select.md b/docs/en/UI/AspNetCore/AutoComplete-Select.md index 1a4705627d..0fbeb4c6ae 100644 --- a/docs/en/UI/AspNetCore/AutoComplete-Select.md +++ b/docs/en/UI/AspNetCore/AutoComplete-Select.md @@ -31,6 +31,8 @@ A simple is usage is presented below. The select must have `auto-complete-select data-autocomplete-value-property="id" data-autocomplete-items-property="items" data-autocomplete-filter-param-name="filter"> + +