Browse Source

Merge branch 'dev' into salihozkara/license

pull/21787/head
SALİH ÖZKARA 2 years ago
parent
commit
9d0be9d618
  1. 5
      abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json
  2. 5
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  3. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuItemAdminAppService.cs
  4. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemCreateInput.cs
  5. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemUpdateInput.cs
  6. 8
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/PermissionLookupDto.cs
  7. 6
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/PermissionLookupInputDto.cs
  8. 10
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs
  9. 28
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs
  10. 8
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs
  11. 56
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json
  12. 7
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuItemAdminController.cs
  13. 5
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml
  14. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs
  15. 24
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml
  16. 7
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs
  17. 46
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/createModal.js
  18. 47
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/updateModal.js
  19. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs
  20. 7
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ar.json
  21. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/cs.json
  22. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/de-DE.json
  23. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/de.json
  24. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/el.json
  25. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en-GB.json
  26. 7
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json
  27. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/es.json
  28. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fa.json
  29. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fi.json
  30. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/fr.json
  31. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hi.json
  32. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hr.json
  33. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/hu.json
  34. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/is.json
  35. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/it.json
  36. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/nl.json
  37. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/pl-PL.json
  38. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/pt-BR.json
  39. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ro-RO.json
  40. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/ru.json
  41. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sk.json
  42. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sl.json
  43. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/sv.json
  44. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json
  45. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/vi.json
  46. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json
  47. 3
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hant.json
  48. 1
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Menus/MenuItemConsts.cs
  49. 1
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/DefaultBlogFeatureProvider.cs
  50. 2
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs
  51. 19
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs
  52. 12
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MarkedItems/MarkedItemManager.cs
  53. 6
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuItem.cs
  54. 36
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs
  55. 2
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs
  56. 46
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs
  57. 1
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs
  58. 13
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs
  59. 12
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs
  60. 2
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/MarkedItemToggle/default.css
  61. 8
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Modals/Login/LoginModal.cshtml
  62. 43
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml
  63. 24
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs
  64. 27
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/filter-on-favorites.js
  65. 5
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.css
  66. 16
      modules/docs/.abpstudio/state.json
  67. 11
      modules/docs/Default.abprun.json
  68. 6
      modules/docs/Volo.Docs.abpsln
  69. 20
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20241231072012_Initial.Designer.cs
  70. 7
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20241231072012_Initial.cs
  71. 18
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs
  72. 3
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs
  73. 7
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
  74. 6
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.Generated.cs
  75. 23
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/docs-admin-generate-proxy.json
  76. 14
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo.Docs.Admin.HttpApi.Client.abppkg
  77. 8
      modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
  78. 11
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs
  79. 13
      modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.abppkg
  80. 7
      modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js
  81. 5
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js

5
abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/en.json

@ -13,6 +13,9 @@
"ManageAccount": "My Account | ABP.IO", "ManageAccount": "My Account | ABP.IO",
"ManageYourProfile": "Manage your profile", "ManageYourProfile": "Manage your profile",
"ReturnToApplication": "Return to application", "ReturnToApplication": "Return to application",
"IdentityUserNotAvailable:Deleted": "This email address is not available. Reason: Already deleted." "IdentityUserNotAvailable:Deleted": "This email address is not available. Reason: Already deleted.",
"SelectYourOrganization": "Select your organization",
"PleaseSelectOrganization": "Please select an organization to continue",
"Continue": "Continue"
} }
} }

5
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -680,6 +680,9 @@
"AdditionalDeveloperUpgradePrice": "Additional Developer Upgrade Price", "AdditionalDeveloperUpgradePrice": "Additional Developer Upgrade Price",
"EditLicense{0}": "Edit {0} License", "EditLicense{0}": "Edit {0} License",
"CampaignNameAlreadyExists": "Campaign name already exists", "CampaignNameAlreadyExists": "Campaign name already exists",
"DiscountRate": "Discount Rate" "DiscountRate": "Discount Rate",
"Menu:RedisManagement": "Redis Management",
"RedisManagement": "Redis Management",
"Permission:RedisManagement": "Redis Management"
} }
} }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuItemAdminAppService.cs

@ -21,4 +21,6 @@ public interface IMenuItemAdminAppService : IApplicationService
Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input); Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input);
Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input); Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input);
Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto);
} }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemCreateInput.cs

@ -27,4 +27,6 @@ public class MenuItemCreateInput : ExtensibleObject
public string CssClass { get; set; } public string CssClass { get; set; }
public Guid? PageId { get; set; } public Guid? PageId { get; set; }
public string RequiredPermissionName { get; set; }
} }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemUpdateInput.cs

@ -24,6 +24,8 @@ public class MenuItemUpdateInput : ExtensibleObject, IHasConcurrencyStamp
public string CssClass { get; set; } public string CssClass { get; set; }
public Guid? PageId { get; set; } public Guid? PageId { get; set; }
public string RequiredPermissionName { get; set; }
public string ConcurrencyStamp { get; set; } public string ConcurrencyStamp { get; set; }
} }

8
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/PermissionLookupDto.cs

@ -0,0 +1,8 @@
namespace Volo.CmsKit.Admin.Menus;
public class PermissionLookupDto
{
public string Name { get; set; }
public string DisplayName { get; set; }
}

6
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/PermissionLookupInputDto.cs

@ -0,0 +1,6 @@
namespace Volo.CmsKit.Admin.Menus;
public class PermissionLookupInputDto
{
public string Filter { get; set; }
}

10
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs

@ -111,9 +111,15 @@ public class BlogPostAdminAppService : CmsKitAppServiceBase, IBlogPostAdminAppSe
{ {
var blogs = (await BlogRepository.GetListAsync()).ToDictionary(x => x.Id); var blogs = (await BlogRepository.GetListAsync()).ToDictionary(x => x.Id);
var blogPosts = await BlogPostRepository.GetListAsync(input.Filter, input.BlogId, input.AuthorId, input.TagId, var blogPosts = await BlogPostRepository.GetListAsync(
input.Filter,
input.BlogId,
input.AuthorId,
input.TagId,
statusFilter: input.Status, statusFilter: input.Status,
input.MaxResultCount, input.SkipCount, input.Sorting); maxResultCount: input.MaxResultCount,
skipCount: input.SkipCount,
sorting: input.Sorting);
var count = await BlogPostRepository.GetCountAsync(input.Filter, input.BlogId, input.AuthorId, tagId: input.TagId); var count = await BlogPostRepository.GetCountAsync(input.Filter, input.BlogId, input.AuthorId, tagId: input.TagId);

28
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs

@ -1,8 +1,10 @@
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;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
@ -23,15 +25,18 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
protected MenuItemManager MenuManager { get; } protected MenuItemManager MenuManager { get; }
protected IMenuItemRepository MenuItemRepository { get; } protected IMenuItemRepository MenuItemRepository { get; }
protected IPageRepository PageRepository { get; } protected IPageRepository PageRepository { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
public MenuItemAdminAppService( public MenuItemAdminAppService(
MenuItemManager menuManager, MenuItemManager menuManager,
IMenuItemRepository menuRepository, IMenuItemRepository menuRepository,
IPageRepository pageRepository) IPageRepository pageRepository,
IPermissionDefinitionManager permissionDefinitionManager)
{ {
MenuManager = menuManager; MenuManager = menuManager;
MenuItemRepository = menuRepository; MenuItemRepository = menuRepository;
PageRepository = pageRepository; PageRepository = pageRepository;
PermissionDefinitionManager = permissionDefinitionManager;
} }
public virtual async Task<ListResultDto<MenuItemDto>> GetListAsync() public virtual async Task<ListResultDto<MenuItemDto>> GetListAsync()
@ -70,7 +75,8 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
input.Target, input.Target,
input.ElementId, input.ElementId,
input.CssClass, input.CssClass,
CurrentTenant.Id CurrentTenant.Id,
input.RequiredPermissionName
); );
if (input.PageId.HasValue) if (input.PageId.HasValue)
@ -103,6 +109,7 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
menuItem.Target = input.Target; menuItem.Target = input.Target;
menuItem.ElementId = input.ElementId; menuItem.ElementId = input.ElementId;
menuItem.CssClass = input.CssClass; menuItem.CssClass = input.CssClass;
menuItem.RequiredPermissionName = input.RequiredPermissionName;
menuItem.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); menuItem.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
input.MapExtraPropertiesTo(menuItem); input.MapExtraPropertiesTo(menuItem);
await MenuItemRepository.UpdateAsync(menuItem); await MenuItemRepository.UpdateAsync(menuItem);
@ -138,4 +145,21 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
ObjectMapper.Map<List<Page>, List<PageLookupDto>>(pages) ObjectMapper.Map<List<Page>, List<PageLookupDto>>(pages)
); );
} }
public virtual async Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto)
{
var permissions = await PermissionDefinitionManager.GetPermissionsAsync();
var permissionLookupDtos= permissions
.WhereIf(!inputDto.Filter.IsNullOrWhiteSpace(), p => p.Name.Contains(inputDto.Filter, StringComparison.OrdinalIgnoreCase))
.Select(x => new PermissionLookupDto
{
Name = x.Name,
DisplayName = x.DisplayName.Localize(StringLocalizerFactory)
}).ToList();
return new ListResultDto<PermissionLookupDto>(
permissionLookupDtos
);
}
} }

8
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs

@ -72,4 +72,12 @@ public partial class MenuItemAdminClientProxy : ClientProxyBase<IMenuItemAdminAp
{ typeof(PageLookupInputDto), input } { typeof(PageLookupInputDto), input }
}); });
} }
public virtual async Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto)
{
return await RequestAsync<ListResultDto<PermissionLookupDto>>(nameof(GetPermissionLookupAsync), new ClientProxyRequestTypeValue
{
{ typeof(PermissionLookupInputDto), inputDto }
});
}
} }

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

