Browse Source

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

pull/21450/head
Dolunay 2 years ago
parent
commit
259692ccf5
  1. 8
      docs/en/tutorials/book-store/part-01.md
  2. 10
      docs/en/tutorials/book-store/part-02.md
  3. 8
      docs/en/tutorials/book-store/part-03.md
  4. 2
      docs/en/tutorials/book-store/part-04.md
  5. 8
      docs/en/tutorials/book-store/part-05.md
  6. 2
      docs/en/tutorials/book-store/part-06.md
  7. 2
      docs/en/tutorials/book-store/part-07.md
  8. 2
      docs/en/tutorials/book-store/part-08.md
  9. 12
      docs/en/tutorials/book-store/part-09.md
  10. 6
      docs/en/tutorials/book-store/part-10.md
  11. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs
  12. 5
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs
  13. 44
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs
  14. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
  15. 14
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.Generated.cs
  16. 117
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json
  17. 15
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs
  18. 59
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/DeleteBlogModal.cshtml
  19. 57
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/DeleteBlogModal.cshtml.cs
  20. 46
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/index.js
  21. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ar.json
  22. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/cs.json
  23. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/de-DE.json
  24. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/de.json
  25. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/el.json
  26. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en-GB.json
  27. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json
  28. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/es.json
  29. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fa.json
  30. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fi.json
  31. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json
  32. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hi.json
  33. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hr.json
  34. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hu.json
  35. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/is.json
  36. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/it.json
  37. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/nl.json
  38. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/pl-PL.json
  39. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/pt-BR.json
  40. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ro-RO.json
  41. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ru.json
  42. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sk.json
  43. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sl.json
  44. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sv.json
  45. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json
  46. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/vi.json
  47. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json
  48. 6
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hant.json
  49. 7
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs
  50. 14
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogWithBlogPostCount.cs
  51. 2
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs
  52. 7
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs
  53. 13
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs
  54. 25
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs
  55. 20
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs
  56. 27
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs

8
docs/en/tutorials/book-store/part-01.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````
@ -36,7 +36,7 @@ abp install-libs
> We suggest you install [Yarn](https://classic.yarnpkg.com/) to prevent possible package inconsistencies, if you haven't installed it yet. > We suggest you install [Yarn](https://classic.yarnpkg.com/) to prevent possible package inconsistencies, if you haven't installed it yet.
{{if UI=="Blazor" || UI=="BlazorServer"}} {{if UI=="Blazor" || UI=="BlazorWebApp"}}
### Bundling and Minification ### Bundling and Minification
@ -440,7 +440,7 @@ ABP can [**automagically**](../../framework/api-development/auto-controllers.md)
### Swagger UI ### Swagger UI
The startup template is configured to run the [Swagger UI](https://swagger.io/tools/swagger-ui/) using the [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) library. Run the application ({{if UI=="MVC"}}`Acme.BookStore.Web`{{else if UI=="BlazorServer"}}`Acme.BookStore.Blazor`{{else}}`Acme.BookStore.HttpApi.Host`{{end}}) by pressing `CTRL+F5` and navigate to `https://localhost:<port>/swagger/` on your browser. Replace `<port>` with your own port number. The startup template is configured to run the [Swagger UI](https://swagger.io/tools/swagger-ui/) using the [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) library. Run the application ({{if UI=="MVC"}}`Acme.BookStore.Web`{{else if UI=="BlazorServer" || UI=="BlazorWebApp"}}`Acme.BookStore.Blazor`{{else}}`Acme.BookStore.HttpApi.Host`{{end}}) by pressing `CTRL+F5` and navigate to `https://localhost:<port>/swagger/` on your browser. Replace `<port>` with your own port number.
You will see some built-in service endpoints as well as the `Book` service and its REST-style endpoints: You will see some built-in service endpoints as well as the `Book` service and its REST-style endpoints:
@ -480,4 +480,4 @@ If you try to execute the `[GET] /api/app/book` API to get a list of books, the
} }
```` ````
That's pretty cool since we haven't written a single line of code to create the API controller, but now we have a fully working REST API! That's pretty cool since we haven't written a single line of code to create the API controller, but now we have a fully working REST API!

