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",
"ManageYourProfile": "Manage your profile",
"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",
"EditLicense{0}": "Edit {0} License",
"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<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 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 Guid? PageId { get; set; }
public string RequiredPermissionName { 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 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,
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);

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

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
@ -23,15 +25,18 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
protected MenuItemManager MenuManager { get; }
protected IMenuItemRepository MenuItemRepository { get; }
protected IPageRepository PageRepository { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
public MenuItemAdminAppService(
MenuItemManager menuManager,
IMenuItemRepository menuRepository,
IPageRepository pageRepository)
IPageRepository pageRepository,
IPermissionDefinitionManager permissionDefinitionManager)
{
MenuManager = menuManager;
MenuItemRepository = menuRepository;
PageRepository = pageRepository;
PermissionDefinitionManager = permissionDefinitionManager;
}
public virtual async Task<ListResultDto<MenuItemDto>> GetListAsync()
@ -70,7 +75,8 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
input.Target,
input.ElementId,
input.CssClass,
CurrentTenant.Id
CurrentTenant.Id,
input.RequiredPermissionName
);
if (input.PageId.HasValue)
@ -103,6 +109,7 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
menuItem.Target = input.Target;
menuItem.ElementId = input.ElementId;
menuItem.CssClass = input.CssClass;
menuItem.RequiredPermissionName = input.RequiredPermissionName;
menuItem.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
input.MapExtraPropertiesTo(menuItem);
await MenuItemRepository.UpdateAsync(menuItem);
@ -138,4 +145,21 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
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 }
});
}
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",
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": false,
"isOptional": true,
"defaultValue": null
}
],
@ -2167,6 +2167,23 @@
"type": "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,
"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);
}
[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.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.Icon"/>
<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 AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending;
@ -32,7 +33,6 @@ public class CreateModalModel : CmsKitAdminPageModel
public virtual async Task OnGetAsync(Guid? parentId)
{
ViewModel.ParentId = parentId;
IsPageFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<PagesFeature>()
&& await FeatureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable);
}
@ -72,6 +72,8 @@ public class CreateModalModel : CmsKitAdminPageModel
public string ElementId { 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"/>
<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.Icon"/>
<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.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using AutoMapper;
@ -28,6 +29,8 @@ public class UpdateModalModel : CmsKitAdminPageModel
public Guid Id { get; set; }
public bool IsPageFeatureEnabled { get; set; }
public IReadOnlyList<PermissionLookupDto> Permissions { get; set; }
public UpdateModalModel(IMenuItemAdminAppService menuAdminAppService, IFeatureChecker featureChecker)
{
@ -39,7 +42,7 @@ public class UpdateModalModel : CmsKitAdminPageModel
public async Task OnGetAsync()
{
var menuItemDto = await MenuAdminAppService.GetAsync(Id);
Permissions = (await MenuAdminAppService.GetPermissionLookupAsync(new PermissionLookupInputDto())).Items;
IsPageFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<PagesFeature>()
&& await FeatureChecker.IsEnabledAsync(CmsKitFeatures.PageEnable);
@ -76,6 +79,8 @@ public class UpdateModalModel : CmsKitAdminPageModel
public Guid? PageId { get; set; }
public string? PageTitle { get; set; }
public string RequiredPermissionName { get; set; }
[HiddenInput]
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 $displayName = $('#ViewModel_DisplayName');
var $menuItemForm = $('#menu-item-form');
var $selectRequiredPermission = $('#requiredPermissionName');
$pageId.on('change', function (params) {
$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) {
$('[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 $displayName = $('#ViewModel_DisplayName');
var $menuItemForm = $('#menu-item-form');
var $selectRequiredPermission = $('#requiredPermissionName');
$pageId.on('change', function (params) {
$url.prop('disabled', $pageId.val());
@ -21,6 +22,52 @@ $(function () {
$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) {
$('[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 Guid? PageId { get; set; }
public string RequiredPermissionName { 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.Reactions": "تفاعلات",
"CmsKit.Tags": "العلامات",
"CmsKit.MarkedItems": "العناصر المميزة",
"CmsKit:0002": "المحتوى موجود بالفعل!",
"CmsKit:0003": "الكيان {0} غير قابل للعلامة.",
"CmsKit:Blog:0001": "slug المحدد ({Slug}) موجود بالفعل!",
@ -28,6 +29,9 @@
"CmsKit:MarkedItem:0001": "لا يمكن أن تمييز الكيان {EntityType}.",
"CmsKit:MarkedItem:0002": "لم يتم العثور على تعريف لنوع الكيان '{EntityType}'.",
"CmsKit:MarkedItem:0003": "يوجد بالفعل تعريف لنوع الكيان '{EntityType}'. يجب أن يكون لكل نوع كيان تعريف واحد فقط.",
"ToggleFavorite": "تفضيل/إلغاء",
"FavoritesFilterMessage": "يرجى تسجيل الدخول لتصفية المفضلات الخاصة بك",
"FilterOnFavorites": "تصفية المفضلات",
"CmsKit:Tag:0002": "الكيان غير قابل للوسم!",
"CommentAuthorizationExceptionMessage": "هذه التعليقات غير مسموح بها للعرض العام.",
"CommentDeletionConfirmationMessage": "سيتم حذف هذا التعليق وجميع الردود!",
@ -241,6 +245,7 @@
"ChooseAnActionForBlog": "اختر إجراءً للمدونة",
"AssignBlogPostsToOtherBlog": "تعيين مشاركات المدونة إلى مدونة أخرى",
"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",
"AssignBlogPostsToOtherBlog": "Přiřaďte blogové příspěvky k jinému blogu",
"SelectAnBlogToAssign": "Vyberte blog, ke kterému chcete přiřadit blogové příspěvky",
"DeleteAllBlogPostsOfThisBlog": "Smazat všechny blogové příspěvky tohoto blogu"
"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",
"AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen",
"SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen",
"DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen"
"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",
"AssignBlogPostsToOtherBlog": "Blogbeiträge einem anderen Blog zuweisen",
"SelectAnBlogToAssign": "Wählen Sie einen Blog aus, um Blogbeiträge zuzuweisen",
"DeleteAllBlogPostsOfThisBlog": "Alle Blogbeiträge dieses Blogs löschen"
"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": "Επιλέξτε μια ενέργεια για το ιστολόγιο",
"AssignBlogPostsToOtherBlog": "Ανάθεση αναρτήσεων ιστολογίου σε άλλο ιστολόγιο",
"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",
"AssignBlogPostsToOtherBlog": "Assign blog posts to another blog",
"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.Reactions": "Reactions",
"CmsKit.Tags": "Tags",
"CmsKit.MarkedItems": "Marked Items",
"CmsKit:0002": "Content already exists!",
"CmsKit:0003": "The entity {0} is not taggable.",
"CmsKit:Blog:0001": "The given slug ({Slug}) already exists!",
@ -27,6 +28,9 @@
"CmsKit:Reaction:0001": "The entity {EntityType} can't have reactions.",
"CmsKit:Tag:0002": "The entity is not taggable!",
"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.",
"CmsKit:Modals:Login": "Login",
"CmsKit:Modals:LoginModalDefaultMessage": "Please login to continue!",
@ -259,6 +263,7 @@
"ChooseAnActionForBlog": "Choose an action for the blog",
"AssignBlogPostsToOtherBlog": "Assign blog posts to another blog",
"SelectAnBlogToAssign": "Select a blog to assign",
"DeleteAllBlogPostsOfThisBlog": "Delete all blog posts of this blog"
"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",
"AssignBlogPostsToOtherBlog": "Asignar publicaciones de blog a otro blog",
"SelectAnBlogToAssign": "Seleccione un blog para asignar publicaciones de blog",
"DeleteAllBlogPostsOfThisBlog": "Eliminar todas las publicaciones de blog de este blog"
"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": "یک عمل برای وبلاگ انتخاب کنید",
"AssignBlogPostsToOtherBlog": "پست های وبلاگ را به وبلاگ دیگری اختصاص دهید",
"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",
"AssignBlogPostsToOtherBlog": "Määritä blogiviestit toiseen blogiin",
"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",
"AssignBlogPostsToOtherBlog": "Attribuer des articles de blog à un autre blog",
"SelectAnBlogToAssign": "Sélectionnez un blog à attribuer",
"DeleteAllBlogPostsOfThisBlog": "Supprimer tous les articles de blog de ce blog"
"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": "ब्लॉग के लिए कोई कार्रवाई चुनें",
"AssignBlogPostsToOtherBlog": "अन्य ब्लॉग को ब्लॉग पोस्ट असाइन करें",
"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",
"AssignBlogPostsToOtherBlog": "Dodijelite postove na blogu drugom blogu",
"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",
"AssignBlogPostsToOtherBlog": "Blogbejegyzések hozzárendelése egy másik bloghoz",
"SelectAnBlogToAssign": "Válasszon egy blogot a hozzárendeléshez",
"DeleteAllBlogPostsOfThisBlog": "Ez a művelet törli az összes blogbejegyzést ebből a blogból. Biztos vagy benne?"
"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",
"AssignBlogPostsToOtherBlog": "Úthluta bloggfærslum til annars bloggs",
"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",
"AssignBlogPostsToOtherBlog": "Assegna i post del blog ad un altro blog",
"SelectAnBlogToAssign": "Seleziona un blog a cui assegnare i post del blog",
"DeleteAllBlogPostsOfThisBlog": "Elimina tutti i post del blog di questo blog"
"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",
"AssignBlogPostsToOtherBlog": "Wijs blogberichten toe aan een andere blog",
"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",
"AssignBlogPostsToOtherBlog": "Przypisz posty na blogu do innego bloga",
"SelectAnBlogToAssign": "Wybierz blog, do którego chcesz przypisać posty na blogu",
"DeleteAllBlogPostsOfThisBlog": "Usuń wszystkie posty na blogu tego bloga"
"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",
"AssignBlogPostsToOtherBlog": "Atribuir postagens de blog a outro blog",
"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",
"AssignBlogPostsToOtherBlog": "Atribuiţi postările de blog la alt blog",
"SelectAnBlogToAssign": "Selectaţi un blog pentru a atribui postările de blog",
"DeleteAllBlogPostsOfThisBlog": "Ştergeţi toate postările de blog ale acestui blog"
"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": "Выберите действие для блога",
"AssignBlogPostsToOtherBlog": "Назначить сообщения в блоге другому блогу",
"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",
"AssignBlogPostsToOtherBlog": "Priradiť blogové príspevky k inému blogu",
"SelectAnBlogToAssign": "Vyberte blog, na ktorý chcete priradiť blogové príspevky",
"DeleteAllBlogPostsOfThisBlog": "Zmazať všetky blogové príspevky tohto blogu"
"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",
"AssignBlogPostsToOtherBlog": "Dodeli objave v blogu drugemu blogu",
"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",
"AssignBlogPostsToOtherBlog": "Tilldela blogginlägg till en annan blogg",
"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",
"AssignBlogPostsToOtherBlog": "Diğer bloglara blog yazıları atayın",
"SelectAnBlogToAssign": "Atanacak bir blog seçin",
"DeleteAllBlogPostsOfThisBlog": "Bu blogun tüm blog yazılarını sil"
"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",
"AssignBlogPostsToOtherBlog": "Gán bài đăng trên blog cho blog khác",
"SelectAnBlogToAssign": "Chọn một blog để gán",
"DeleteAllBlogPostsOfThisBlog": "Xóa tất cả bài đăng trên blog của blog này"
"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": "选择博客的操作",
"AssignBlogPostsToOtherBlog": "将博客文章分配给其他博客",
"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": "選擇部落格的操作",
"AssignBlogPostsToOtherBlog": "將部落格文章分配給其他部落格",
"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 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, RatingsFeature.Name),
new BlogFeature(blogId, TagsFeature.Name),
new BlogFeature(blogId, MarkedItemsFeature.Name),
new BlogFeature(blogId, BlogPostScrollIndexFeature.Name),
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? authorId = null,
Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null,
CancellationToken cancellationToken = default);
@ -22,6 +23,7 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Guid? blogId = null,
Guid? authorId = null,
Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null,
int maxResultCount = int.MaxValue,
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.GlobalFeatures;
using Volo.CmsKit.Localization;
using Volo.CmsKit.MarkedItems;
using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages;
@ -91,6 +92,24 @@ public class CmsKitDomainModule : AbpModule
{
// 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)

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

@ -2,6 +2,8 @@
using JetBrains.Annotations;
using System.Threading.Tasks;
using Volo.Abp;
using System.Collections.Generic;
using System.Threading;
namespace Volo.CmsKit.MarkedItems;
public class MarkedItemManager : CmsKitDomainServiceBase
@ -20,7 +22,7 @@ public class MarkedItemManager : CmsKitDomainServiceBase
public virtual async Task<bool> ToggleUserMarkedItemAsync(
Guid creatorId,
[NotNull] string entityType,
[NotNull] string entityType,
[NotNull] string entityId)
{
Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
@ -49,4 +51,12 @@ public class MarkedItemManager : CmsKitDomainServiceBase
);
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? TenantId { get; protected set; }
public string RequiredPermissionName { get; set; }
protected MenuItem()
{
@ -55,7 +57,8 @@ public class MenuItem : AuditedAggregateRoot<Guid>, IMultiTenant
[CanBeNull] string target = null,
[CanBeNull] string elementId = null,
[CanBeNull] string cssClass = null,
[CanBeNull] Guid? tenantId = null)
[CanBeNull] Guid? tenantId = null,
[CanBeNull] string requiredPermissionName = null)
: base(id)
{
SetDisplayName(displayName);
@ -68,6 +71,7 @@ public class MenuItem : AuditedAggregateRoot<Guid>, IMultiTenant
ElementId = elementId;
CssClass = cssClass;
TenantId = tenantId;
RequiredPermissionName = requiredPermissionName;
}
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.EntityFrameworkCore;
using Volo.CmsKit.EntityFrameworkCore;
using Volo.CmsKit.MarkedItems;
using Volo.CmsKit.Tags;
using Volo.CmsKit.Users;
@ -18,12 +19,15 @@ namespace Volo.CmsKit.Blogs;
public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogPost, Guid>, IBlogPostRepository
{
private readonly MarkedItemManager _markedItemManager;
private EntityTagManager _entityTagManager;
public EfCoreBlogPostRepository(
IDbContextProvider<ICmsKitDbContext> dbContextProvider,
MarkedItemManager markedItemManager,
EntityTagManager entityTagManager) : base(dbContextProvider)
{
_markedItemManager = markedItemManager;
_entityTagManager = entityTagManager;
}
@ -50,17 +54,21 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
Guid? blogId = null,
Guid? authorId = null,
Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null,
CancellationToken cancellationToken = default)
{
List<string> entityIdFilters = null;
if (tagId.HasValue)
{
entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken);
}
var tagFilteredEntityIds = tagId.HasValue
? await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken)
: null;
var favoriteUserFilteredEntityIds = favoriteUserId.HasValue
? await _markedItemManager.GetEntityIdsFilteredByUserAsync(favoriteUserId.Value, BlogPostConsts.EntityType)
: null;
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(authorId.HasValue, x => x.AuthorId == authorId)
.WhereIf(statusFilter.HasValue, x => x.Status == statusFilter)
@ -75,6 +83,7 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
Guid? blogId = null,
Guid? authorId = null,
Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
@ -86,14 +95,17 @@ public class EfCoreBlogPostRepository : EfCoreRepository<ICmsKitDbContext, BlogP
var blogPostsDbSet = dbContext.Set<BlogPost>();
var usersDbSet = dbContext.Set<CmsUser>();
List<string> entityIdFilters = null;
if (tagId.HasValue)
{
entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken);
}
var tagFilteredEntityIds = tagId.HasValue
? await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken)
: null;
var favoriteUserFilteredEntityIds = favoriteUserId.HasValue
? await _markedItemManager.GetEntityIdsFilteredByUserAsync(favoriteUserId.Value, BlogPostConsts.EntityType)
: null;
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(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.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.Url).IsRequired().HasMaxLength(MenuItemConsts.MaxUrlLength);
b.Property(x => x.RequiredPermissionName).HasMaxLength(MenuItemConsts.MaxRequiredPermissionNameLength);
});
}
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.MongoDB;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.MarkedItems;
using Volo.CmsKit.Tags;
using Volo.CmsKit.Users;
@ -19,10 +20,15 @@ namespace Volo.CmsKit.MongoDB.Blogs;
public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, BlogPost, Guid>, IBlogPostRepository
{
private readonly MarkedItemManager _markedItemManager;
private EntityTagManager _entityTagManager;
public MongoBlogPostRepository(IMongoDbContextProvider<CmsKitMongoDbContext> dbContextProvider, EntityTagManager entityTagManager) : base(
public MongoBlogPostRepository(
IMongoDbContextProvider<CmsKitMongoDbContext> dbContextProvider,
MarkedItemManager markedItemManager,
EntityTagManager entityTagManager) : base(
dbContextProvider)
{
_markedItemManager = markedItemManager;
_entityTagManager = entityTagManager;
}
@ -48,15 +54,19 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
Guid? blogId = null,
Guid? authorId = null,
Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null,
CancellationToken cancellationToken = default)
{
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))
.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>>(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(authorId.HasValue, x => x.AuthorId == authorId)
@ -69,6 +79,7 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
Guid? blogId = null,
Guid? authorId = null,
Guid? tagId = null,
Guid? favoriteUserId = null,
BlogPostStatus? statusFilter = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
@ -79,12 +90,15 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
var dbContext = await GetDbContextAsync(cancellationToken);
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 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(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId)
@ -132,6 +146,28 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
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,
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? 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);
Guid? favoriteUserId = await GetFavoriteUserIdAsync(input.FilterOnFavorites);
var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.AuthorId, input.TagId,
favoriteUserId,
BlogPostStatus.Published, input.MaxResultCount,
input.SkipCount, input.Sorting);
@ -100,4 +103,14 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
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.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.UI.Navigation;
@ -55,7 +57,7 @@ public class CmsKitPublicMenuContributor : IMenuContributor
private ApplicationMenuItem CreateApplicationMenuItem(MenuItemDto menuItem)
{
return new ApplicationMenuItem(
var menu = new ApplicationMenuItem(
menuItem.DisplayName,
menuItem.DisplayName,
menuItem.Url,
@ -65,5 +67,11 @@ public class CmsKitPublicMenuContributor : IMenuContributor
menuItem.ElementId,
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 {
font-size: 1.5em;
font-size: 1.05rem;
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
@{
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-header title="@L["CmsKit:Modals:YouAreNotAuthenticated"]">
@ -15,8 +16,9 @@
<h4>
@message
</h4>
<br />
<a href="@Model.ViewModel.LoginUrl" class="btn btn-secondary">@L["CmsKit:Modals:Login"]</a>
</div>
</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>

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

@ -1,6 +1,10 @@
@page
@using Volo.CmsKit.Blogs
@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.Web
@ -8,6 +12,11 @@
@model IndexModel
@{
const string dummyImageSource = "/cms-kit/dummy-placeholder-320x180.png";
var isMarkedItemFeatureEnabled = GlobalFeatureManager.Instance.IsEnabled<MarkedItemsFeature>() && Model.MarkedItemsFeature?.IsEnabled == true;
}
@section styles {
<abp-style src="/Pages/Public/CmsKit/Blogs/index.css" />
}
@ -15,13 +24,13 @@
@section scripts {
<abp-script-bundle>
<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>
}
@{
const string dummyImageSource = "/cms-kit/dummy-placeholder-320x180.png";
}
@if (Model.AuthorId.HasValue)
{
<abp-row id="blogs-filter-area">
@ -61,11 +70,37 @@
@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">
@foreach (var blog in Model.Blogs.Items)
{
<abp-column size="_12" size-md="_6" size-lg="_4">
<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)
{
<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.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.Contents;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
@ -22,6 +26,9 @@ public class IndexModel : CmsKitPublicPageModelBase
[BindProperty(SupportsGet = true)]
public Guid? AuthorId { get; set; }
[BindProperty(SupportsGet = true)]
public bool? FilterOnFavorites { get; set; }
[BindProperty(SupportsGet = true)]
public Guid? TagId { get; set; }
@ -32,12 +39,17 @@ public class IndexModel : CmsKitPublicPageModelBase
public CmsUserDto SelectedAuthor { get; protected set; }
public string FilteredTagName { get; protected set; }
public BlogFeatureDto MarkedItemsFeature { get; private set; }
protected IBlogPostPublicAppService BlogPostPublicAppService { get; }
public IBlogFeatureAppService BlogFeatureAppService { get; }
public IndexModel(IBlogPostPublicAppService blogPostPublicAppService)
public IndexModel(
IBlogPostPublicAppService blogPostPublicAppService,
IBlogFeatureAppService blogFeatureAppService)
{
BlogPostPublicAppService = blogPostPublicAppService;
BlogFeatureAppService = blogFeatureAppService;
}
public virtual async Task<IActionResult> OnGetAsync()
@ -49,7 +61,8 @@ public class IndexModel : CmsKitPublicPageModelBase
SkipCount = PageSize * (CurrentPage - 1),
MaxResultCount = PageSize,
AuthorId = AuthorId,
TagId = TagId
TagId = TagId,
FilterOnFavorites = FilterOnFavorites
});
if (AuthorId != null)
@ -62,6 +75,13 @@ public class IndexModel : CmsKitPublicPageModelBase
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();
}
}

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;
-webkit-box-orient: vertical;
-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": {
"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
{
[DbContext(typeof(VoloDocsDbContext))]
[Migration("20240707104226_Initial")]
[Migration("20241231072012_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -22,7 +22,7 @@ namespace Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("ProductVersion", "8.0.4")
.HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -40,6 +40,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<string>("Description")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
@ -116,6 +120,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<int>("EntityVersion")
.HasColumnType("int");
@ -281,9 +289,13 @@ namespace Migrations
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("IpAddresses")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.Property<DateTime?>("LastAccessed")
.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),
Description = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
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),
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),
IsPublic = table.Column<bool>(type: "bit", 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),
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),
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
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),
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 =>
{

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

@ -19,7 +19,7 @@ namespace Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("ProductVersion", "8.0.4")
.HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -37,6 +37,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<string>("Description")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
@ -113,6 +117,10 @@ namespace Migrations
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<int>("EntityVersion")
.HasColumnType("int");
@ -278,9 +286,13 @@ namespace Migrations
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("IpAddresses")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.Property<DateTime?>("LastAccessed")
.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 Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin.Documents
{
@ -21,5 +22,7 @@ namespace Volo.Docs.Admin.Documents
Task ReindexAsync(Guid documentId);
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.Services;
using Volo.Abp.Caching;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Caching;
using Volo.Docs.Documents;
using Volo.Docs.Documents.FullSearch.Elastic;
@ -220,6 +221,12 @@ namespace Volo.Docs.Admin.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)
{

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.Modeling;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Admin;
@ -69,4 +70,9 @@ public partial class DocumentsAdminClientProxy : ClientProxyBase<IDocumentAdminA
{
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>",
"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,
"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.AspNetCore.Mvc;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin
{
@ -71,5 +72,12 @@ namespace Volo.Docs.Admin
{
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 Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin.Pages.Docs.Admin.Documents;
[Authorize(DocsAdminPermissions.Projects.Default)]
[Authorize(DocsAdminPermissions.Documents.Default)]
public class IndexModel : DocsAdminPageModel
{
private readonly IProjectAdminAppService _projectAdminAppService;
private readonly IDocumentAdminAppService _documentAdminAppService;
public List<ProjectWithoutDetailsDto> Projects { get; set; }
public IndexModel(IProjectAdminAppService projectAdminAppService)
public IndexModel(IDocumentAdminAppService documentAdminAppService)
{
_projectAdminAppService = projectAdminAppService;
_documentAdminAppService = documentAdminAppService;
}
public virtual async Task<IActionResult> OnGet()
{
Projects = await _projectAdminAppService.GetListWithoutDetailsAsync();
Projects = await _documentAdminAppService.GetProjectsAsync();
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));
};
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

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

@ -364,6 +364,11 @@ var doc = doc || {};
var initLazyExpandNavigation = function(){
$("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(){
var $this = $(this);
if($this.has("ul").length > 0){

Loading…
Cancel
Save