@ -40,7 +40,7 @@
"typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib", "typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib",
"type": "System.Guid?", "type": "System.Guid?",
"typeSimple": "string?", "typeSimple": "string?",
"isOptional": false, "isOptional": true,
"defaultValue": null "defaultValue": null
} }
], ],
@ -2167,6 +2167,23 @@
"type": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.CmsKit.Admin.Menus.PageLookupDto>", "type": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.CmsKit.Admin.Menus.PageLookupDto>",
"typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.CmsKit.Admin.Menus.PageLookupDto>" "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.CmsKit.Admin.Menus.PageLookupDto>"
} }
},
{
"name": "GetPermissionLookupAsync",
"parametersOnMethod": [
{
"name": "inputDto",
"typeAsString": "Volo.CmsKit.Admin.Menus.PermissionLookupInputDto, Volo.CmsKit.Admin.Application.Contracts",
"type": "Volo.CmsKit.Admin.Menus.PermissionLookupInputDto",
"typeSimple": "Volo.CmsKit.Admin.Menus.PermissionLookupInputDto",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Menus.PermissionLookupDto>",
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Menus.PermissionLookupDto>"
}
} }
] ]
} }
@ -2484,6 +2501,43 @@
}, },
"allowAnonymous": false, "allowAnonymous": false,
"implementFrom": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService" "implementFrom": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService"
},
"GetPermissionLookupAsyncByInputDto": {
"uniqueName": "GetPermissionLookupAsyncByInputDto",
"name": "GetPermissionLookupAsync",
"httpMethod": "GET",
"url": "api/cms-kit-admin/menu-items/lookup/permissions",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "inputDto",
"typeAsString": "Volo.CmsKit.Admin.Menus.PermissionLookupInputDto, Volo.CmsKit.Admin.Application.Contracts",
"type": "Volo.CmsKit.Admin.Menus.PermissionLookupInputDto",
"typeSimple": "Volo.CmsKit.Admin.Menus.PermissionLookupInputDto",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "inputDto",
"name": "Filter",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "inputDto"
}
],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Menus.PermissionLookupDto>",
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Menus.PermissionLookupDto>"
},
"allowAnonymous": false,
"implementFrom": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService"
} }
} }
}, },

7
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuItemAdminController.cs

@ -78,4 +78,11 @@ public class MenuItemAdminController : CmsKitAdminController, IMenuItemAdminAppS
{ {
return MenuItemAdminAppService.GetPageLookupAsync(input); return MenuItemAdminAppService.GetPageLookupAsync(input);
} }
[HttpGet]
[Route("lookup/permissions")]
public Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto)
{
return MenuItemAdminAppService.GetPermissionLookupAsync(inputDto);
}
} }

5
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml

@ -60,6 +60,11 @@
<abp-input asp-for="ViewModel.ParentId"/> <abp-input asp-for="ViewModel.ParentId"/>
<abp-input asp-for="ViewModel.DisplayName"/> <abp-input asp-for="ViewModel.DisplayName"/>
<div class="mb-3">
<label class="form-label" for="requiredPermissionName">@L["RequiredPermissionName"].Value</label>
<select asp-for="ViewModel.RequiredPermissionName" id="requiredPermissionName" class="form-control"></select>
<div id="tooltip_container"></div>
</div>
<abp-input asp-for="ViewModel.IsActive"/> <abp-input asp-for="ViewModel.IsActive"/>
<abp-input asp-for="ViewModel.Icon"/> <abp-input asp-for="ViewModel.Icon"/>
<abp-input asp-for="ViewModel.Order"/> <abp-input asp-for="ViewModel.Order"/>

4
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoMapper; using AutoMapper;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending;
@ -32,7 +33,6 @@ public class CreateModalModel : CmsKitAdminPageModel
public virtual async Task OnGetAsync(Guid? parentId) public virtual async Task OnGetAsync(Guid? parentId)
{ {
ViewModel.ParentId = parentId; ViewModel.ParentId = parentId;
IsPageFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<PagesFeature>() IsPageFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<PagesFeature>()
&& await FeatureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable); && await FeatureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable);
} }
@ -72,6 +72,8 @@ public class CreateModalModel : CmsKitAdminPageModel
public string ElementId { get; set; } public string ElementId { get; set; }
public string CssClass { get; set; } public string CssClass { get; set; }
public string RequiredPermissionName { get; set; }
} }
} }

24
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml

@ -64,6 +64,30 @@
} }
<abp-input asp-for="ViewModel.DisplayName"/> <abp-input asp-for="ViewModel.DisplayName"/>
<div class="mb-3">
<label class="form-label" for="requiredPermissionName">@L["RequiredPermissionName"].Value</label>
<select asp-for="ViewModel.RequiredPermissionName" id="requiredPermissionName" class="form-control">
@if(Model.ViewModel.RequiredPermissionName != null)
{
var selectedPermission = Model.Permissions.FirstOrDefault(p => p.Name == Model.ViewModel.RequiredPermissionName);
if (selectedPermission != null)
{
<option
data-bs-toggle="tooltip"
data-bs-container="#tooltip_container"
data-bs-placement="top"
title="@selectedPermission.DisplayName"
selected
value="@Model.ViewModel.RequiredPermissionName">@selectedPermission.Name</option>
}
else
{
<option selected value="@Model.ViewModel.RequiredPermissionName">@Model.ViewModel.RequiredPermissionName</option>
}
}
</select>
<div id="tooltip_container"></div>
</div>
<abp-input asp-for="ViewModel.IsActive"/> <abp-input asp-for="ViewModel.IsActive"/>
<abp-input asp-for="ViewModel.Icon"/> <abp-input asp-for="ViewModel.Icon"/>
<abp-input asp-for="ViewModel.Target"/> <abp-input asp-for="ViewModel.Target"/>