10
docs/en/tutorials/book-store/part-02.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp", "NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````
@ -514,13 +514,13 @@ Now you can see the final result on your browser:
![Book list final result](images/bookstore-book-list-angular.png) ![Book list final result](images/bookstore-book-list-angular.png)
{{else if UI == "Blazor" || UI == "BlazorServer"}} {{else if UI == "Blazor" || UI == "BlazorServer" || UI == "BlazorWebApp"}}
## Create a Books Page ## Create a Books Page
It's time to create something visible and usable! Right click on the `Pages` folder under the {{ if UI == "Blazor"}}`Acme.BookStore.Blazor.Client`{{ else }}`Acme.BookStore.Blazor`{{ end }} project and add a new **razor component**, named `Books.razor`: It's time to create something visible and usable! Right click on the `Pages` folder under the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add a new **razor component**, named `Books.razor`:
{{ if UI == "Blazor"}} {{ if UI == "Blazor" || UI == "BlazorWebApp" }}
![blazor-add-books-component](images/blazor-add-books-component-client.png) ![blazor-add-books-component](images/blazor-add-books-component-client.png)
{{ else }} {{ else }}
![blazor-add-books-component](images/blazor-add-books-component.png) ![blazor-add-books-component](images/blazor-add-books-component.png)
@ -540,7 +540,7 @@ Replace the contents of this component as shown below:
### Add the Books Page to the Main Menu ### Add the Books Page to the Main Menu
Open the `BookStoreMenuContributor` class in the {{ if UI == "Blazor"}}`Acme.BookStore.Blazor.Client`{{ else }}`Acme.BookStore.Blazor`{{ end }} project add the following code to the end of the `ConfigureMainMenuAsync` method: Open the `BookStoreMenuContributor` class in the {{ if UI == "BlazorServer"}}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project add the following code to the end of the `ConfigureMainMenuAsync` method:
````csharp ````csharp
context.Menu.AddItem( context.Menu.AddItem(

8
docs/en/tutorials/book-store/part-03.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````
@ -1101,7 +1101,7 @@ Clicking the "Delete" action calls the `delete` method which then shows a confir
{{end}} {{end}}
{{if UI == "Blazor" || UI == "BlazorServer"}} {{if UI == "Blazor" || UI == "BlazorServer" || UI == "BlazorWebApp"}}
## Creating a New Book ## Creating a New Book
@ -1292,13 +1292,13 @@ We can now define a modal to edit the book. Add the following code to the end of
The base `AbpCrudPageBase` uses the [object to object mapping](../../framework/infrastructure/object-to-object-mapping.md) system to convert an incoming `BookDto` object to a `CreateUpdateBookDto` object. So, we need to define the mapping. The base `AbpCrudPageBase` uses the [object to object mapping](../../framework/infrastructure/object-to-object-mapping.md) system to convert an incoming `BookDto` object to a `CreateUpdateBookDto` object. So, we need to define the mapping.
Open the `BookStoreBlazorAutoMapperProfile` inside the `Acme.BookStore.Blazor.Client` project and change the content as the following: Open the `BookStoreBlazorAutoMapperProfile` inside the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and change the content as the following:
````csharp ````csharp
using Acme.BookStore.Books; using Acme.BookStore.Books;
using AutoMapper; using AutoMapper;
namespace Acme.BookStore.Blazor.Client; {{ if UI == "BlazorServer" }}namespace Acme.BookStore.Blazor;{{ else }}namespace Acme.BookStore.Blazor.Client;{{ end }}
public class BookStoreBlazorAutoMapperProfile : Profile public class BookStoreBlazorAutoMapperProfile : Profile
{ {

2
docs/en/tutorials/book-store/part-04.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````

8
docs/en/tutorials/book-store/part-05.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````
@ -389,11 +389,11 @@ Open the `/src/app/book/book.component.html` file and replace the edit and delet
* Added `*abpPermission="'BookStore.Books.Edit'"` that hides the edit action if the current user has no editing permission. * Added `*abpPermission="'BookStore.Books.Edit'"` that hides the edit action if the current user has no editing permission.
* Added `*abpPermission="'BookStore.Books.Delete'"` that hides the delete action if the current user has no delete permission. * Added `*abpPermission="'BookStore.Books.Delete'"` that hides the delete action if the current user has no delete permission.
{{else if UI == "Blazor"}} {{else if UI == "Blazor" || UI == "BlazorServer" || UI == "BlazorWebApp"}}
### Authorize the Razor Component ### Authorize the Razor Component
Open the `/Pages/Books.razor` file in the `Acme.BookStore.Blazor.Client` project and add an `Authorize` attribute just after the `@page` directive and the following namespace imports (`@using` lines), as shown below: Open the `/Pages/Books.razor` file in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add an `Authorize` attribute just after the `@page` directive and the following namespace imports (`@using` lines), as shown below:
````html ````html
@page "/books" @page "/books"
@ -479,7 +479,7 @@ You can run and test the permissions. Remove a book related permission from the
Even we have secured all the layers of the book management page, it is still visible on the main menu of the application. We should hide the menu item if the current user has no permission. Even we have secured all the layers of the book management page, it is still visible on the main menu of the application. We should hide the menu item if the current user has no permission.
Open the `BookStoreMenuContributor` class in the `Acme.BookStore.Blazor.Client` project, find the code block below: Open the `BookStoreMenuContributor` class in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project, find the code block below:
````csharp ````csharp
context.Menu.AddItem( context.Menu.AddItem(

2
docs/en/tutorials/book-store/part-06.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp", "NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````

2
docs/en/tutorials/book-store/part-07.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````

2
docs/en/tutorials/book-store/part-08.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````

12
docs/en/tutorials/book-store/part-09.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````
@ -848,13 +848,13 @@ That's all! This is a fully working CRUD page, you can create, edit and delete a
{{end}} {{end}}
{{if UI == "Blazor" || UI == "BlazorServer"}} {{if UI == "Blazor" || UI == "BlazorServer" || UI == "BlazorWebApp"}}
## The Author Management Page ## The Author Management Page
### Authors Razor Component ### Authors Razor Component
Create a new Razor Component Page, `/Pages/Authors.razor`, in the `Acme.BookStore.Blazor.Client` project with the following content: Create a new Razor Component Page, `/Pages/Authors.razor`, in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project with the following content:
````xml ````xml
@page "/authors" @page "/authors"
@ -1055,7 +1055,7 @@ using Blazorise.DataGrid;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Blazor.Client.Pages; {{ if UI == "BlazorServer" }}namespace Acme.BookStore.Blazor.Pages;{{ else }}namespace Acme.BookStore.Blazor.Client.Pages;{{ end }}
public partial class Authors public partial class Authors
{ {
@ -1201,7 +1201,7 @@ This class typically defines the properties and methods used by the `Authors.raz
`Authors` class uses the `IObjectMapper` in the `OpenEditAuthorModal` method. So, we need to define this mapping. `Authors` class uses the `IObjectMapper` in the `OpenEditAuthorModal` method. So, we need to define this mapping.
Open the `BookStoreBlazorAutoMapperProfile.cs` in the `Acme.BookStore.Blazor.Client` project and add the following mapping code in the constructor: Open the `BookStoreBlazorAutoMapperProfile.cs` in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add the following mapping code in the constructor:
````csharp ````csharp
CreateMap<AuthorDto, UpdateAuthorDto>(); CreateMap<AuthorDto, UpdateAuthorDto>();
@ -1211,7 +1211,7 @@ You will need to declare a `using Acme.BookStore.Authors;` statement to the begi
### Add to the Main Menu ### Add to the Main Menu
Open the `BookStoreMenuContributor.cs` in the `Acme.BookStore.Blazor.Client` project and add the following code to the end of the `ConfigureMainMenuAsync` method: Open the `BookStoreMenuContributor.cs` in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add the following code to the end of the `ConfigureMainMenuAsync` method:
````csharp ````csharp
if (await context.IsGrantedAsync(BookStorePermissions.Authors.Default)) if (await context.IsGrantedAsync(BookStorePermissions.Authors.Default))

6
docs/en/tutorials/book-store/part-10.md

@ -2,7 +2,7 @@
````json ````json
//[doc-params] //[doc-params]
{ {
"UI": ["MVC","Blazor","BlazorServer","NG"], "UI": ["MVC","Blazor","BlazorServer","BlazorWebApp","NG"],
"DB": ["EF","Mongo"] "DB": ["EF","Mongo"]
} }
```` ````
@ -1071,11 +1071,11 @@ That's all. Just run the application and try to create or edit an author.
{{end}} {{end}}
{{if UI == "Blazor" || UI == "BlazorServer"}} {{if UI == "Blazor" || UI == "BlazorServer" || UI == "BlazorWebApp" }}
### The Book List ### The Book List
It is very easy to show the *Author Name* in the book list. Open the `/Pages/Books.razor` file in the `Acme.BookStore.Blazor.Client` project and add the following `DataGridColumn` definition just after the `Name` (book name) column: It is very easy to show the *Author Name* in the book list. Open the `/Pages/Books.razor` file in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add the following `DataGridColumn` definition just after the `Name` (book name) column:
````xml ````xml
<DataGridColumn TItem="BookDto" <DataGridColumn TItem="BookDto"

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs

@ -11,4 +11,6 @@ public class BlogDto : ExtensibleEntityDto<Guid>, IHasConcurrencyStamp
public string Slug { get; set; } public string Slug { get; set; }
public string ConcurrencyStamp { get; set; } public string ConcurrencyStamp { get; set; }
public int BlogPostCount { get; set; }
} }

5
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs

@ -1,8 +1,13 @@
using System; using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
public interface IBlogAdminAppService : ICrudAppService<BlogDto, Guid, BlogGetListInput, CreateBlogDto, UpdateBlogDto> public interface IBlogAdminAppService : ICrudAppService<BlogDto, Guid, BlogGetListInput, CreateBlogDto, UpdateBlogDto>
{ {
Task<ListResultDto<BlogDto>> GetAllListAsync();
Task MoveAllBlogPostsAsync(Guid blogId, Guid? assignToBlogId = null);
} }

44
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
@ -20,16 +21,19 @@ namespace Volo.CmsKit.Admin.Blogs;
public class BlogAdminAppService : CmsKitAdminAppServiceBase, IBlogAdminAppService public class BlogAdminAppService : CmsKitAdminAppServiceBase, IBlogAdminAppService
{ {
protected IBlogRepository BlogRepository { get; } protected IBlogRepository BlogRepository { get; }
protected IBlogPostRepository BlogPostRepository { get; }
protected BlogManager BlogManager { get; } protected BlogManager BlogManager { get; }
protected BlogFeatureManager BlogFeatureManager { get; } protected BlogFeatureManager BlogFeatureManager { get; }
public BlogAdminAppService( public BlogAdminAppService(
IBlogRepository blogRepository, IBlogRepository blogRepository,
BlogManager blogManager, BlogManager blogManager,
IBlogPostRepository blogPostRepository,
BlogFeatureManager blogFeatureManager = null) BlogFeatureManager blogFeatureManager = null)
{ {
BlogRepository = blogRepository; BlogRepository = blogRepository;
BlogManager = blogManager; BlogManager = blogManager;
BlogPostRepository = blogPostRepository;
BlogFeatureManager = blogFeatureManager; BlogFeatureManager = blogFeatureManager;
} }
@ -37,20 +41,44 @@ public class BlogAdminAppService : CmsKitAdminAppServiceBase, IBlogAdminAppServi
{ {
var blog = await BlogRepository.GetAsync(id); var blog = await BlogRepository.GetAsync(id);
return ObjectMapper.Map<Blog, BlogDto>(blog); var blogDto = ObjectMapper.Map<Blog, BlogDto>(blog);
blogDto.BlogPostCount = await BlogPostRepository.GetCountAsync(blogId : blog.Id);
return blogDto;
} }
public virtual async Task<PagedResultDto<BlogDto>> GetListAsync(BlogGetListInput input) public virtual async Task<PagedResultDto<BlogDto>> GetListAsync(BlogGetListInput input)
{ {
var totalCount = await BlogRepository.GetCountAsync(input.Filter); var totalCount = await BlogRepository.GetCountAsync(input.Filter);
var blogs = await BlogRepository.GetListAsync( var blogs = await BlogRepository.GetListWithBlogPostCountAsync(
input.Filter, input.Filter,
input.Sorting, input.Sorting,
input.MaxResultCount, input.MaxResultCount,
input.SkipCount); input.SkipCount);
var blogDtos = new PagedResultDto<BlogDto>(totalCount, ObjectMapper.Map<List<Blog>, List<BlogDto>>(blogs.Select(x => x.Blog).ToList()));
foreach (var blogDto in blogDtos.Items)
{
blogDto.BlogPostCount = blogs.First(x => x.Blog.Id == blogDto.Id).BlogPostCount;
}
return new PagedResultDto<BlogDto>(totalCount, ObjectMapper.Map<List<Blog>, List<BlogDto>>(blogs)); return blogDtos;
}
public virtual async Task<ListResultDto<BlogDto>> GetAllListAsync()
{
var blogs = await BlogRepository.GetListWithBlogPostCountAsync(maxResultCount: int.MaxValue);
var blogDtos = new ListResultDto<BlogDto>(ObjectMapper.Map<List<Blog>, List<BlogDto>>(blogs.Select(x => x.Blog).ToList()));
foreach (var blogDto in blogDtos.Items)
{
blogDto.BlogPostCount = blogs.First(x => x.Blog.Id == blogDto.Id).BlogPostCount;
}
return blogDtos;
} }
[Authorize(CmsKitAdminPermissions.Blogs.Create)] [Authorize(CmsKitAdminPermissions.Blogs.Create)]
@ -79,10 +107,18 @@ public class BlogAdminAppService : CmsKitAdminAppServiceBase, IBlogAdminAppServi
return ObjectMapper.Map<Blog, BlogDto>(blog); return ObjectMapper.Map<Blog, BlogDto>(blog);
} }
[Authorize(CmsKitAdminPermissions.Blogs.Delete)]
public virtual async Task MoveAllBlogPostsAsync(Guid blogId, Guid? assignToBlogId)
{
var blog = await BlogRepository.GetAsync(blogId);
await BlogPostRepository.UpdateBlogAsync(blog.Id, assignToBlogId);
}
[Authorize(CmsKitAdminPermissions.Blogs.Delete)] [Authorize(CmsKitAdminPermissions.Blogs.Delete)]
public virtual Task DeleteAsync(Guid id) public virtual Task DeleteAsync(Guid id)
{ {
return BlogRepository.DeleteAsync(id); return BlogRepository.DeleteAsync(id);
} }
} }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs

@ -38,7 +38,7 @@ public class CmsKitAdminApplicationAutoMapperProfile : Profile
CreateMap<CreateBlogPostDto, BlogPost>(MemberList.Source).MapExtraProperties(); CreateMap<CreateBlogPostDto, BlogPost>(MemberList.Source).MapExtraProperties();
CreateMap<UpdateBlogPostDto, BlogPost>(MemberList.Source).MapExtraProperties(); CreateMap<UpdateBlogPostDto, BlogPost>(MemberList.Source).MapExtraProperties();
CreateMap<Blog, BlogDto>().MapExtraProperties(); CreateMap<Blog, BlogDto>().Ignore(b => b.BlogPostCount).MapExtraProperties();
CreateMap<TagEntityTypeDefiniton, TagDefinitionDto>(MemberList.Destination); CreateMap<TagEntityTypeDefiniton, TagDefinitionDto>(MemberList.Destination);

14
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Blogs/BlogAdminClientProxy.Generated.cs

@ -57,4 +57,18 @@ public partial class BlogAdminClientProxy : ClientProxyBase<IBlogAdminAppService
{ typeof(Guid), id } { typeof(Guid), id }
}); });
} }
public virtual async Task<ListResultDto<BlogDto>> GetAllListAsync()
{
return await RequestAsync<ListResultDto<BlogDto>>(nameof(GetAllListAsync));
}
public virtual async Task MoveAllBlogPostsAsync(Guid blogId, Guid? assignToBlogId)
{
await RequestAsync(nameof(MoveAllBlogPostsAsync), new ClientProxyRequestTypeValue
{
{ typeof(Guid), blogId },
{ typeof(Guid?), assignToBlogId }
});
}
} }

117
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json

@ -16,6 +16,39 @@
"type": "Volo.CmsKit.Admin.Blogs.IBlogAdminAppService", "type": "Volo.CmsKit.Admin.Blogs.IBlogAdminAppService",
"name": "IBlogAdminAppService", "name": "IBlogAdminAppService",
"methods": [ "methods": [
{
"name": "GetAllListAsync",
"parametersOnMethod": [],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Blogs.BlogDto>",
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Blogs.BlogDto>"
}
},
{
"name": "MoveAllBlogPostsAsync",
"parametersOnMethod": [
{
"name": "blogId",
"typeAsString": "System.Guid, System.Private.CoreLib",
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null
},
{
"name": "assignToBlogId",
"typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib",
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
}
},
{ {
"name": "GetAsync", "name": "GetAsync",
"parametersOnMethod": [ "parametersOnMethod": [
@ -353,6 +386,90 @@
}, },
"allowAnonymous": false, "allowAnonymous": false,
"implementFrom": "Volo.Abp.Application.Services.IDeleteAppService<System.Guid>" "implementFrom": "Volo.Abp.Application.Services.IDeleteAppService<System.Guid>"
},
"GetAllListAsync": {
"uniqueName": "GetAllListAsync",
"name": "GetAllListAsync",
"httpMethod": "GET",
"url": "api/cms-kit-admin/blogs/all",
"supportedVersions": [],
"parametersOnMethod": [],
"parameters": [],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Blogs.BlogDto>",
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Blogs.BlogDto>"
},
"allowAnonymous": false,
"implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogAdminAppService"
},
"MoveAllBlogPostsAsyncByBlogIdAndAssignToBlogId": {
"uniqueName": "MoveAllBlogPostsAsyncByBlogIdAndAssignToBlogId",
"name": "MoveAllBlogPostsAsync",
"httpMethod": "PUT",
"url": "api/cms-kit-admin/blogs/{id}/move-all-blog-posts",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "blogId",
"typeAsString": "System.Guid, System.Private.CoreLib",
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null
},
{
"name": "assignToBlogId",
"typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib",
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "blogId",
"name": "blogId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": ""
},
{
"nameOnMethod": "assignToBlogId",
"name": "assignToBlogId",
"jsonName": null,
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "Query",
"descriptorName": ""
},
{
"nameOnMethod": "id",
"name": "id",
"jsonName": null,
"type": null,
"typeSimple": null,
"isOptional": false,
"defaultValue": null,
"constraintTypes": [],
"bindingSourceId": "Path",
"descriptorName": ""
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": false,
"implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogAdminAppService"
} }
} }
}, },

15
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs

@ -62,4 +62,19 @@ public class BlogAdminController : CmsKitAdminController, IBlogAdminAppService
{ {
return BlogAdminAppService.DeleteAsync(id); return BlogAdminAppService.DeleteAsync(id);
} }
[HttpGet]
[Route("all")]
public Task<ListResultDto<BlogDto>> GetAllListAsync()
{
return BlogAdminAppService.GetAllListAsync();
}
[HttpPut]
[Route("{id}/move-all-blog-posts")]
[Authorize(CmsKitAdminPermissions.Blogs.Delete)]
public Task MoveAllBlogPostsAsync(Guid blogId, [FromQuery]Guid? assignToBlogId)
{
return BlogAdminAppService.MoveAllBlogPostsAsync(blogId, assignToBlogId);
}
} }

59
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/DeleteBlogModal.cshtml

@ -0,0 +1,59 @@
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs
@using Volo.CmsKit.Localization
@model DeleteBlogModal
@inject IHtmlLocalizer<CmsKitResource> L
@{
Layout = null;
}
<form method="post" asp-page="/CmsKit/Blogs/DeleteBlogModal" autocomplete="off">
@{
var deleteAllClicked = "checked";
var deleteButtonDisabled = "";
<abp-modal>
<abp-modal-header title="@L["AreYouSure"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="Blog.Id" type="hidden"></abp-input>
<p class="fw-bold">@L.GetString("BlogDeletionConfirmationMessage", Model.Blog.Name).Value</p>
@if (Model.Blog.BlogPostCount > 0)
{
<p class="mt-2">@L.GetString("ChooseAnActionForBlog", Model.Blog.BlogPostCount).Value</p>
if (Model.Blog.OtherBlogs.Any())
{
deleteAllClicked = "";
deleteButtonDisabled = "disabled";
<div class="form-check">
<input class="form-check-input" type="radio" checked name="assign" id="assign">
<label class="form-check-label" for="assign">@L["AssignBlogPostsToOtherBlog"].Value</label>
</div>
<select name="Blog.AssignToBlogId" id="Blog_AssignToBlogId" class="form-select mt-2">
<option value="" selected>@L["SelectAnBlogToAssign"].Value</option>
@foreach (var blog in Model.Blog.OtherBlogs)
{
<option value="@blog.Key">@blog.Value</option>
}
</select>
}
<div class="form-check mt-2">
<input class="form-check-input" type="radio" @deleteAllClicked name="assign" id="deleteAll">
<label class="form-check-label" for="deleteAll">@L["DeleteAllBlogPostsOfThisBlog"].Value</label>
</div>
}
</abp-modal-body>
<abp-modal-footer>
<button class="btn btn-outline-danger" data-bs-dismiss="modal" type="button">@L["Cancel"]</button>
<button class="btn btn-danger" @deleteButtonDisabled type="submit"><i class="fa fa-trash"></i> <span>@L["Delete"]</span></button>
</abp-modal-footer>
</abp-modal>
}
</form>

57
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/DeleteBlogModal.cshtml.cs

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Admin.Blogs;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs;
public class DeleteBlogModal : CmsKitAdminPageModel
{
[BindProperty]
public BlogInfoModel Blog { get; set; }
protected IBlogAdminAppService BlogAdminAppService { get; }
public DeleteBlogModal(IBlogAdminAppService blogAdminAppService)
{
BlogAdminAppService = blogAdminAppService;
}
public virtual async Task OnGetAsync(Guid id)
{
var blog = await BlogAdminAppService.GetAsync(id);
var allBlogs = await BlogAdminAppService.GetAllListAsync();
Blog = new BlogInfoModel
{
Id = blog.Id,
Name = blog.Name,
BlogPostCount = blog.BlogPostCount,
OtherBlogs = allBlogs.Items.Where(b => b.Id != blog.Id).Select(e => new KeyValuePair<Guid, string>(e.Id, e.Name)).ToList()
};
}
public virtual async Task<IActionResult> OnPostAsync()
{
await BlogAdminAppService.MoveAllBlogPostsAsync(Blog.Id, Blog.AssignToBlogId);
await BlogAdminAppService.DeleteAsync(Blog.Id);
return NoContent();
}
public class BlogInfoModel : ExtensibleObject
{
public Guid Id { get; set; }
public string Name { get; set; }
public int BlogPostCount { get; set; }
public List<KeyValuePair<Guid, string>> OtherBlogs { get; set; }
public Guid? AssignToBlogId { get; set; }
}
}

46
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/index.js

@ -6,6 +6,35 @@ $(function () {
var updateModal = new abp.ModalManager({ viewUrl: abp.appPath + "CmsKit/Blogs/UpdateModal", modalClass: 'updateBlog' }); var updateModal = new abp.ModalManager({ viewUrl: abp.appPath + "CmsKit/Blogs/UpdateModal", modalClass: 'updateBlog' });
var featuresModal = new abp.ModalManager(abp.appPath + "CmsKit/Blogs/FeaturesModal"); var featuresModal = new abp.ModalManager(abp.appPath + "CmsKit/Blogs/FeaturesModal");
var deleteBlogModal = new abp.ModalManager(abp.appPath + 'CmsKit/Blogs/DeleteBlogModal');
deleteBlogModal.onResult(function(){
abp.notify.success(l('DeletedSuccessfully'));
});
deleteBlogModal.onOpen(function () {
var $form = deleteBlogModal.getForm();
$form.find('#assign').click(function () {
$form.find('#Blog_AssignToBlogId').show();
$form.find('[type=submit]').attr("disabled","disabled")
})
$form.find('#deleteAll').click(function () {
$form.find('#Blog_AssignToBlogId').hide();
$form.find('#Blog_AssignToBlogId').val("");
$form.find('[type=submit]').removeAttr("disabled");
})
$("#Blog_AssignToBlogId").on("change", function () {
var val = $(this).val();
if(val === ''){
$form.find('[type=submit]').attr("disabled","disabled")
}else{
$form.find('[type=submit]').removeAttr("disabled");
}
})
})
var blogsService = volo.cmsKit.admin.blogs.blogAdmin; var blogsService = volo.cmsKit.admin.blogs.blogAdmin;
var dataTable = $("#BlogsTable").DataTable(abp.libs.datatables.normalizeConfiguration({ var dataTable = $("#BlogsTable").DataTable(abp.libs.datatables.normalizeConfiguration({
@ -41,16 +70,10 @@ $(function () {
{ {
text: l('Delete'), text: l('Delete'),
visible: abp.auth.isGranted('CmsKit.Blogs.Delete'), visible: abp.auth.isGranted('CmsKit.Blogs.Delete'),
confirmMessage: function (data) {
return l("BlogDeletionConfirmationMessage", data.record.name)
},
action: function (data) { action: function (data) {
blogsService deleteBlogModal.open({
.delete(data.record.id) id: data.record.id
.then(function () { });
dataTable.ajax.reloadEx();
abp.notify.success(l('DeletedSuccessfully'));
});
} }
} }
] ]
@ -74,6 +97,7 @@ $(function () {
createModal.open(); createModal.open();
}); });
createModal.onResult(function () { createModal.onResult(function () {
dataTable.ajax.reloadEx(); dataTable.ajax.reloadEx();
}); });
@ -81,4 +105,8 @@ $(function () {
updateModal.onResult(function () { updateModal.onResult(function () {
dataTable.ajax.reloadEx(); dataTable.ajax.reloadEx();
}); });
deleteBlogModal.onResult(function () {
dataTable.ajax.reloadEx();
});
}); });

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ar.json

@ -237,6 +237,10 @@
"CssClass": "فئة CSS", "CssClass": "فئة CSS",
"TagsHelpText": "يجب أن تكون العلامات مفصولة بفواصل (على سبيل المثال: tag1، tag2، tag3)", "TagsHelpText": "يجب أن تكون العلامات مفصولة بفواصل (على سبيل المثال: tag1، tag2، tag3)",
"ThisPartOfContentCouldntBeLoaded": "لا يمكن تحميل هذا الجزء من المحتوى.", "ThisPartOfContentCouldntBeLoaded": "لا يمكن تحميل هذا الجزء من المحتوى.",
"DuplicateCommentAttemptMessage": "تم اكتشاف محاولة نشر تعليق مكررة. لقد تم بالفعل تقديم تعليقك." "DuplicateCommentAttemptMessage": "تم اكتشاف محاولة نشر تعليق مكررة. لقد تم بالفعل تقديم تعليقك.",
"ChooseAnActionForBlog": "اختر إجراءً للمدونة",
"AssignBlogPostsToOtherBlog": "تعيين مشاركات المدونة إلى مدونة أخرى",
"SelectAnBlogToAssign": "حدد مدونة لتعيين مشاركات المدونة إليها",
"DeleteAllBlogPostsOfThisBlog": "حذف جميع مشاركات المدونة"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/cs.json

@ -227,6 +227,10 @@
"CssClass": "Třída CSS", "CssClass": "Třída CSS",
"TagsHelpText": "Značky by měly být odděleny čárkami (např.: tag1, tag2, tag3)", "TagsHelpText": "Značky by měly být odděleny čárkami (např.: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Tato část obsahu nemohla být načtena.", "ThisPartOfContentCouldntBeLoaded": "Tato část obsahu nemohla být načtena.",
"DuplicateCommentAttemptMessage": "Byl zjištěn duplicitní pokus o vložení komentáře. Váš komentář již byl odeslán." "DuplicateCommentAttemptMessage": "Byl zjištěn duplicitní pokus o vložení komentáře. Váš komentář již byl odeslán.",
"ChooseAnActionForBlog": "Vyberte akci pro blog",
"AssignBlogPostsToOtherBlog": "Přiřaďte blogové příspěvky k jinému blogu",
"SelectAnBlogToAssign": "Vyberte blog, ke kterému chcete přiřadit blogové příspěvky",
"DeleteAllBlogPostsOfThisBlog": "Smazat všechny blogové příspěvky tohoto blogu"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/de-DE.json

@ -161,6 +161,10 @@
"YourFullName": "Ihren vollständigen Namen", "YourFullName": "Ihren vollständigen Namen",
"YourMessage": "Ihre Nachricht", "YourMessage": "Ihre Nachricht",
"YourReply": "Ihre Antwort", "YourReply": "Ihre Antwort",
"ThisPartOfContentCouldntBeLoaded": "Dieser Teil des Inhalts konnte nicht geladen werden." "ThisPartOfContentCouldntBeLoaded": "Dieser Teil des Inhalts konnte nicht geladen werden.",
"ChooseAnActionForBlog": "Wählen Sie eine Aktion für den Blog",
"AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen",
"SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen",
"DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/de.json

@ -227,6 +227,10 @@
"CssClass": "CSS-Klasse", "CssClass": "CSS-Klasse",
"TagsHelpText": "Tags sollten durch Kommas getrennt werden (z. B. Tag1, Tag2, Tag3).", "TagsHelpText": "Tags sollten durch Kommas getrennt werden (z. B. Tag1, Tag2, Tag3).",
"ThisPartOfContentCouldntBeLoaded": "Dieser Teil des Inhalts konnte nicht geladen werden.", "ThisPartOfContentCouldntBeLoaded": "Dieser Teil des Inhalts konnte nicht geladen werden.",
"DuplicateCommentAttemptMessage": "Es wurde versucht, einen doppelten Kommentar zu posten. Ihr Kommentar wurde bereits übermittelt." "DuplicateCommentAttemptMessage": "Es wurde versucht, einen doppelten Kommentar zu posten. Ihr Kommentar wurde bereits übermittelt.",
"ChooseAnActionForBlog": "Wählen Sie eine Aktion für den Blog",
"AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen",
"SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen",
"DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/el.json

@ -184,6 +184,10 @@
"SelectAStatus": "Επιλέξτε μια κατάσταση", "SelectAStatus": "Επιλέξτε μια κατάσταση",
"Status": "Κατάσταση", "Status": "Κατάσταση",
"CmsKit.BlogPost.ScrollIndex": "Γραμμή γρήγορης πλοήγησης σε αναρτήσεις ιστολογίου", "CmsKit.BlogPost.ScrollIndex": "Γραμμή γρήγορης πλοήγησης σε αναρτήσεις ιστολογίου",
"ThisPartOfContentCouldntBeLoaded": "Αυτό το τμήμα του περιεχομένου δεν μπορούσε να φορτωθεί." "ThisPartOfContentCouldntBeLoaded": "Αυτό το τμήμα του περιεχομένου δεν μπορούσε να φορτωθεί.",
"ChooseAnActionForBlog": "Επιλέξτε μια ενέργεια για το ιστολόγιο",
"AssignBlogPostsToOtherBlog": "Ανάθεση αναρτήσεων ιστολογίου σε άλλο ιστολόγιο",
"SelectAnBlogToAssign": "Επιλέξτε ένα ιστολόγιο για να αναθέσετε αναρτήσεις ιστολογίου",
"DeleteAllBlogPostsOfThisBlog": "Διαγραφή όλων των αναρτήσεων ιστολογίου αυτού του ιστολογίου"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en-GB.json

@ -28,6 +28,10 @@
"Undo": "Undo", "Undo": "Undo",
"Update": "Update", "Update": "Update",
"YourComment": "Your comment", "YourComment": "Your comment",
"YourReply": "Your reply" "YourReply": "Your reply",
"ChooseAnActionForBlog": "Choose an action for the blog",
"AssignBlogPostsToOtherBlog": "Assign blog posts to another blog",
"SelectAnBlogToAssign": "Select a blog to assign",
"DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json

@ -255,6 +255,10 @@
"CommentAlertMessage": "There are {0} comments waiting for approval", "CommentAlertMessage": "There are {0} comments waiting for approval",
"Settings:Menu:CmsKit": "CMS", "Settings:Menu:CmsKit": "CMS",
"CommentsAwaitingApproval": "Comments Awaiting Approval", "CommentsAwaitingApproval": "Comments Awaiting Approval",
"CommentSubmittedForApproval": "Your comment has been submitted for approval." "CommentSubmittedForApproval": "Your comment has been submitted for approval.",
"ChooseAnActionForBlog": "Choose an action for the blog",
"AssignBlogPostsToOtherBlog": "Assign blog posts to another blog",
"SelectAnBlogToAssign": "Select a blog to assign",
"DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/es.json

@ -227,6 +227,10 @@
"CssClass": "Clase CSS", "CssClass": "Clase CSS",
"TagsHelpText": "Las etiquetas deben estar separadas por comas (por ejemplo: etiqueta1, etiqueta2, etiqueta3)", "TagsHelpText": "Las etiquetas deben estar separadas por comas (por ejemplo: etiqueta1, etiqueta2, etiqueta3)",
"ThisPartOfContentCouldntBeLoaded": "Esta parte del contenido no se pudo cargar.", "ThisPartOfContentCouldntBeLoaded": "Esta parte del contenido no se pudo cargar.",
"DuplicateCommentAttemptMessage": "Intento de publicación de comentario duplicado detectado. Tu comentario ya ha sido enviado." "DuplicateCommentAttemptMessage": "Intento de publicación de comentario duplicado detectado. Tu comentario ya ha sido enviado.",
"ChooseAnActionForBlog": "Elija una acción para el blog",
"AssignBlogPostsToOtherBlog": "Asignar publicaciones de blog a otro blog",
"SelectAnBlogToAssign": "Seleccione un blog para asignar publicaciones de blog",
"DeleteAllBlogPostsOfThisBlog": "Eliminar todas las publicaciones de blog de este blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fa.json

@ -183,6 +183,10 @@
"Status": "وضعیت", "Status": "وضعیت",
"CmsKit.BlogPost.ScrollIndex": "نوار پیمایش سریع در پست های وبلاگ", "CmsKit.BlogPost.ScrollIndex": "نوار پیمایش سریع در پست های وبلاگ",
"CmsKit.BlogPost.PreventXssFeature": "جلوگیری از XSS", "CmsKit.BlogPost.PreventXssFeature": "جلوگیری از XSS",
"ThisPartOfContentCouldntBeLoaded": "این قسمت از محتوا قابل بارگیری نیست." "ThisPartOfContentCouldntBeLoaded": "این قسمت از محتوا قابل بارگیری نیست.",
"ChooseAnActionForBlog": "یک عمل برای وبلاگ انتخاب کنید",
"AssignBlogPostsToOtherBlog": "پست های وبلاگ را به وبلاگ دیگری اختصاص دهید",
"SelectAnBlogToAssign": "یک وبلاگ برای اختصاص دادن انتخاب کنید",
"DeleteAllBlogPostsOfThisBlog": "تمام پست های وبلاگ این وبلاگ را حذف کنید"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fi.json

@ -227,6 +227,10 @@
"CssClass": "CSS-luokka", "CssClass": "CSS-luokka",
"TagsHelpText": "Tunnisteet on erotettava pilkuilla (esim. tag1, tag2, tag3)", "TagsHelpText": "Tunnisteet on erotettava pilkuilla (esim. tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Tämä sisällön osa ei voitu ladata.", "ThisPartOfContentCouldntBeLoaded": "Tämä sisällön osa ei voitu ladata.",
"DuplicateCommentAttemptMessage": "Kopiokommenttiyritys havaittiin. Kommenttisi on jo lähetetty." "DuplicateCommentAttemptMessage": "Kopiokommenttiyritys havaittiin. Kommenttisi on jo lähetetty.",
"ChooseAnActionForBlog": "Valitse toiminto blogille",
"AssignBlogPostsToOtherBlog": "Määritä blogiviestit toiseen blogiin",
"SelectAnBlogToAssign": "Valitse blogi, johon haluat määrittää",
"DeleteAllBlogPostsOfThisBlog": "Poista tämän blogin kaikki blogiviestit"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json

@ -227,6 +227,10 @@
"CssClass": "Classe CSS", "CssClass": "Classe CSS",
"TagsHelpText": "Les balises doivent être séparées par des virgules (par exemple : tag1, tag2, tag3)", "TagsHelpText": "Les balises doivent être séparées par des virgules (par exemple : tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Cette partie du contenu n'a pas pu être chargée.", "ThisPartOfContentCouldntBeLoaded": "Cette partie du contenu n'a pas pu être chargée.",
"DuplicateCommentAttemptMessage": "Tentative de publication de commentaire en double détectée. Votre commentaire a déjà été soumis." "DuplicateCommentAttemptMessage": "Tentative de publication de commentaire en double détectée. Votre commentaire a déjà été soumis.",
"ChooseAnActionForBlog": "Choisissez une action pour le blog",
"AssignBlogPostsToOtherBlog": "Attribuer des articles de blog à un autre blog",
"SelectAnBlogToAssign": "Sélectionnez un blog à attribuer",
"DeleteAllBlogPostsOfThisBlog": "Supprimer tous les articles de blog de ce blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hi.json

@ -227,6 +227,10 @@
"CssClass": "सीएसएस क्लास", "CssClass": "सीएसएस क्लास",
"TagsHelpText": "टैग को अल्पविराम से अलग किया जाना चाहिए (जैसे: टैग1, टैग2, टैग3)", "TagsHelpText": "टैग को अल्पविराम से अलग किया जाना चाहिए (जैसे: टैग1, टैग2, टैग3)",
"ThisPartOfContentCouldntBeLoaded": "यह भाग लोड नहीं किया जा सका।", "ThisPartOfContentCouldntBeLoaded": "यह भाग लोड नहीं किया जा सका।",
"DuplicateCommentAttemptMessage": "डुप्लिकेट टिप्पणी पोस्ट प्रयास का पता चला। आपकी टिप्पणी पहले ही सबमिट की जा चुकी है." "DuplicateCommentAttemptMessage": "डुप्लिकेट टिप्पणी पोस्ट प्रयास का पता चला। आपकी टिप्पणी पहले ही सबमिट की जा चुकी है.",
"ChooseAnActionForBlog": "ब्लॉग के लिए कोई कार्रवाई चुनें",
"AssignBlogPostsToOtherBlog": "अन्य ब्लॉग को ब्लॉग पोस्ट असाइन करें",
"SelectAnBlogToAssign": "असाइन करने के लिए एक ब्लॉग चुनें",
"DeleteAllBlogPostsOfThisBlog": "इस ब्लॉग के सभी ब्लॉग पोस्ट हटाएं"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hr.json

@ -227,6 +227,10 @@
"CssClass": "CSS klasa", "CssClass": "CSS klasa",
"TagsHelpText": "Oznake trebaju biti odvojene zarezom (npr. oznaka1, oznaka2, oznaka3)", "TagsHelpText": "Oznake trebaju biti odvojene zarezom (npr. oznaka1, oznaka2, oznaka3)",
"ThisPartOfContentCouldntBeLoaded": "Ovaj dio sadržaja nije bilo moguće učitati.", "ThisPartOfContentCouldntBeLoaded": "Ovaj dio sadržaja nije bilo moguće učitati.",
"DuplicateCommentAttemptMessage": "Otkriven pokušaj postavljanja duplikata komentara. Vaš komentar je već poslan." "DuplicateCommentAttemptMessage": "Otkriven pokušaj postavljanja duplikata komentara. Vaš komentar je već poslan.",
"ChooseAnActionForBlog": "Odaberite radnju za blog",
"AssignBlogPostsToOtherBlog": "Dodijelite postove na blogu drugom blogu",
"SelectAnBlogToAssign": "Odaberite blog za dodjelu",
"DeleteAllBlogPostsOfThisBlog": "Izbrišite sve postove na blogu"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hu.json

@ -227,6 +227,10 @@
"CssClass": "CSS osztály", "CssClass": "CSS osztály",
"TagsHelpText": "A címkéket vesszővel kell elválasztani (pl.: tag1, tag2, tag3)", "TagsHelpText": "A címkéket vesszővel kell elválasztani (pl.: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "A tartalom ezen része nem tölthető be.", "ThisPartOfContentCouldntBeLoaded": "A tartalom ezen része nem tölthető be.",
"DuplicateCommentAttemptMessage": "Ismétlődő megjegyzés közzétételi kísérlet észlelve. Megjegyzését már elküldtük." "DuplicateCommentAttemptMessage": "Ismétlődő megjegyzés közzétételi kísérlet észlelve. Megjegyzését már elküldtük.",
"ChooseAnActionForBlog": "Válasszon egy műveletet a bloghoz",
"AssignBlogPostsToOtherBlog": "Blogbejegyzések hozzárendelése egy másik bloghoz",
"SelectAnBlogToAssign": "Válasszon egy blogot a hozzárendeléshez",
"DeleteAllBlogPostsOfThisBlog": "Ez a művelet törli az összes blogbejegyzést ebből a blogból. Biztos vagy benne?"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/is.json

@ -227,6 +227,10 @@
"CssClass": "CSS flokkur", "CssClass": "CSS flokkur",
"TagsHelpText": "Merki ættu að vera aðskilin með kommum (td: tag1, tag2, tag3)", "TagsHelpText": "Merki ættu að vera aðskilin með kommum (td: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Þessi hluti af efni gat ekki verið hlaðið inn.", "ThisPartOfContentCouldntBeLoaded": "Þessi hluti af efni gat ekki verið hlaðið inn.",
"DuplicateCommentAttemptMessage": "Tvítekin tilraun til að skrifa athugasemd fannst. Athugasemd þín hefur þegar verið send." "DuplicateCommentAttemptMessage": "Tvítekin tilraun til að skrifa athugasemd fannst. Athugasemd þín hefur þegar verið send.",
"ChooseAnActionForBlog": "Veldu aðgerð fyrir blogg",
"AssignBlogPostsToOtherBlog": "Úthluta bloggfærslum til annars bloggs",
"SelectAnBlogToAssign": "Veldu blogg til að úthluta",
"DeleteAllBlogPostsOfThisBlog": "Eyða öllum bloggfærslum þessa bloggs"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/it.json

@ -227,6 +227,10 @@
"CssClass": "Classe CSS", "CssClass": "Classe CSS",
"TagsHelpText": "I tag devono essere separati da virgole (ad esempio: tag1, tag2, tag3)", "TagsHelpText": "I tag devono essere separati da virgole (ad esempio: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Questa parte del contenuto non può essere caricata.", "ThisPartOfContentCouldntBeLoaded": "Questa parte del contenuto non può essere caricata.",
"DuplicateCommentAttemptMessage": "Rilevato tentativo di pubblicare commenti duplicati. Il tuo commento è già stato inviato." "DuplicateCommentAttemptMessage": "Rilevato tentativo di pubblicare commenti duplicati. Il tuo commento è già stato inviato.",
"ChooseAnActionForBlog": "Scegli un'azione per il blog",
"AssignBlogPostsToOtherBlog": "Assegna i post del blog ad un altro blog",
"SelectAnBlogToAssign": "Seleziona un blog a cui assegnare i post del blog",
"DeleteAllBlogPostsOfThisBlog": "Elimina tutti i post del blog di questo blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/nl.json

@ -227,6 +227,10 @@
"CssClass": "CSS-klasse", "CssClass": "CSS-klasse",
"TagsHelpText": "Tags moeten door komma&#39;s worden gescheiden (bijvoorbeeld: tag1, tag2, tag3)", "TagsHelpText": "Tags moeten door komma&#39;s worden gescheiden (bijvoorbeeld: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Dit deel van de inhoud kon niet worden geladen.", "ThisPartOfContentCouldntBeLoaded": "Dit deel van de inhoud kon niet worden geladen.",
"DuplicateCommentAttemptMessage": "Dubbele poging tot posten van commentaar gedetecteerd. Uw reactie is al verzonden." "DuplicateCommentAttemptMessage": "Dubbele poging tot posten van commentaar gedetecteerd. Uw reactie is al verzonden.",
"ChooseAnActionForBlog": "Kies een actie voor de blog",
"AssignBlogPostsToOtherBlog": "Wijs blogberichten toe aan een andere blog",
"SelectAnBlogToAssign": "Selecteer een blog om toe te wijzen",
"DeleteAllBlogPostsOfThisBlog": "Verwijder alle blogberichten van deze blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/pl-PL.json

@ -227,6 +227,10 @@
"CssClass": "Klasa CSS", "CssClass": "Klasa CSS",
"TagsHelpText": "Tagi powinny być oddzielone przecinkami (np. tag1, tag2, tag3)", "TagsHelpText": "Tagi powinny być oddzielone przecinkami (np. tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Ta część zawartości nie mogła zostać załadowana.", "ThisPartOfContentCouldntBeLoaded": "Ta część zawartości nie mogła zostać załadowana.",
"DuplicateCommentAttemptMessage": "Wykryto zduplikowaną próbę opublikowania komentarza. Twój komentarz został już przesłany." "DuplicateCommentAttemptMessage": "Wykryto zduplikowaną próbę opublikowania komentarza. Twój komentarz został już przesłany.",
"ChooseAnActionForBlog": "Wybierz akcję dla bloga",
"AssignBlogPostsToOtherBlog": "Przypisz posty na blogu do innego bloga",
"SelectAnBlogToAssign": "Wybierz blog, do którego chcesz przypisać posty na blogu",
"DeleteAllBlogPostsOfThisBlog": "Usuń wszystkie posty na blogu tego bloga"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/pt-BR.json

@ -227,6 +227,10 @@
"CssClass": "Classe CSS", "CssClass": "Classe CSS",
"TagsHelpText": "As tags devem ser separadas por vírgula (por exemplo: tag1, tag2, tag3)", "TagsHelpText": "As tags devem ser separadas por vírgula (por exemplo: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Esta parte do conteúdo não pôde ser carregada.", "ThisPartOfContentCouldntBeLoaded": "Esta parte do conteúdo não pôde ser carregada.",
"DuplicateCommentAttemptMessage": "Tentativa duplicada de postagem de comentário detectada. Seu comentário já foi enviado." "DuplicateCommentAttemptMessage": "Tentativa duplicada de postagem de comentário detectada. Seu comentário já foi enviado.",
"ChooseAnActionForBlog": "Escolha uma ação para o blog",
"AssignBlogPostsToOtherBlog": "Atribuir postagens de blog a outro blog",
"SelectAnBlogToAssign": "Selecione um blog para atribuir",
"DeleteAllBlogPostsOfThisBlog": "Excluir todas as postagens de blog deste blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ro-RO.json

@ -227,6 +227,10 @@
"CssClass": "Clasa CSS", "CssClass": "Clasa CSS",
"TagsHelpText": "Etichetele ar trebui să fie separate prin virgulă (de exemplu: tag1, tag2, tag3)", "TagsHelpText": "Etichetele ar trebui să fie separate prin virgulă (de exemplu: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Această parte a conţinutului nu a putut fi încărcată.", "ThisPartOfContentCouldntBeLoaded": "Această parte a conţinutului nu a putut fi încărcată.",
"DuplicateCommentAttemptMessage": "A fost detectată o încercare de postare de comentarii duplicată. Comentariul dvs. a fost deja trimis." "DuplicateCommentAttemptMessage": "A fost detectată o încercare de postare de comentarii duplicată. Comentariul dvs. a fost deja trimis.",
"ChooseAnActionForBlog": "Alegeţi o acţiune pentru blog",
"AssignBlogPostsToOtherBlog": "Atribuiţi postările de blog la alt blog",
"SelectAnBlogToAssign": "Selectaţi un blog pentru a atribui postările de blog",
"DeleteAllBlogPostsOfThisBlog": "Ştergeţi toate postările de blog ale acestui blog"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ru.json

@ -227,6 +227,10 @@
"CssClass": "CSS-класс", "CssClass": "CSS-класс",
"TagsHelpText": "Теги должны быть разделены запятыми (например: тег1, тег2, тег3).", "TagsHelpText": "Теги должны быть разделены запятыми (например: тег1, тег2, тег3).",
"ThisPartOfContentCouldntBeLoaded": "Эта часть содержимого не может быть загружена.", "ThisPartOfContentCouldntBeLoaded": "Эта часть содержимого не может быть загружена.",
"DuplicateCommentAttemptMessage": "Обнаружена повторная попытка публикации комментария. Ваш комментарий уже отправлен." "DuplicateCommentAttemptMessage": "Обнаружена повторная попытка публикации комментария. Ваш комментарий уже отправлен.",
"ChooseAnActionForBlog": "Выберите действие для блога",
"AssignBlogPostsToOtherBlog": "Назначить сообщения в блоге другому блогу",
"SelectAnBlogToAssign": "Выберите блог для назначения",
"DeleteAllBlogPostsOfThisBlog": "Удалить все сообщения в блоге этого блога"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sk.json

@ -227,6 +227,10 @@
"CssClass": "CSS trieda", "CssClass": "CSS trieda",
"TagsHelpText": "Značky by mali byť oddelené čiarkou (napr.: tag1, tag2, tag3)", "TagsHelpText": "Značky by mali byť oddelené čiarkou (napr.: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Táto časť obsahu sa nedá načítať.", "ThisPartOfContentCouldntBeLoaded": "Táto časť obsahu sa nedá načítať.",
"DuplicateCommentAttemptMessage": "Zistil sa duplicitný pokus o uverejnenie komentára. Váš komentár už bol odoslaný." "DuplicateCommentAttemptMessage": "Zistil sa duplicitný pokus o uverejnenie komentára. Váš komentár už bol odoslaný.",
"ChooseAnActionForBlog": "Vyberte akciu pre blog",
"AssignBlogPostsToOtherBlog": "Priradiť blogové príspevky k inému blogu",
"SelectAnBlogToAssign": "Vyberte blog, na ktorý chcete priradiť blogové príspevky",
"DeleteAllBlogPostsOfThisBlog": "Zmazať všetky blogové príspevky tohto blogu"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sl.json

@ -227,6 +227,10 @@
"CssClass": "Razred CSS", "CssClass": "Razred CSS",
"TagsHelpText": "Oznake morajo biti ločene z vejicami (npr. oznaka1, oznaka2, oznaka3)", "TagsHelpText": "Oznake morajo biti ločene z vejicami (npr. oznaka1, oznaka2, oznaka3)",
"ThisPartOfContentCouldntBeLoaded": "Ta del vsebine ni bil naložen.", "ThisPartOfContentCouldntBeLoaded": "Ta del vsebine ni bil naložen.",
"DuplicateCommentAttemptMessage": "Zaznan poskus podvojene objave komentarja. Vaš komentar je že oddan." "DuplicateCommentAttemptMessage": "Zaznan poskus podvojene objave komentarja. Vaš komentar je že oddan.",
"ChooseAnActionForBlog": "Izberite dejanje za blog",
"AssignBlogPostsToOtherBlog": "Dodeli objave v blogu drugemu blogu",
"SelectAnBlogToAssign": "Izberite blog, ki mu želite dodeliti objave",
"DeleteAllBlogPostsOfThisBlog": "Izbriši vse objave v tem blogu"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sv.json

@ -254,6 +254,10 @@
"CommentAlertMessage": "Det finns {0} kommentarer som väntar på godkännande", "CommentAlertMessage": "Det finns {0} kommentarer som väntar på godkännande",
"Settings:Menu:CmsKit": "CMS", "Settings:Menu:CmsKit": "CMS",
"CommentsAwaitingApproval": "Kommentarer som väntar på godkännande", "CommentsAwaitingApproval": "Kommentarer som väntar på godkännande",
"CommentSubmittedForApproval": "Din kommentar har skickats in för godkännande." "CommentSubmittedForApproval": "Din kommentar har skickats in för godkännande.",
"ChooseAnActionForBlog": "Välj en åtgärd för bloggen",
"AssignBlogPostsToOtherBlog": "Tilldela blogginlägg till en annan blogg",
"SelectAnBlogToAssign": "Välj en blogg att tilldela",
"DeleteAllBlogPostsOfThisBlog": "Radera alla blogginlägg i denna blogg"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json

@ -218,6 +218,10 @@
"CaptchaCode": "Captcha kodu", "CaptchaCode": "Captcha kodu",
"CommentTextRequired": "Yorum zorunlu", "CommentTextRequired": "Yorum zorunlu",
"PopularTags": "Popüler Etiketler", "PopularTags": "Popüler Etiketler",
"ThisPartOfContentCouldntBeLoaded": "Bu içerik yüklenemedi" "ThisPartOfContentCouldntBeLoaded": "Bu içerik yüklenemedi",
"ChooseAnActionForBlog": "Blog için bir eylem seçin",
"AssignBlogPostsToOtherBlog": "Diğer bloglara blog yazıları atayın",
"SelectAnBlogToAssign": "Atanacak bir blog seçin",
"DeleteAllBlogPostsOfThisBlog": "Bu blogun tüm blog yazılarını sil"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/vi.json

@ -227,6 +227,10 @@
"CssClass": "Lớp CSS", "CssClass": "Lớp CSS",
"TagsHelpText": "Các thẻ phải được phân tách bằng dấu phẩy (ví dụ: tag1, tag2, tag3)", "TagsHelpText": "Các thẻ phải được phân tách bằng dấu phẩy (ví dụ: tag1, tag2, tag3)",
"ThisPartOfContentCouldntBeLoaded": "Phần này của nội dung không thể được tải.", "ThisPartOfContentCouldntBeLoaded": "Phần này của nội dung không thể được tải.",
"DuplicateCommentAttemptMessage": "Đã phát hiện nỗ lực đăng bình luận trùng lặp. Bình luận của bạn đã được gửi." "DuplicateCommentAttemptMessage": "Đã phát hiện nỗ lực đăng bình luận trùng lặp. Bình luận của bạn đã được gửi.",
"ChooseAnActionForBlog": "Chọn một hành động cho blog",
"AssignBlogPostsToOtherBlog": "Gán bài đăng trên blog cho blog khác",
"SelectAnBlogToAssign": "Chọn một blog để gán",
"DeleteAllBlogPostsOfThisBlog": "Xóa tất cả bài đăng trên blog của blog này"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json

@ -227,6 +227,10 @@
"CssClass": "CSS 类", "CssClass": "CSS 类",
"TagsHelpText": "标签应以逗号分隔(例如:标签 1,标签 2,标签 3)", "TagsHelpText": "标签应以逗号分隔(例如:标签 1,标签 2,标签 3)",
"ThisPartOfContentCouldntBeLoaded": "这部分内容无法加载。", "ThisPartOfContentCouldntBeLoaded": "这部分内容无法加载。",
"DuplicateCommentAttemptMessage": "检测到重复发表评论。您的评论已经提交。" "DuplicateCommentAttemptMessage": "检测到重复发表评论。您的评论已经提交。",
"ChooseAnActionForBlog": "选择博客的操作",
"AssignBlogPostsToOtherBlog": "将博客文章分配给其他博客",
"SelectAnBlogToAssign": "选择要分配的博客",
"DeleteAllBlogPostsOfThisBlog": "删除此博客的所有博客文章"
} }
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hant.json

@ -227,6 +227,10 @@
"CssClass": "CSS類", "CssClass": "CSS類",
"TagsHelpText": "標籤應以逗號分隔(例如:tag1、tag2、tag3)", "TagsHelpText": "標籤應以逗號分隔(例如:tag1、tag2、tag3)",
"ThisPartOfContentCouldntBeLoaded": "這部分內容無法加載", "ThisPartOfContentCouldntBeLoaded": "這部分內容無法加載",
"DuplicateCommentAttemptMessage": "偵測到重複的評論貼文嘗試。您的評論已經提交。" "DuplicateCommentAttemptMessage": "偵測到重複的評論貼文嘗試。您的評論已經提交。",
"ChooseAnActionForBlog": "選擇部落格的操作",
"AssignBlogPostsToOtherBlog": "將部落格文章分配給其他部落格",
"SelectAnBlogToAssign": "選擇要分配的部落格",
"DeleteAllBlogPostsOfThisBlog": "刪除此部落格的所有部落格文章"
} }
} }

7
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs

@ -53,7 +53,7 @@ public class BlogPost : FullAuditedAggregateRoot<Guid>, IMultiTenant, IHasEntity
) : base(id) ) : base(id)
{ {
TenantId = tenantId; TenantId = tenantId;
BlogId = blogId; SetBlogId(blogId);
AuthorId = authorId; AuthorId = authorId;
SetTitle(title); SetTitle(title);
SetSlug(slug); SetSlug(slug);
@ -68,6 +68,11 @@ public class BlogPost : FullAuditedAggregateRoot<Guid>, IMultiTenant, IHasEntity
Title = Check.NotNullOrWhiteSpace(title, nameof(title), BlogPostConsts.MaxTitleLength); Title = Check.NotNullOrWhiteSpace(title, nameof(title), BlogPostConsts.MaxTitleLength);
} }
public virtual void SetBlogId(Guid blogId)
{
BlogId = blogId;
}
internal void SetSlug(string slug) internal void SetSlug(string slug)
{ {
Check.NotNullOrWhiteSpace(slug, nameof(slug), BlogPostConsts.MaxSlugLength, BlogPostConsts.MinSlugLength); Check.NotNullOrWhiteSpace(slug, nameof(slug), BlogPostConsts.MaxSlugLength, BlogPostConsts.MinSlugLength);

14
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogWithBlogPostCount.cs

@ -0,0 +1,14 @@
namespace Volo.CmsKit.Blogs;
public class BlogWithBlogPostCount
{
public Blog Blog { get; set; }
public int BlogPostCount { get; set; }
public BlogWithBlogPostCount(Blog blog, int blogPostCount)
{
Blog = blog;
BlogPostCount = blogPostCount;
}
}

2
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs

@ -44,4 +44,6 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Task<CmsUser> GetAuthorHasBlogPostAsync(Guid id, CancellationToken cancellationToken = default); Task<CmsUser> GetAuthorHasBlogPostAsync(Guid id, CancellationToken cancellationToken = default);
Task<bool> HasBlogPostWaitingForReviewAsync(CancellationToken cancellationToken = default); Task<bool> HasBlogPostWaitingForReviewAsync(CancellationToken cancellationToken = default);
Task UpdateBlogAsync(Guid sourceBlogId, Guid? targetBlogId = null, CancellationToken cancellationToken = default);
} }

7
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs

@ -16,6 +16,13 @@ public interface IBlogRepository : IBasicRepository<Blog, Guid>
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
Task<List<BlogWithBlogPostCount>> GetListWithBlogPostCountAsync(
string filter = null,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync( Task<long> GetCountAsync(
string filter = null, string filter = null,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default

13
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs

@ -160,4 +160,17 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
return await (await GetDbSetAsync()) return await (await GetDbSetAsync())
.AnyAsync(x => x.Status == BlogPostStatus.WaitingForReview, GetCancellationToken(cancellationToken)); .AnyAsync(x => x.Status == BlogPostStatus.WaitingForReview, GetCancellationToken(cancellationToken));
} }
public async Task UpdateBlogAsync(Guid sourceBlogId, Guid? targetBlogId = null, CancellationToken cancellationToken = default)
{
if (targetBlogId != null)
{
await (await GetDbSetAsync()).Where(x => x.BlogId == sourceBlogId).ExecuteUpdateAsync(x => x.SetProperty(b => b.BlogId, targetBlogId.Value), GetCancellationToken(cancellationToken));
}
else
{
await (await GetDbSetAsync()).Where(x => x.BlogId == sourceBlogId).ExecuteDeleteAsync(GetCancellationToken(cancellationToken));
}
}
} }

25
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs

@ -43,6 +43,31 @@ public class EfCoreBlogRepository : EfCoreRepository<ICmsKitDbContext, Blog, Gui
.ToListAsync(GetCancellationToken(cancellationToken)); .ToListAsync(GetCancellationToken(cancellationToken));
} }
public virtual async Task<List<BlogWithBlogPostCount>> GetListWithBlogPostCountAsync(
string filter = null,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var blogs = await (await GetListQueryAsync(filter)).OrderBy(sorting.IsNullOrEmpty() ? "creationTime desc" : sorting)
.PageBy(skipCount, maxResultCount).ToListAsync(GetCancellationToken(cancellationToken));
var blogIds = blogs.Select(x => x.Id).ToArray();
var blogPostCount = await (await GetDbContextAsync()).Set<BlogPost>()
.Where(blogPost => blogIds.Contains(blogPost.BlogId))
.GroupBy(blogPost => blogPost.BlogId)
.Select(x => new
{
BlogId = x.Key,
Count = x.Count()
})
.ToListAsync(GetCancellationToken(cancellationToken));
return blogs.Select(blog => new BlogWithBlogPostCount(blog, blogPostCount.FirstOrDefault(x => x.BlogId == blog.Id)?.Count ?? 0)).ToList();
}
public virtual async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default) public virtual async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default)
{ {
var query = await GetListQueryAsync(filter); var query = await GetListQueryAsync(filter);

20
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs

@ -192,4 +192,24 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
return await (await GetMongoQueryableAsync(cancellationToken)) return await (await GetMongoQueryableAsync(cancellationToken))
.AnyAsync(x => x.Status == BlogPostStatus.WaitingForReview, cancellationToken); .AnyAsync(x => x.Status == BlogPostStatus.WaitingForReview, cancellationToken);
} }
public async Task UpdateBlogAsync(Guid sourceBlogId, Guid? targetBlogId, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
var blogPosts = await (await GetMongoQueryableAsync(cancellationToken)).Where(x => x.BlogId == sourceBlogId).ToListAsync(cancellationToken);
if (targetBlogId.HasValue)
{
foreach (var blogPost in blogPosts)
{
blogPost.SetBlogId(targetBlogId.Value);
}
await UpdateManyAsync(blogPosts, false, cancellationToken);
}
else
{
await DeleteManyAsync(blogPosts, false, cancellationToken);
}
}
} }

27
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs

@ -49,6 +49,33 @@ public class MongoBlogRepository : MongoDbRepository<ICmsKitMongoDbContext, Blog
.ToListAsync(token); .ToListAsync(token);
} }
public async Task<List<BlogWithBlogPostCount>> GetListWithBlogPostCountAsync(
string filter = null,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var token = GetCancellationToken(cancellationToken);
var blogs = await GetListQueryAsync(filter, token);
var blogIds = blogs.OrderBy(sorting.IsNullOrEmpty() ? "creationTime desc" : sorting)
.PageBy(skipCount, maxResultCount).Select(x => x.Id).ToList();
var blogPostCount = await (await GetMongoQueryableAsync<BlogPost>(token))
.Where(blogPost => blogIds.Contains(blogPost.Id))
.GroupBy(blogPost => blogPost.BlogId)
.Select(x => new
{
BlogId = x.Key,
Count = x.Count()
})
.ToListAsync(GetCancellationToken(cancellationToken));
return blogs.Select(blog => new BlogWithBlogPostCount(blog, blogPostCount.FirstOrDefault(x => x.BlogId == blog.Id) != null ? blogPostCount.FirstOrDefault(x => x.BlogId == blog.Id).Count : 0)).ToList();
}
public virtual async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default) public virtual async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default)
{ {
var token = GetCancellationToken(cancellationToken); var token = GetCancellationToken(cancellationToken);

Loading…
Cancel
Save