7
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoMapper; using AutoMapper;
@ -28,6 +29,8 @@ public class UpdateModalModel : CmsKitAdminPageModel
public Guid Id { get; set; } public Guid Id { get; set; }
public bool IsPageFeatureEnabled { get; set; } public bool IsPageFeatureEnabled { get; set; }
public IReadOnlyList<PermissionLookupDto> Permissions { get; set; }
public UpdateModalModel(IMenuItemAdminAppService menuAdminAppService, IFeatureChecker featureChecker) public UpdateModalModel(IMenuItemAdminAppService menuAdminAppService, IFeatureChecker featureChecker)
{ {
@ -39,7 +42,7 @@ public class UpdateModalModel : CmsKitAdminPageModel
public async Task OnGetAsync() public async Task OnGetAsync()
{ {
var menuItemDto = await MenuAdminAppService.GetAsync(Id); var menuItemDto = await MenuAdminAppService.GetAsync(Id);
Permissions = (await MenuAdminAppService.GetPermissionLookupAsync(new PermissionLookupInputDto())).Items;
IsPageFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<PagesFeature>() IsPageFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<PagesFeature>()
&& await FeatureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable); && await FeatureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable);
@ -76,6 +79,8 @@ public class UpdateModalModel : CmsKitAdminPageModel
public Guid? PageId { get; set; } public Guid? PageId { get; set; }
public string? PageTitle { get; set; } public string? PageTitle { get; set; }
public string RequiredPermissionName { get; set; }
[HiddenInput] [HiddenInput]
public string ConcurrencyStamp { get; set; } public string ConcurrencyStamp { get; set; }

46
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/createModal.js

@ -8,6 +8,7 @@ $(function () {
var $url = $('#ViewModel_Url'); var $url = $('#ViewModel_Url');
var $displayName = $('#ViewModel_DisplayName'); var $displayName = $('#ViewModel_DisplayName');
var $menuItemForm = $('#menu-item-form'); var $menuItemForm = $('#menu-item-form');
var $selectRequiredPermission = $('#requiredPermissionName');
$pageId.on('change', function (params) { $pageId.on('change', function (params) {
$url.prop('disabled', $pageId.val()); $url.prop('disabled', $pageId.val());
@ -20,6 +21,51 @@ $(function () {
} }
}) })
function initSelectRequiredPermission(){
function formatDisplayName(item) {
if (!item.id) {
return item.text;
}
var $displayName = $(`<span data-bs-toggle="tooltip" data-bs-container="#tooltip_container" data-bs-placement="top" title="${item.displayName}">${item.id}</span>`);
$displayName.tooltip();
return $displayName;
}
$selectRequiredPermission.select2({
ajax:{
url: '/api/cms-kit-admin/menu-items/lookup/permissions',
delay: 250,
dataType: "json",
data: function (params) {
let query = {};
query["filter"] = params.term;
return query;
},
processResults: function (data) {
let retVal = [];
let items = data["items"];
$('body').tooltip('dispose');
items.forEach(function (item, index) {
retVal.push({
id: item["name"],
text: item["name"],
displayName: item["displayName"]
})
});
return {
results: retVal
};
}
},
templateResult: formatDisplayName,
width: '100%',
dropdownParent: $('#menu-create-modal'),
language: abp.localization.currentCulture.cultureName
});
}
initSelectRequiredPermission();
$menuItemForm.on('submit', function (e) { $menuItemForm.on('submit', function (e) {
$('[href="#url"]').tab('show'); $('[href="#url"]').tab('show');
}); });

47
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/updateModal.js

@ -8,6 +8,7 @@ $(function () {
var $url = $('#ViewModel_Url'); var $url = $('#ViewModel_Url');
var $displayName = $('#ViewModel_DisplayName'); var $displayName = $('#ViewModel_DisplayName');
var $menuItemForm = $('#menu-item-form'); var $menuItemForm = $('#menu-item-form');
var $selectRequiredPermission = $('#requiredPermissionName');
$pageId.on('change', function (params) { $pageId.on('change', function (params) {
$url.prop('disabled', $pageId.val()); $url.prop('disabled', $pageId.val());
@ -21,6 +22,52 @@ $(function () {
$pageId.trigger('change'); $pageId.trigger('change');
function initSelectRequiredPermission(){
function formatDisplayName(item) {
if (!item.id) {
return item.text;
}
var $displayName = $(`<span data-bs-container="#tooltip_container" data-bs-toggle="tooltip" data-bs-placement="top" title="${item.displayName}">${item.id}</span>`);
$displayName.tooltip();
return $displayName;
}
$selectRequiredPermission.select2({
ajax:{
url: '/api/cms-kit-admin/menu-items/lookup/permissions',
delay: 250,
dataType: "json",
data: function (params) {
let query = {};
query["filter"] = params.term;
return query;
},
processResults: function (data) {
let retVal = [];
let items = data["items"];
$('body').tooltip('dispose');
items.forEach(function (item, index) {
retVal.push({
id: item["name"],
text: item["name"],
displayName: item["displayName"]
})
});
return {
results: retVal
};
}
},
templateResult: formatDisplayName,
width: '100%',
dropdownParent: $('#menu-update-modal'),
language: abp.localization.currentCulture.cultureName
});
}
initSelectRequiredPermission();
$('[data-ts-toggle="tooltip"]').tooltip()
$menuItemForm.on('submit', function (e) { $menuItemForm.on('submit', function (e) {
$('[href="#url"]').tab('show'); $('[href="#url"]').tab('show');
}); });

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs

@ -26,6 +26,8 @@ public class MenuItemDto : ExtensibleAuditedEntityDto<Guid>, IHasConcurrencyStam
public string CssClass { get; set; } public string CssClass { get; set; }
public Guid? PageId { get; set; } public Guid? PageId { get; set; }
public string RequiredPermissionName { get; set; }
public string ConcurrencyStamp { get; set; } public string ConcurrencyStamp { get; set; }
} }

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

@ -15,6 +15,7 @@
"CmsKit.Ratings": "التقييمات", "CmsKit.Ratings": "التقييمات",
"CmsKit.Reactions": "تفاعلات", "CmsKit.Reactions": "تفاعلات",
"CmsKit.Tags": "العلامات", "CmsKit.Tags": "العلامات",
"CmsKit.MarkedItems": "العناصر المميزة",
"CmsKit:0002": "المحتوى موجود بالفعل!", "CmsKit:0002": "المحتوى موجود بالفعل!",
"CmsKit:0003": "الكيان {0} غير قابل للعلامة.", "CmsKit:0003": "الكيان {0} غير قابل للعلامة.",
"CmsKit:Blog:0001": "slug المحدد ({Slug}) موجود بالفعل!", "CmsKit:Blog:0001": "slug المحدد ({Slug}) موجود بالفعل!",
@ -28,6 +29,9 @@
"CmsKit:MarkedItem:0001": "لا يمكن أن تمييز الكيان {EntityType}.", "CmsKit:MarkedItem:0001": "لا يمكن أن تمييز الكيان {EntityType}.",
"CmsKit:MarkedItem:0002": "لم يتم العثور على تعريف لنوع الكيان '{EntityType}'.", "CmsKit:MarkedItem:0002": "لم يتم العثور على تعريف لنوع الكيان '{EntityType}'.",
"CmsKit:MarkedItem:0003": "يوجد بالفعل تعريف لنوع الكيان '{EntityType}'. يجب أن يكون لكل نوع كيان تعريف واحد فقط.", "CmsKit:MarkedItem:0003": "يوجد بالفعل تعريف لنوع الكيان '{EntityType}'. يجب أن يكون لكل نوع كيان تعريف واحد فقط.",
"ToggleFavorite": "تفضيل/إلغاء",
"FavoritesFilterMessage": "يرجى تسجيل الدخول لتصفية المفضلات الخاصة بك",
"FilterOnFavorites": "تصفية المفضلات",
"CmsKit:Tag:0002": "الكيان غير قابل للوسم!", "CmsKit:Tag:0002": "الكيان غير قابل للوسم!",
"CommentAuthorizationExceptionMessage": "هذه التعليقات غير مسموح بها للعرض العام.", "CommentAuthorizationExceptionMessage": "هذه التعليقات غير مسموح بها للعرض العام.",
"CommentDeletionConfirmationMessage": "سيتم حذف هذا التعليق وجميع الردود!", "CommentDeletionConfirmationMessage": "سيتم حذف هذا التعليق وجميع الردود!",
@ -241,6 +245,7 @@
"ChooseAnActionForBlog": "اختر إجراءً للمدونة", "ChooseAnActionForBlog": "اختر إجراءً للمدونة",
"AssignBlogPostsToOtherBlog": "تعيين مشاركات المدونة إلى مدونة أخرى", "AssignBlogPostsToOtherBlog": "تعيين مشاركات المدونة إلى مدونة أخرى",
"SelectAnBlogToAssign": "حدد مدونة لتعيين مشاركات المدونة إليها", "SelectAnBlogToAssign": "حدد مدونة لتعيين مشاركات المدونة إليها",
"DeleteAllBlogPostsOfThisBlog": "حذف جميع مشاركات المدونة" "DeleteAllBlogPostsOfThisBlog": "حذف جميع مشاركات المدونة",
"RequiredPermissionName": "اسم الإذن المطلوب",
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Vyberte akci pro blog", "ChooseAnActionForBlog": "Vyberte akci pro blog",
"AssignBlogPostsToOtherBlog": "Přiřaďte blogové příspěvky k jinému blogu", "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", "SelectAnBlogToAssign": "Vyberte blog, ke kterému chcete přiřadit blogové příspěvky",
"DeleteAllBlogPostsOfThisBlog": "Smazat všechny blogové příspěvky tohoto blogu" "DeleteAllBlogPostsOfThisBlog": "Smazat všechny blogové příspěvky tohoto blogu",
"RequiredPermissionName": "Je vyžadováno oprávnění"
} }
} }

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

@ -165,6 +165,7 @@
"ChooseAnActionForBlog": "Wählen Sie eine Aktion für den Blog", "ChooseAnActionForBlog": "Wählen Sie eine Aktion für den Blog",
"AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen", "AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen",
"SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen", "SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen",
"DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen" "DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen",
"RequiredPermissionName": "Erforderlicher Berechtigungsname"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Wählen Sie eine Aktion für den Blog", "ChooseAnActionForBlog": "Wählen Sie eine Aktion für den Blog",
"AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen", "AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen",
"SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen", "SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen",
"DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen" "DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen",
"RequiredPermissionName": "Erforderlicher Berechtigungsname"
} }
} }

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

@ -188,6 +188,7 @@
"ChooseAnActionForBlog": "Επιλέξτε μια ενέργεια για το ιστολόγιο", "ChooseAnActionForBlog": "Επιλέξτε μια ενέργεια για το ιστολόγιο",
"AssignBlogPostsToOtherBlog": "Ανάθεση αναρτήσεων ιστολογίου σε άλλο ιστολόγιο", "AssignBlogPostsToOtherBlog": "Ανάθεση αναρτήσεων ιστολογίου σε άλλο ιστολόγιο",
"SelectAnBlogToAssign": "Επιλέξτε ένα ιστολόγιο για να αναθέσετε αναρτήσεις ιστολογίου", "SelectAnBlogToAssign": "Επιλέξτε ένα ιστολόγιο για να αναθέσετε αναρτήσεις ιστολογίου",
"DeleteAllBlogPostsOfThisBlog": "Διαγραφή όλων των αναρτήσεων ιστολογίου αυτού του ιστολογίου" "DeleteAllBlogPostsOfThisBlog": "Διαγραφή όλων των αναρτήσεων ιστολογίου αυτού του ιστολογίου",
"RequiredPermissionName": "Απαιτούμενο όνομα δικαιώματος"
} }
} }

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

@ -32,6 +32,7 @@
"ChooseAnActionForBlog": "Choose an action for the blog", "ChooseAnActionForBlog": "Choose an action for the blog",
"AssignBlogPostsToOtherBlog": "Assign blog posts to another blog", "AssignBlogPostsToOtherBlog": "Assign blog posts to another blog",
"SelectAnBlogToAssign": "Select a blog to assign", "SelectAnBlogToAssign": "Select a blog to assign",
"DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog" "DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog",
"RequiredPermissionName": "Required permission name"
} }
} }

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

@ -15,6 +15,7 @@
"CmsKit.Ratings": "Ratings", "CmsKit.Ratings": "Ratings",
"CmsKit.Reactions": "Reactions", "CmsKit.Reactions": "Reactions",
"CmsKit.Tags": "Tags", "CmsKit.Tags": "Tags",
"CmsKit.MarkedItems": "Marked Items",
"CmsKit:0002": "Content already exists!", "CmsKit:0002": "Content already exists!",
"CmsKit:0003": "The entity {0} is not taggable.", "CmsKit:0003": "The entity {0} is not taggable.",
"CmsKit:Blog:0001": "The given slug ({Slug}) already exists!", "CmsKit:Blog:0001": "The given slug ({Slug}) already exists!",
@ -27,6 +28,9 @@
"CmsKit:Reaction:0001": "The entity {EntityType} can't have reactions.", "CmsKit:Reaction:0001": "The entity {EntityType} can't have reactions.",
"CmsKit:Tag:0002": "The entity is not taggable!", "CmsKit:Tag:0002": "The entity is not taggable!",
"CmsKit:MarkedItem:ToggleConfirmation": "Are you sure you want to toggle the marked item?", "CmsKit:MarkedItem:ToggleConfirmation": "Are you sure you want to toggle the marked item?",
"ToggleFavorite": "Add/Remove Favorite",
"FavoritesFilterMessage": "Please log in to filter your favorites",
"FilterOnFavorites": "Filter On Favorites",
"CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.",
"CmsKit:Modals:Login": "Login", "CmsKit:Modals:Login": "Login",
"CmsKit:Modals:LoginModalDefaultMessage": "Please login to continue!", "CmsKit:Modals:LoginModalDefaultMessage": "Please login to continue!",
@ -259,6 +263,7 @@
"ChooseAnActionForBlog": "Choose an action for the blog", "ChooseAnActionForBlog": "Choose an action for the blog",
"AssignBlogPostsToOtherBlog": "Assign blog posts to another blog", "AssignBlogPostsToOtherBlog": "Assign blog posts to another blog",
"SelectAnBlogToAssign": "Select a blog to assign", "SelectAnBlogToAssign": "Select a blog to assign",
"DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog" "DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog",
"RequiredPermissionName": "Required permission name"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Elija una acción para el blog", "ChooseAnActionForBlog": "Elija una acción para el blog",
"AssignBlogPostsToOtherBlog": "Asignar publicaciones de blog a otro blog", "AssignBlogPostsToOtherBlog": "Asignar publicaciones de blog a otro blog",
"SelectAnBlogToAssign": "Seleccione un blog para asignar publicaciones de blog", "SelectAnBlogToAssign": "Seleccione un blog para asignar publicaciones de blog",
"DeleteAllBlogPostsOfThisBlog": "Eliminar todas las publicaciones de blog de este blog" "DeleteAllBlogPostsOfThisBlog": "Eliminar todas las publicaciones de blog de este blog",
"RequiredPermissionName": "Nombre de permiso requerido"
} }
} }

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

@ -187,6 +187,7 @@
"ChooseAnActionForBlog": "یک عمل برای وبلاگ انتخاب کنید", "ChooseAnActionForBlog": "یک عمل برای وبلاگ انتخاب کنید",
"AssignBlogPostsToOtherBlog": "پست های وبلاگ را به وبلاگ دیگری اختصاص دهید", "AssignBlogPostsToOtherBlog": "پست های وبلاگ را به وبلاگ دیگری اختصاص دهید",
"SelectAnBlogToAssign": "یک وبلاگ برای اختصاص دادن انتخاب کنید", "SelectAnBlogToAssign": "یک وبلاگ برای اختصاص دادن انتخاب کنید",
"DeleteAllBlogPostsOfThisBlog": "تمام پست های وبلاگ این وبلاگ را حذف کنید" "DeleteAllBlogPostsOfThisBlog": "تمام پست های وبلاگ این وبلاگ را حذف کنید",
"RequiredPermissionName": "نام مجوز مورد نیاز"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Valitse toiminto blogille", "ChooseAnActionForBlog": "Valitse toiminto blogille",
"AssignBlogPostsToOtherBlog": "Määritä blogiviestit toiseen blogiin", "AssignBlogPostsToOtherBlog": "Määritä blogiviestit toiseen blogiin",
"SelectAnBlogToAssign": "Valitse blogi, johon haluat määrittää", "SelectAnBlogToAssign": "Valitse blogi, johon haluat määrittää",
"DeleteAllBlogPostsOfThisBlog": "Poista tämän blogin kaikki blogiviestit" "DeleteAllBlogPostsOfThisBlog": "Poista tämän blogin kaikki blogiviestit",
"RequiredPermissionName": "Tarvittava lupa"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Choisissez une action pour le blog", "ChooseAnActionForBlog": "Choisissez une action pour le blog",
"AssignBlogPostsToOtherBlog": "Attribuer des articles de blog à un autre blog", "AssignBlogPostsToOtherBlog": "Attribuer des articles de blog à un autre blog",
"SelectAnBlogToAssign": "Sélectionnez un blog à attribuer", "SelectAnBlogToAssign": "Sélectionnez un blog à attribuer",
"DeleteAllBlogPostsOfThisBlog": "Supprimer tous les articles de blog de ce blog" "DeleteAllBlogPostsOfThisBlog": "Supprimer tous les articles de blog de ce blog",
"RequiredPermissionName": "Nom de permission requis"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "ब्लॉग के लिए कोई कार्रवाई चुनें", "ChooseAnActionForBlog": "ब्लॉग के लिए कोई कार्रवाई चुनें",
"AssignBlogPostsToOtherBlog": "अन्य ब्लॉग को ब्लॉग पोस्ट असाइन करें", "AssignBlogPostsToOtherBlog": "अन्य ब्लॉग को ब्लॉग पोस्ट असाइन करें",
"SelectAnBlogToAssign": "असाइन करने के लिए एक ब्लॉग चुनें", "SelectAnBlogToAssign": "असाइन करने के लिए एक ब्लॉग चुनें",
"DeleteAllBlogPostsOfThisBlog": "इस ब्लॉग के सभी ब्लॉग पोस्ट हटाएं" "DeleteAllBlogPostsOfThisBlog": "इस ब्लॉग के सभी ब्लॉग पोस्ट हटाएं",
"RequiredPermissionName": "आवश्यक अनुमति नाम"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Odaberite radnju za blog", "ChooseAnActionForBlog": "Odaberite radnju za blog",
"AssignBlogPostsToOtherBlog": "Dodijelite postove na blogu drugom blogu", "AssignBlogPostsToOtherBlog": "Dodijelite postove na blogu drugom blogu",
"SelectAnBlogToAssign": "Odaberite blog za dodjelu", "SelectAnBlogToAssign": "Odaberite blog za dodjelu",
"DeleteAllBlogPostsOfThisBlog": "Izbrišite sve postove na blogu" "DeleteAllBlogPostsOfThisBlog": "Izbrišite sve postove na blogu",
"RequiredPermissionName": "Potrebno ime dozvole"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Válasszon egy műveletet a bloghoz", "ChooseAnActionForBlog": "Válasszon egy műveletet a bloghoz",
"AssignBlogPostsToOtherBlog": "Blogbejegyzések hozzárendelése egy másik bloghoz", "AssignBlogPostsToOtherBlog": "Blogbejegyzések hozzárendelése egy másik bloghoz",
"SelectAnBlogToAssign": "Válasszon egy blogot a hozzárendeléshez", "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?" "DeleteAllBlogPostsOfThisBlog": "Ez a művelet törli az összes blogbejegyzést ebből a blogból. Biztos vagy benne?",
"RequiredPermissionName": "Szükséges engedély neve"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Veldu aðgerð fyrir blogg", "ChooseAnActionForBlog": "Veldu aðgerð fyrir blogg",
"AssignBlogPostsToOtherBlog": "Úthluta bloggfærslum til annars bloggs", "AssignBlogPostsToOtherBlog": "Úthluta bloggfærslum til annars bloggs",
"SelectAnBlogToAssign": "Veldu blogg til að úthluta", "SelectAnBlogToAssign": "Veldu blogg til að úthluta",
"DeleteAllBlogPostsOfThisBlog": "Eyða öllum bloggfærslum þessa bloggs" "DeleteAllBlogPostsOfThisBlog": "Eyða öllum bloggfærslum þessa bloggs",
"RequiredPermissionName": "Nafn á nauðsynlegri leyfi"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Scegli un'azione per il blog", "ChooseAnActionForBlog": "Scegli un'azione per il blog",
"AssignBlogPostsToOtherBlog": "Assegna i post del blog ad un altro blog", "AssignBlogPostsToOtherBlog": "Assegna i post del blog ad un altro blog",
"SelectAnBlogToAssign": "Seleziona un blog a cui assegnare i post del blog", "SelectAnBlogToAssign": "Seleziona un blog a cui assegnare i post del blog",
"DeleteAllBlogPostsOfThisBlog": "Elimina tutti i post del blog di questo blog" "DeleteAllBlogPostsOfThisBlog": "Elimina tutti i post del blog di questo blog",
"RequiredPermissionName": "Nome del permesso richiesto"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Kies een actie voor de blog", "ChooseAnActionForBlog": "Kies een actie voor de blog",
"AssignBlogPostsToOtherBlog": "Wijs blogberichten toe aan een andere blog", "AssignBlogPostsToOtherBlog": "Wijs blogberichten toe aan een andere blog",
"SelectAnBlogToAssign": "Selecteer een blog om toe te wijzen", "SelectAnBlogToAssign": "Selecteer een blog om toe te wijzen",
"DeleteAllBlogPostsOfThisBlog": "Verwijder alle blogberichten van deze blog" "DeleteAllBlogPostsOfThisBlog": "Verwijder alle blogberichten van deze blog",
"RequiredPermissionName": "Vereiste toestemming"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Wybierz akcję dla bloga", "ChooseAnActionForBlog": "Wybierz akcję dla bloga",
"AssignBlogPostsToOtherBlog": "Przypisz posty na blogu do innego bloga", "AssignBlogPostsToOtherBlog": "Przypisz posty na blogu do innego bloga",
"SelectAnBlogToAssign": "Wybierz blog, do którego chcesz przypisać posty na blogu", "SelectAnBlogToAssign": "Wybierz blog, do którego chcesz przypisać posty na blogu",
"DeleteAllBlogPostsOfThisBlog": "Usuń wszystkie posty na blogu tego bloga" "DeleteAllBlogPostsOfThisBlog": "Usuń wszystkie posty na blogu tego bloga",
"RequiredPermissionName": "Wymagana nazwa uprawnienia"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Escolha uma ação para o blog", "ChooseAnActionForBlog": "Escolha uma ação para o blog",
"AssignBlogPostsToOtherBlog": "Atribuir postagens de blog a outro blog", "AssignBlogPostsToOtherBlog": "Atribuir postagens de blog a outro blog",
"SelectAnBlogToAssign": "Selecione um blog para atribuir", "SelectAnBlogToAssign": "Selecione um blog para atribuir",
"DeleteAllBlogPostsOfThisBlog": "Excluir todas as postagens de blog deste blog" "DeleteAllBlogPostsOfThisBlog": "Excluir todas as postagens de blog deste blog",
"RequiredPermissionName": "Nome da permissão necessária"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Alegeţi o acţiune pentru blog", "ChooseAnActionForBlog": "Alegeţi o acţiune pentru blog",
"AssignBlogPostsToOtherBlog": "Atribuiţi postările de blog la alt blog", "AssignBlogPostsToOtherBlog": "Atribuiţi postările de blog la alt blog",
"SelectAnBlogToAssign": "Selectaţi un blog pentru a atribui postările de blog", "SelectAnBlogToAssign": "Selectaţi un blog pentru a atribui postările de blog",
"DeleteAllBlogPostsOfThisBlog": "Ştergeţi toate postările de blog ale acestui blog" "DeleteAllBlogPostsOfThisBlog": "Ştergeţi toate postările de blog ale acestui blog",
"RequiredPermissionName": "Numele permisiunii necesare"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Выберите действие для блога", "ChooseAnActionForBlog": "Выберите действие для блога",
"AssignBlogPostsToOtherBlog": "Назначить сообщения в блоге другому блогу", "AssignBlogPostsToOtherBlog": "Назначить сообщения в блоге другому блогу",
"SelectAnBlogToAssign": "Выберите блог для назначения", "SelectAnBlogToAssign": "Выберите блог для назначения",
"DeleteAllBlogPostsOfThisBlog": "Удалить все сообщения в блоге этого блога" "DeleteAllBlogPostsOfThisBlog": "Удалить все сообщения в блоге этого блога",
"RequiredPermissionName": "Имя требуемого разрешения"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Vyberte akciu pre blog", "ChooseAnActionForBlog": "Vyberte akciu pre blog",
"AssignBlogPostsToOtherBlog": "Priradiť blogové príspevky k inému blogu", "AssignBlogPostsToOtherBlog": "Priradiť blogové príspevky k inému blogu",
"SelectAnBlogToAssign": "Vyberte blog, na ktorý chcete priradiť blogové príspevky", "SelectAnBlogToAssign": "Vyberte blog, na ktorý chcete priradiť blogové príspevky",
"DeleteAllBlogPostsOfThisBlog": "Zmazať všetky blogové príspevky tohto blogu" "DeleteAllBlogPostsOfThisBlog": "Zmazať všetky blogové príspevky tohto blogu",
"RequiredPermissionName": "Požadovaný názov oprávnenia"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Izberite dejanje za blog", "ChooseAnActionForBlog": "Izberite dejanje za blog",
"AssignBlogPostsToOtherBlog": "Dodeli objave v blogu drugemu blogu", "AssignBlogPostsToOtherBlog": "Dodeli objave v blogu drugemu blogu",
"SelectAnBlogToAssign": "Izberite blog, ki mu želite dodeliti objave", "SelectAnBlogToAssign": "Izberite blog, ki mu želite dodeliti objave",
"DeleteAllBlogPostsOfThisBlog": "Izbriši vse objave v tem blogu" "DeleteAllBlogPostsOfThisBlog": "Izbriši vse objave v tem blogu",
"RequiredPermissionName": "Ime zahtevane dovoljenja"
} }
} }

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

@ -258,6 +258,7 @@
"ChooseAnActionForBlog": "Välj en åtgärd för bloggen", "ChooseAnActionForBlog": "Välj en åtgärd för bloggen",
"AssignBlogPostsToOtherBlog": "Tilldela blogginlägg till en annan blogg", "AssignBlogPostsToOtherBlog": "Tilldela blogginlägg till en annan blogg",
"SelectAnBlogToAssign": "Välj en blogg att tilldela", "SelectAnBlogToAssign": "Välj en blogg att tilldela",
"DeleteAllBlogPostsOfThisBlog": "Radera alla blogginlägg i denna blogg" "DeleteAllBlogPostsOfThisBlog": "Radera alla blogginlägg i denna blogg",
"RequiredPermissionName": "Nödvändigt behörighetsnamn"
} }
} }

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

@ -222,6 +222,7 @@
"ChooseAnActionForBlog": "Blog için bir eylem seçin", "ChooseAnActionForBlog": "Blog için bir eylem seçin",
"AssignBlogPostsToOtherBlog": "Diğer bloglara blog yazıları atayın", "AssignBlogPostsToOtherBlog": "Diğer bloglara blog yazıları atayın",
"SelectAnBlogToAssign": "Atanacak bir blog seçin", "SelectAnBlogToAssign": "Atanacak bir blog seçin",
"DeleteAllBlogPostsOfThisBlog": "Bu blogun tüm blog yazılarını sil" "DeleteAllBlogPostsOfThisBlog": "Bu blogun tüm blog yazılarını sil",
"RequiredPermissionName": "Gerekli izin adı"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "Chọn một hành động cho blog", "ChooseAnActionForBlog": "Chọn một hành động cho blog",
"AssignBlogPostsToOtherBlog": "Gán bài đăng trên blog cho blog khác", "AssignBlogPostsToOtherBlog": "Gán bài đăng trên blog cho blog khác",
"SelectAnBlogToAssign": "Chọn một blog để gán", "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" "DeleteAllBlogPostsOfThisBlog": "Xóa tất cả bài đăng trên blog của blog này",
"RequiredPermissionName": "Tên quyền cần thiết"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "选择博客的操作", "ChooseAnActionForBlog": "选择博客的操作",
"AssignBlogPostsToOtherBlog": "将博客文章分配给其他博客", "AssignBlogPostsToOtherBlog": "将博客文章分配给其他博客",
"SelectAnBlogToAssign": "选择要分配的博客", "SelectAnBlogToAssign": "选择要分配的博客",
"DeleteAllBlogPostsOfThisBlog": "删除此博客的所有博客文章" "DeleteAllBlogPostsOfThisBlog": "删除此博客的所有博客文章",
"RequiredPermissionName": "所需权限名称"
} }
} }

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

@ -231,6 +231,7 @@
"ChooseAnActionForBlog": "選擇部落格的操作", "ChooseAnActionForBlog": "選擇部落格的操作",
"AssignBlogPostsToOtherBlog": "將部落格文章分配給其他部落格", "AssignBlogPostsToOtherBlog": "將部落格文章分配給其他部落格",
"SelectAnBlogToAssign": "選擇要分配的部落格", "SelectAnBlogToAssign": "選擇要分配的部落格",
"DeleteAllBlogPostsOfThisBlog": "刪除此部落格的所有部落格文章" "DeleteAllBlogPostsOfThisBlog": "刪除此部落格的所有部落格文章",
"RequiredPermissionName": "所需權限名稱"
} }
} }

1
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Menus/MenuItemConsts.cs

@ -4,4 +4,5 @@ public static class MenuItemConsts
{ {
public const int MaxDisplayNameLength = 64; public const int MaxDisplayNameLength = 64;
public const int MaxUrlLength = 1024; public const int MaxUrlLength = 1024;
public const int MaxRequiredPermissionNameLength = 128;
} }

1
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/DefaultBlogFeatureProvider.cs

@ -16,6 +16,7 @@ public class DefaultBlogFeatureProvider : IDefaultBlogFeatureProvider, ITransien
new BlogFeature(blogId, ReactionsFeature.Name), new BlogFeature(blogId, ReactionsFeature.Name),
new BlogFeature(blogId, RatingsFeature.Name), new BlogFeature(blogId, RatingsFeature.Name),
new BlogFeature(blogId, TagsFeature.Name), new BlogFeature(blogId, TagsFeature.Name),
new BlogFeature(blogId, MarkedItemsFeature.Name),
new BlogFeature(blogId, BlogPostScrollIndexFeature.Name), new BlogFeature(blogId, BlogPostScrollIndexFeature.Name),
new BlogFeature(blogId, BlogConsts.PreventXssFeatureName) new BlogFeature(blogId, BlogConsts.PreventXssFeatureName)
}); });

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

@ -14,6 +14,7 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null, Guid? authorId = null,
Guid? tagId = null, Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null, BlogPostStatus? statusFilter = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
@ -22,6 +23,7 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null, Guid? authorId = null,
Guid? tagId = null, Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null, BlogPostStatus? statusFilter = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,
int skipCount = 0, int skipCount = 0,

19
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs

@ -12,6 +12,7 @@ using Volo.CmsKit.Blogs;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Localization; using Volo.CmsKit.Localization;
using Volo.CmsKit.MarkedItems;
using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus; using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
@ -91,6 +92,24 @@ public class CmsKitDomainModule : AbpModule
{ {
// TODO: Configure TagEntityTypes here... // TODO: Configure TagEntityTypes here...
} }
if (GlobalFeatureManager.Instance.IsEnabled<MarkedItemsFeature>())
{
Configure<CmsKitMarkedItemOptions>(options =>
{
if (GlobalFeatureManager.Instance.IsEnabled<BlogsFeature>())
{
options.EntityTypes.Add(
new MarkedItemEntityTypeDefinition(
BlogPostConsts.EntityType,
StandardMarkedItems.Favorite
)
);
}
// TODO: Add more entities that can be marked.
});
}
} }
public override void PostConfigureServices(ServiceConfigurationContext context) public override void PostConfigureServices(ServiceConfigurationContext context)

12
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MarkedItems/MarkedItemManager.cs

@ -2,6 +2,8 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using System.Collections.Generic;
using System.Threading;
namespace Volo.CmsKit.MarkedItems; namespace Volo.CmsKit.MarkedItems;
public class MarkedItemManager : CmsKitDomainServiceBase public class MarkedItemManager : CmsKitDomainServiceBase
@ -20,7 +22,7 @@ public class MarkedItemManager : CmsKitDomainServiceBase
public virtual async Task<bool> ToggleUserMarkedItemAsync( public virtual async Task<bool> ToggleUserMarkedItemAsync(
Guid creatorId, Guid creatorId,
[NotNull] string entityType, [NotNull] string entityType,
[NotNull] string entityId) [NotNull] string entityId)
{ {
Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
@ -49,4 +51,12 @@ public class MarkedItemManager : CmsKitDomainServiceBase
); );
return true; return true;
} }
public async Task<List<string>> GetEntityIdsFilteredByUserAsync(
[NotNull] Guid userId,
[NotNull] string entityType,
[CanBeNull] Guid? tenantId = null,
CancellationToken cancellationToken = default)
{
return await UserMarkedItemRepository.GetEntityIdsFilteredByUserAsync(userId, entityType, tenantId, cancellationToken);
}
} }

6
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuItem.cs

@ -40,6 +40,8 @@ public class MenuItem : AuditedAggregateRoot<Guid>, IMultiTenant
public Guid? PageId { get; protected set; } public Guid? PageId { get; protected set; }
public Guid? TenantId { get; protected set; } public Guid? TenantId { get; protected set; }
public string RequiredPermissionName { get; set; }
protected MenuItem() protected MenuItem()
{ {
@ -55,7 +57,8 @@ public class MenuItem : AuditedAggregateRoot<Guid>, IMultiTenant
[CanBeNull] string target = null, [CanBeNull] string target = null,
[CanBeNull] string elementId = null, [CanBeNull] string elementId = null,
[CanBeNull] string cssClass = null, [CanBeNull] string cssClass = null,
[CanBeNull] Guid? tenantId = null) [CanBeNull] Guid? tenantId = null,
[CanBeNull] string requiredPermissionName = null)
: base(id) : base(id)
{ {
SetDisplayName(displayName); SetDisplayName(displayName);
@ -68,6 +71,7 @@ public class MenuItem : AuditedAggregateRoot<Guid>, IMultiTenant
ElementId = elementId; ElementId = elementId;
CssClass = cssClass; CssClass = cssClass;
TenantId = tenantId; TenantId = tenantId;
RequiredPermissionName = requiredPermissionName;
} }
public void SetDisplayName([NotNull] string displayName) public void SetDisplayName([NotNull] string displayName)

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

@ -11,6 +11,7 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.CmsKit.EntityFrameworkCore; using Volo.CmsKit.EntityFrameworkCore;
using Volo.CmsKit.MarkedItems;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
using Volo.CmsKit.Users; using Volo.CmsKit.Users;
@ -18,12 +19,15 @@ namespace Volo.CmsKit.Blogs;
public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogPost, Guid>, IBlogPostRepository public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogPost, Guid>, IBlogPostRepository
{ {
private readonly MarkedItemManager _markedItemManager;
private EntityTagManager _entityTagManager; private EntityTagManager _entityTagManager;
public EfCoreBlogPostRepository( public EfCoreBlogPostRepository(
IDbContextProvider<ICmsKitDbContext> dbContextProvider, IDbContextProvider<ICmsKitDbContext> dbContextProvider,
MarkedItemManager markedItemManager,
EntityTagManager entityTagManager) : base(dbContextProvider) EntityTagManager entityTagManager) : base(dbContextProvider)
{ {
_markedItemManager = markedItemManager;
_entityTagManager = entityTagManager; _entityTagManager = entityTagManager;
} }
@ -50,17 +54,21 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null, Guid? authorId = null,
Guid? tagId = null, Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null, BlogPostStatus? statusFilter = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
List<string> entityIdFilters = null; var tagFilteredEntityIds = tagId.HasValue
if (tagId.HasValue) ? await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken)
{ : null;
entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken);
} var favoriteUserFilteredEntityIds = favoriteUserId.HasValue
? await _markedItemManager.GetEntityIdsFilteredByUserAsync(favoriteUserId.Value, BlogPostConsts.EntityType)
: null;
var queryable = (await GetDbSetAsync()) var queryable = (await GetDbSetAsync())
.WhereIf(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) .WhereIf(tagFilteredEntityIds != null, x => tagFilteredEntityIds.Contains(x.Id.ToString()))
.WhereIf(favoriteUserFilteredEntityIds != null, x => favoriteUserFilteredEntityIds.Contains(x.Id.ToString()))
.WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId)
.WhereIf(statusFilter.HasValue, x => x.Status == statusFilter) .WhereIf(statusFilter.HasValue, x => x.Status == statusFilter)
@ -75,6 +83,7 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null, Guid? authorId = null,
Guid? tagId = null, Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null, BlogPostStatus? statusFilter = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,
int skipCount = 0, int skipCount = 0,
@ -86,14 +95,17 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
var blogPostsDbSet = dbContext.Set<BlogPost>(); var blogPostsDbSet = dbContext.Set<BlogPost>();
var usersDbSet = dbContext.Set<CmsUser>(); var usersDbSet = dbContext.Set<CmsUser>();
List<string> entityIdFilters = null; var tagFilteredEntityIds = tagId.HasValue
if (tagId.HasValue) ? await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken)
{ : null;
entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken);
} var favoriteUserFilteredEntityIds = favoriteUserId.HasValue
? await _markedItemManager.GetEntityIdsFilteredByUserAsync(favoriteUserId.Value, BlogPostConsts.EntityType)
: null;
var queryable = (await GetDbSetAsync()) var queryable = (await GetDbSetAsync())
.WhereIf(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) .WhereIf(tagFilteredEntityIds != null, x => tagFilteredEntityIds.Contains(x.Id.ToString()))
.WhereIf(favoriteUserFilteredEntityIds != null, x => favoriteUserFilteredEntityIds.Contains(x.Id.ToString()))
.WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId)

2
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs

@ -261,6 +261,8 @@ public static class CmsKitDbContextModelCreatingExtensions
b.Property(x => x.DisplayName).IsRequired().HasMaxLength(MenuItemConsts.MaxDisplayNameLength); b.Property(x => x.DisplayName).IsRequired().HasMaxLength(MenuItemConsts.MaxDisplayNameLength);
b.Property(x => x.Url).IsRequired().HasMaxLength(MenuItemConsts.MaxUrlLength); b.Property(x => x.Url).IsRequired().HasMaxLength(MenuItemConsts.MaxUrlLength);
b.Property(x => x.RequiredPermissionName).HasMaxLength(MenuItemConsts.MaxRequiredPermissionNameLength);
}); });
} }
else else

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

@ -12,6 +12,7 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.MarkedItems;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
using Volo.CmsKit.Users; using Volo.CmsKit.Users;
@ -19,10 +20,15 @@ namespace Volo.CmsKit.MongoDB.Blogs;
public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, BlogPost, Guid>, IBlogPostRepository public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, BlogPost, Guid>, IBlogPostRepository
{ {
private readonly MarkedItemManager _markedItemManager;
private EntityTagManager _entityTagManager; private EntityTagManager _entityTagManager;
public MongoBlogPostRepository(IMongoDbContextProvider<CmsKitMongoDbContext> dbContextProvider, EntityTagManager entityTagManager) : base( public MongoBlogPostRepository(
IMongoDbContextProvider<CmsKitMongoDbContext> dbContextProvider,
MarkedItemManager markedItemManager,
EntityTagManager entityTagManager) : base(
dbContextProvider) dbContextProvider)
{ {
_markedItemManager = markedItemManager;
_entityTagManager = entityTagManager; _entityTagManager = entityTagManager;
} }
@ -48,15 +54,19 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null, Guid? authorId = null,
Guid? tagId = null, Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null, BlogPostStatus? statusFilter = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
cancellationToken = GetCancellationToken(cancellationToken); cancellationToken = GetCancellationToken(cancellationToken);
var entityIdFilters = await GetEntityIdsByTagId(tagId, cancellationToken); var tagFilteredEntityIds = await GetEntityIdsByTagId(tagId, cancellationToken);
var favoriteUserFilteredEntityIds = await GetFavoriteEntityIdsByUserId(favoriteUserId, cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken)) return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(entityIdFilters.Any(), x => entityIdFilters.Contains(x.Id)) .WhereIf<BlogPost, IMongoQueryable<BlogPost>>(tagFilteredEntityIds.Any(), x => tagFilteredEntityIds.Contains(x.Id))
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(favoriteUserFilteredEntityIds.Any(), x => favoriteUserFilteredEntityIds.Contains(x.Id))
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf<BlogPost, IMongoQueryable<BlogPost>>(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(blogId.HasValue, x => x.BlogId == blogId) .WhereIf<BlogPost, IMongoQueryable<BlogPost>>(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(authorId.HasValue, x => x.AuthorId == authorId) .WhereIf<BlogPost, IMongoQueryable<BlogPost>>(authorId.HasValue, x => x.AuthorId == authorId)
@ -69,6 +79,7 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null, Guid? authorId = null,
Guid? tagId = null, Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null, BlogPostStatus? statusFilter = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,
int skipCount = 0, int skipCount = 0,
@ -79,12 +90,15 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
var dbContext = await GetDbContextAsync(cancellationToken); var dbContext = await GetDbContextAsync(cancellationToken);
var blogPostQueryable = await GetQueryableAsync(); var blogPostQueryable = await GetQueryableAsync();
var entityIdFilters = await GetEntityIdsByTagId(tagId, cancellationToken); var tagFilteredEntityIds = await GetEntityIdsByTagId(tagId, cancellationToken);
var favoriteUserFilteredEntityIds = await GetFavoriteEntityIdsByUserId(favoriteUserId, cancellationToken);
var usersQueryable = dbContext.Collection<CmsUser>().AsQueryable(); var usersQueryable = dbContext.Collection<CmsUser>().AsQueryable();
var queryable = blogPostQueryable var queryable = blogPostQueryable
.WhereIf(entityIdFilters.Any(), x => entityIdFilters.Contains(x.Id)) .WhereIf(tagFilteredEntityIds.Any(), x => tagFilteredEntityIds.Contains(x.Id))
.WhereIf(favoriteUserFilteredEntityIds.Any(), x => favoriteUserFilteredEntityIds.Contains(x.Id))
.WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId)
@ -132,6 +146,28 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
return entityIdFilters; return entityIdFilters;
} }
protected virtual async Task<List<Guid>> GetFavoriteEntityIdsByUserId(Guid? userId, CancellationToken cancellationToken)
{
var entityIdFilters = new List<Guid>();
if (!userId.HasValue)
{
return entityIdFilters;
}
var entityIds =
await _markedItemManager.GetEntityIdsFilteredByUserAsync(userId.Value, BlogPostConsts.EntityType, CurrentTenant.Id, cancellationToken);
foreach (var entityId in entityIds)
{
if (Guid.TryParse(entityId, out var parsedEntityId))
{
entityIdFilters.Add(parsedEntityId);
}
}
return entityIdFilters;
}
public virtual async Task<bool> SlugExistsAsync(Guid blogId, [NotNull] string slug, public virtual async Task<bool> SlugExistsAsync(Guid blogId, [NotNull] string slug,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {

1
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs

@ -8,4 +8,5 @@ public class BlogPostGetListInput : PagedAndSortedResultRequestDto
public Guid? AuthorId { get; set; } public Guid? AuthorId { get; set; }
public Guid? TagId { get; set; } public Guid? TagId { get; set; }
public bool? FilterOnFavorites { get; set; }
} }

13
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs

@ -54,7 +54,10 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
{ {
var blog = await BlogRepository.GetBySlugAsync(blogSlug); var blog = await BlogRepository.GetBySlugAsync(blogSlug);
Guid? favoriteUserId = await GetFavoriteUserIdAsync(input.FilterOnFavorites);
var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.AuthorId, input.TagId, var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.AuthorId, input.TagId,
favoriteUserId,
BlogPostStatus.Published, input.MaxResultCount, BlogPostStatus.Published, input.MaxResultCount,
input.SkipCount, input.Sorting); input.SkipCount, input.Sorting);
@ -100,4 +103,14 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
return tag.Name; return tag.Name;
} }
protected virtual async Task<Guid?> GetFavoriteUserIdAsync(bool? filterOnFavorites)
{
if (!filterOnFavorites.GetValueOrDefault() || !CurrentUser.IsAuthenticated)
{
return null;
}
return CurrentUser.GetId();
}
} }

12
modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs

@ -1,7 +1,9 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation;
@ -55,7 +57,7 @@ public class CmsKitPublicMenuContributor : IMenuContributor
private ApplicationMenuItem CreateApplicationMenuItem(MenuItemDto menuItem) private ApplicationMenuItem CreateApplicationMenuItem(MenuItemDto menuItem)
{ {
return new ApplicationMenuItem( var menu = new ApplicationMenuItem(
menuItem.DisplayName, menuItem.DisplayName,
menuItem.DisplayName, menuItem.DisplayName,
menuItem.Url, menuItem.Url,
@ -65,5 +67,11 @@ public class CmsKitPublicMenuContributor : IMenuContributor
menuItem.ElementId, menuItem.ElementId,
menuItem.CssClass menuItem.CssClass
); );
if (!menuItem.RequiredPermissionName.IsNullOrWhiteSpace())
{
menu.RequirePermissions(menuItem.RequiredPermissionName);
}
return menu;
} }
} }

2
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/MarkedItemToggle/default.css

@ -2,6 +2,6 @@
} }
.cms-markedItem-area i { .cms-markedItem-area i {
font-size: 1.5em; font-size: 1.05rem;
cursor: pointer; cursor: pointer;
} }

8
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Modals/Login/LoginModal.cshtml

@ -5,7 +5,8 @@
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Modals.Login.LoginModalModel @model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Modals.Login.LoginModalModel
@{ @{
Layout = null; Layout = null;
var message = String.IsNullOrEmpty(Model.ViewModel.Message) ? L["CmsKit:Modals:LoginModalDefaultMessage"] : Model.ViewModel.Message; var message = String.IsNullOrEmpty(Model.ViewModel.Message) ? L["CmsKit:Modals:LoginModalDefaultMessage"] :
Model.ViewModel.Message;
} }
<abp-modal centered="true"> <abp-modal centered="true">
<abp-modal-header title="@L["CmsKit:Modals:YouAreNotAuthenticated"]"> <abp-modal-header title="@L["CmsKit:Modals:YouAreNotAuthenticated"]">
@ -15,8 +16,9 @@
<h4> <h4>
@message @message
</h4> </h4>
<br />
<a href="@Model.ViewModel.LoginUrl" class="btn btn-secondary">@L["CmsKit:Modals:Login"]</a>
</div> </div>
</abp-modal-body> </abp-modal-body>
<abp-modal-footer class="d-flex justify-content-center">
<a href="@Model.ViewModel.LoginUrl" class="btn btn-secondary">@L["CmsKit:Modals:Login"]</a>
</abp-modal-footer>
</abp-modal> </abp-modal>

43
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml

@ -1,6 +1,10 @@
@page @page
@using Volo.CmsKit.Blogs
@using Volo.CmsKit.Public.Web.Pages @using Volo.CmsKit.Public.Web.Pages
@using Volo.Abp.GlobalFeatures
@using Volo.CmsKit.GlobalFeatures
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.MarkedItemToggle
@using Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs @using Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs
@using Volo.CmsKit.Web @using Volo.CmsKit.Web
@ -8,6 +12,11 @@
@model IndexModel @model IndexModel
@{
const string dummyImageSource = "/cms-kit/dummy-placeholder-320x180.png";
var isMarkedItemFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<MarkedItemsFeature>() && Model.MarkedItemsFeature?.IsEnabled == true;
}
@section styles { @section styles {
<abp-style src="/Pages/Public/CmsKit/Blogs/index.css" /> <abp-style src="/Pages/Public/CmsKit/Blogs/index.css" />
} }
@ -15,13 +24,13 @@
@section scripts { @section scripts {
<abp-script-bundle> <abp-script-bundle>
<abp-script src="/Pages/Public/CmsKit/Blogs/index.js" /> <abp-script src="/Pages/Public/CmsKit/Blogs/index.js" />
@if (isMarkedItemFeatureEnabled)
{
<abp-script src="/Pages/Public/CmsKit/Blogs/filter-on-favorites.js" />
}
</abp-script-bundle> </abp-script-bundle>
} }
@{
const string dummyImageSource = "/cms-kit/dummy-placeholder-320x180.png";
}
@if (Model.AuthorId.HasValue) @if (Model.AuthorId.HasValue)
{ {
<abp-row id="blogs-filter-area"> <abp-row id="blogs-filter-area">
@ -61,11 +70,37 @@
@if (Model.Blogs.TotalCount > 0) @if (Model.Blogs.TotalCount > 0)
{ {
@if (isMarkedItemFeatureEnabled)
{
var filterOnFavorties = Model.FilterOnFavorites.GetValueOrDefault();
string icon = filterOnFavorties ? "heart" : "heart-o";
<abp-button class="favorite-button badge text-bg-light my-2 border-light-subtle"
button-type="Light"
icon="@icon text-danger"
text="@L["FilterOnFavorites"]"
filter-on-favorites="@filterOnFavorties">
</abp-button>
}
<abp-row id="blogs-container"> <abp-row id="blogs-container">
@foreach (var blog in Model.Blogs.Items) @foreach (var blog in Model.Blogs.Items)
{ {
<abp-column size="_12" size-md="_6" size-lg="_4"> <abp-column size="_12" size-md="_6" size-lg="_4">
<abp-card> <abp-card>
@if (isMarkedItemFeatureEnabled)
{
<div class="position-absolute top-0 end-0 m-3 z-3">
<abp-button button-type="Light"
class="favorite-toggle rounded-circle shadow-sm d-flex align-items-center justify-content-center"
abp-tooltip="@L["ToggleFavorite"]">
@await Component.InvokeAsync(typeof(MarkedItemToggleViewComponent), new
{
entityId = blog.Id.ToString(),
entityType = BlogPostConsts.EntityType
})
</abp-button>
</div>
}
@if (blog.CoverImageMediaId != null) @if (blog.CoverImageMediaId != null)
{ {
<img src="/api/cms-kit/media/@blog.CoverImageMediaId" class="card-img-top" onerror="this.src='@dummyImageSource'" /> <img src="/api/cms-kit/media/@blog.CoverImageMediaId" class="card-img-top" onerror="this.src='@dummyImageSource'" />

24
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs

@ -1,9 +1,13 @@
using System; using System;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.Contents; using Volo.CmsKit.Contents;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users; using Volo.CmsKit.Users;
@ -22,6 +26,9 @@ public class IndexModel : CmsKitPublicPageModelBase
[BindProperty(SupportsGet = true)] [BindProperty(SupportsGet = true)]
public Guid? AuthorId { get; set; } public Guid? AuthorId { get; set; }
[BindProperty(SupportsGet = true)]
public bool? FilterOnFavorites { get; set; }
[BindProperty(SupportsGet = true)] [BindProperty(SupportsGet = true)]
public Guid? TagId { get; set; } public Guid? TagId { get; set; }
@ -32,12 +39,17 @@ public class IndexModel : CmsKitPublicPageModelBase
public CmsUserDto SelectedAuthor { get; protected set; } public CmsUserDto SelectedAuthor { get; protected set; }
public string FilteredTagName { get; protected set; } public string FilteredTagName { get; protected set; }
public BlogFeatureDto MarkedItemsFeature { get; private set; }
protected IBlogPostPublicAppService BlogPostPublicAppService { get; } protected IBlogPostPublicAppService BlogPostPublicAppService { get; }
public IBlogFeatureAppService BlogFeatureAppService { get; }
public IndexModel(IBlogPostPublicAppService blogPostPublicAppService) public IndexModel(
IBlogPostPublicAppService blogPostPublicAppService,
IBlogFeatureAppService blogFeatureAppService)
{ {
BlogPostPublicAppService = blogPostPublicAppService; BlogPostPublicAppService = blogPostPublicAppService;
BlogFeatureAppService = blogFeatureAppService;
} }
public virtual async Task<IActionResult> OnGetAsync() public virtual async Task<IActionResult> OnGetAsync()
@ -49,7 +61,8 @@ public class IndexModel : CmsKitPublicPageModelBase
SkipCount = PageSize * (CurrentPage - 1), SkipCount = PageSize * (CurrentPage - 1),
MaxResultCount = PageSize, MaxResultCount = PageSize,
AuthorId = AuthorId, AuthorId = AuthorId,
TagId = TagId TagId = TagId,
FilterOnFavorites = FilterOnFavorites
}); });
if (AuthorId != null) if (AuthorId != null)
@ -62,6 +75,13 @@ public class IndexModel : CmsKitPublicPageModelBase
FilteredTagName = await BlogPostPublicAppService.GetTagNameAsync(TagId.Value); FilteredTagName = await BlogPostPublicAppService.GetTagNameAsync(TagId.Value);
} }
if (GlobalFeatureManager.Instance.IsEnabled<MarkedItemsFeature>() &&
Blogs.Items.Any())
{
var blogId = Blogs.Items.First().BlogId;
MarkedItemsFeature = await BlogFeatureAppService.GetOrDefaultAsync(blogId, GlobalFeatures.MarkedItemsFeature.Name);
}
return Page(); return Page();
} }
} }

27
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/filter-on-favorites.js

@ -0,0 +1,27 @@
$(function () {
var l = abp.localization.getResource('CmsKit');
let filterButton = $('.favorite-button');
let filterOnFavorites = filterButton.attr('filter-on-favorites');
const loginModal = new abp.ModalManager(abp.appPath + 'CmsKit/Shared/Modals/Login/LoginModal');
$('.favorite-button').on('click', function () {
if (!abp.currentUser.isAuthenticated) {
const currentPageRoute = window.location.pathname;
loginModal.open({ message: l("FavoritesFilterMessage"), returnUrl: currentPageRoute });
return;
}
let currentUrl = new URL(window.location.href);
let searchParams = currentUrl.searchParams;
// Toggle the 'filterOnFavorites' parameter
if (filterOnFavorites) {
searchParams.delete('filterOnFavorites');
} else {
searchParams.set('filterOnFavorites', 'true');
}
window.location.href = currentUrl.pathname + '?' + searchParams.toString();
});
});

5
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.css

@ -17,4 +17,9 @@
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
}
.favorite-toggle {
width: 40px;
height: 40px;
} }

16
modules/docs/.abpstudio/state.json

@ -0,0 +1,16 @@
{
"selectedKubernetesProfile": null,
"solutionRunner": {
"selectedProfile": "Default",
"targetFrameworks": [],
"applicationsStartingWithoutBuild": [],
"applicationBatchStartStates": [
{
"profile": "Default",
"applicationOrFolder": "VoloDocs.Web",
"value": 0
}
],
"folderBatchStartStates": []
}
}

11
modules/docs/Default.abprun.json

@ -0,0 +1,11 @@
{
"metadata": {},
"applications": {
"VoloDocs.Web": {
"type": "dotnet-project",
"path": "app/VoloDocs.Web/VoloDocs.Web.csproj",
"launchUrl": "https://localhost:5001",
"kubernetesService": null
}
}
}

6
modules/docs/Volo.Docs.abpsln

@ -3,5 +3,11 @@
"Volo.Docs": { "Volo.Docs": {
"path": "Volo.Docs.abpmdl" "path": "Volo.Docs.abpmdl"
} }
},
"id": "c1d848e0-0b53-461b-824a-8533ba1fd82b",
"runProfiles": {
"Default": {
"path": "Default.abprun.json"
}
} }
} }

20
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20240707104226_Initial.Designer.cs → modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20241231072012_Initial.Designer.cs

@ -13,7 +13,7 @@ using VoloDocs.EntityFrameworkCore;
namespace Migrations namespace Migrations
{ {
[DbContext(typeof(VoloDocsDbContext))] [DbContext(typeof(VoloDocsDbContext))]
[Migration("20240707104226_Initial")] [Migration("20241231072012_Initial")]
partial class Initial partial class Initial
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -22,7 +22,7 @@ namespace Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("ProductVersion", "8.0.4") .HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128); .HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -40,6 +40,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)") .HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp"); .HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<string>("Description") b.Property<string>("Description")
.HasMaxLength(256) .HasMaxLength(256)
.HasColumnType("nvarchar(256)"); .HasColumnType("nvarchar(256)");
@ -116,6 +120,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)") .HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp"); .HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<int>("EntityVersion") b.Property<int>("EntityVersion")
.HasColumnType("int"); .HasColumnType("int");
@ -281,9 +289,13 @@ namespace Migrations
.HasMaxLength(64) .HasMaxLength(64)
.HasColumnType("nvarchar(64)"); .HasColumnType("nvarchar(64)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("IpAddresses") b.Property<string>("IpAddresses")
.HasMaxLength(256) .HasMaxLength(2048)
.HasColumnType("nvarchar(256)"); .HasColumnType("nvarchar(2048)");
b.Property<DateTime?>("LastAccessed") b.Property<DateTime?>("LastAccessed")
.HasColumnType("datetime2"); .HasColumnType("datetime2");

7
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20240707104226_Initial.cs → modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20241231072012_Initial.cs

@ -23,6 +23,7 @@ namespace Migrations
RegexDescription = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), RegexDescription = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
Description = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), Description = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ValueType = table.Column<int>(type: "int", nullable: false), ValueType = table.Column<int>(type: "int", nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false), ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false) ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false)
}, },
@ -137,6 +138,7 @@ namespace Migrations
IsStatic = table.Column<bool>(type: "bit", nullable: false), IsStatic = table.Column<bool>(type: "bit", nullable: false),
IsPublic = table.Column<bool>(type: "bit", nullable: false), IsPublic = table.Column<bool>(type: "bit", nullable: false),
EntityVersion = table.Column<int>(type: "int", nullable: false), EntityVersion = table.Column<int>(type: "int", nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false), ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false) ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false)
}, },
@ -181,9 +183,10 @@ namespace Migrations
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
ClientId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true), ClientId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
IpAddresses = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), IpAddresses = table.Column<string>(type: "nvarchar(2048)", maxLength: 2048, nullable: true),
SignedIn = table.Column<DateTime>(type: "datetime2", nullable: false), SignedIn = table.Column<DateTime>(type: "datetime2", nullable: false),
LastAccessed = table.Column<DateTime>(type: "datetime2", nullable: true) LastAccessed = table.Column<DateTime>(type: "datetime2", nullable: true),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true)
}, },
constraints: table => constraints: table =>
{ {

18
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs

@ -19,7 +19,7 @@ namespace Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("ProductVersion", "8.0.4") .HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128); .HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -37,6 +37,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)") .HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp"); .HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<string>("Description") b.Property<string>("Description")
.HasMaxLength(256) .HasMaxLength(256)
.HasColumnType("nvarchar(256)"); .HasColumnType("nvarchar(256)");
@ -113,6 +117,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)") .HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp"); .HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<int>("EntityVersion") b.Property<int>("EntityVersion")
.HasColumnType("int"); .HasColumnType("int");
@ -278,9 +286,13 @@ namespace Migrations
.HasMaxLength(64) .HasMaxLength(64)
.HasColumnType("nvarchar(64)"); .HasColumnType("nvarchar(64)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("IpAddresses") b.Property<string>("IpAddresses")
.HasMaxLength(256) .HasMaxLength(2048)
.HasColumnType("nvarchar(256)"); .HasColumnType("nvarchar(2048)");
b.Property<DateTime?>("LastAccessed") b.Property<DateTime?>("LastAccessed")
.HasColumnType("datetime2"); .HasColumnType("datetime2");

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

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin.Documents namespace Volo.Docs.Admin.Documents
{ {
@ -21,5 +22,7 @@ namespace Volo.Docs.Admin.Documents
Task ReindexAsync(Guid documentId); Task ReindexAsync(Guid documentId);
Task<List<DocumentInfoDto>> GetFilterItemsAsync(); Task<List<DocumentInfoDto>> GetFilterItemsAsync();
Task<List<ProjectWithoutDetailsDto>> GetProjectsAsync();
} }
} }

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

@ -8,6 +8,7 @@ using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Caching; using Volo.Docs.Caching;
using Volo.Docs.Documents; using Volo.Docs.Documents;
using Volo.Docs.Documents.FullSearch.Elastic; using Volo.Docs.Documents.FullSearch.Elastic;
@ -220,6 +221,12 @@ namespace Volo.Docs.Admin.Documents
return ObjectMapper.Map<List<DocumentInfo>, List<DocumentInfoDto>>(documents); return ObjectMapper.Map<List<DocumentInfo>, List<DocumentInfoDto>>(documents);
} }
public virtual async Task<List<ProjectWithoutDetailsDto>> GetProjectsAsync()
{
var projects = await _projectRepository.GetListWithoutDetailsAsync();
return ObjectMapper.Map<List<ProjectWithoutDetails>, List<ProjectWithoutDetailsDto>>(projects);
}
private async Task UpdateDocumentUpdateInfoCache(Document document) private async Task UpdateDocumentUpdateInfoCache(Document document)
{ {

6
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentsAdminClientProxy.Generated.cs

@ -9,6 +9,7 @@ using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.ClientProxying; using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Http.Modeling; using Volo.Abp.Http.Modeling;
using Volo.Docs.Admin.Documents; using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
// ReSharper disable once CheckNamespace // ReSharper disable once CheckNamespace
namespace Volo.Docs.Admin; namespace Volo.Docs.Admin;
@ -69,4 +70,9 @@ public partial class DocumentsAdminClientProxy : ClientProxyBase<IDocumentAdminA
{ {
return await RequestAsync<List<DocumentInfoDto>>(nameof(GetFilterItemsAsync)); return await RequestAsync<List<DocumentInfoDto>>(nameof(GetFilterItemsAsync));
} }
public virtual async Task<List<ProjectWithoutDetailsDto>> GetProjectsAsync()
{
return await RequestAsync<List<ProjectWithoutDetailsDto>>(nameof(GetProjectsAsync));
}
} }

23
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/docs-admin-generate-proxy.json → modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/docs-admin-generate-proxy.json

@ -125,6 +125,14 @@
"type": "System.Collections.Generic.List<Volo.Docs.Admin.Documents.DocumentInfoDto>", "type": "System.Collections.Generic.List<Volo.Docs.Admin.Documents.DocumentInfoDto>",
"typeSimple": "[Volo.Docs.Admin.Documents.DocumentInfoDto]" "typeSimple": "[Volo.Docs.Admin.Documents.DocumentInfoDto]"
} }
},
{
"name": "GetProjectsAsync",
"parametersOnMethod": [],
"returnValue": {
"type": "System.Collections.Generic.List<Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto>",
"typeSimple": "[Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto]"
}
} }
] ]
} }
@ -558,6 +566,21 @@
}, },
"allowAnonymous": null, "allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentAdminAppService" "implementFrom": "Volo.Docs.Admin.Documents.IDocumentAdminAppService"
},
"GetProjectsAsync": {
"uniqueName": "GetProjectsAsync",
"name": "GetProjectsAsync",
"httpMethod": "GET",
"url": "api/docs/admin/documents/GetProjects",
"supportedVersions": [],
"parametersOnMethod": [],
"parameters": [],
"returnValue": {
"type": "System.Collections.Generic.List<Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto>",
"typeSimple": "[Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto]"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentAdminAppService"
} }
} }
}, },

14
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo.Docs.Admin.HttpApi.Client.abppkg

@ -1,3 +1,15 @@
{ {
"role": "lib.http-api-client" "role": "lib.http-api-client",
"proxies": {
"csharp": {
"VoloDocs.Web-docs-admin": {
"applicationName": "VoloDocs.Web",
"module": "docs-admin",
"url": "https://localhost:5001",
"folder": "ClientProxies\\Volo\\Docs\\Admin",
"serviceType": "application",
"withoutContracts": true
}
}
}
} }

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

@ -7,6 +7,7 @@ using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Docs.Admin.Documents; using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin namespace Volo.Docs.Admin
{ {
@ -71,5 +72,12 @@ namespace Volo.Docs.Admin
{ {
return await _documentAdminAppService.GetFilterItemsAsync(); return await _documentAdminAppService.GetFilterItemsAsync();
} }
[HttpGet]
[Route("GetProjects")]
public virtual Task<List<ProjectWithoutDetailsDto>> GetProjectsAsync()
{
return _documentAdminAppService.GetProjectsAsync();
}
} }
} }

11
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs

@ -2,23 +2,24 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects; using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin.Pages.Docs.Admin.Documents; namespace Volo.Docs.Admin.Pages.Docs.Admin.Documents;
[Authorize(DocsAdminPermissions.Projects.Default)] [Authorize(DocsAdminPermissions.Documents.Default)]
public class IndexModel : DocsAdminPageModel public class IndexModel : DocsAdminPageModel
{ {
private readonly IProjectAdminAppService _projectAdminAppService; private readonly IDocumentAdminAppService _documentAdminAppService;
public List<ProjectWithoutDetailsDto> Projects { get; set; } public List<ProjectWithoutDetailsDto> Projects { get; set; }
public IndexModel(IProjectAdminAppService projectAdminAppService) public IndexModel(IDocumentAdminAppService documentAdminAppService)
{ {
_projectAdminAppService = projectAdminAppService; _documentAdminAppService = documentAdminAppService;
} }
public virtual async Task<IActionResult> OnGet() public virtual async Task<IActionResult> OnGet()
{ {
Projects = await _projectAdminAppService.GetListWithoutDetailsAsync(); Projects = await _documentAdminAppService.GetProjectsAsync();
return Page(); return Page();
} }
} }

13
modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.abppkg

@ -1,3 +1,14 @@
{ {
"role": "lib.mvc" "role": "lib.mvc",
"proxies": {
"Javascript": {
"VoloDocs.Web-docs-admin": {
"applicationName": "VoloDocs.Web",
"module": "docs-admin",
"url": "https://localhost:5001",
"output": "wwwroot/client-proxies",
"serviceType": "application"
}
}
}
} }

7
modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js

@ -68,6 +68,13 @@
}, ajaxParams)); }, ajaxParams));
}; };
volo.docs.admin.documentsAdmin.getProjects = function(ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/GetProjects',
type: 'GET'
}, ajaxParams));
};
})(); })();
// controller volo.docs.admin.projectsAdmin // controller volo.docs.admin.projectsAdmin

5
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js

@ -364,6 +364,11 @@ var doc = doc || {};
var initLazyExpandNavigation = function(){ var initLazyExpandNavigation = function(){
$("li .lazy-expand").off('click'); $("li .lazy-expand").off('click');
$("li .lazy-expand a").on('click', function(e){
if($(this).attr("href") !== "javascript:;"){
e.stopPropagation();
}
});
$("li .lazy-expand").on('click', function(){ $("li .lazy-expand").on('click', function(){
var $this = $(this); var $this = $(this);
if($this.has("ul").length > 0){ if($this.has("ul").length > 0){

Loading…
Cancel
Save