From 3aaa1d84236b16c4b3b19a9007a128bcc1cafe08 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 22 Feb 2021 16:46:44 +0800 Subject: [PATCH 001/101] Add RequiredPermissionName to ApplicationMenuItem. --- .../Abp/Ui/Navigation/ApplicationMenuItem.cs | 7 ++- .../Volo/Abp/Ui/Navigation/MenuManager.cs | 54 ++++++++++++++++- .../Volo.Abp.UI.Navigation.Tests.csproj | 2 + .../Navigation/AbpUiNavigationTestModule.cs | 21 +++++++ .../Abp/Ui/Navigation/FakePermissionStore.cs | 28 +++++++++ .../Abp/Ui/Navigation/MenuManager_Tests.cs | 60 +++++++++++-------- .../TestPermissionDefinitionProvider.cs | 24 ++++++++ 7 files changed, 167 insertions(+), 29 deletions(-) create mode 100644 framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs create mode 100644 framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/FakePermissionStore.cs create mode 100644 framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/TestPermissionDefinitionProvider.cs diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index 1c41727f7b..c1e4896513 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -71,6 +71,9 @@ namespace Volo.Abp.UI.Navigation [NotNull] public ApplicationMenuItemList Items { get; } + [CanBeNull] + public string RequiredPermissionName { get; } + /// /// Can be used to store a custom object related to this menu item. Optional. /// @@ -95,7 +98,8 @@ namespace Volo.Abp.UI.Navigation object customData = null, string target = null, string elementId = null, - string cssClass = null) + string cssClass = null, + string requiredPermissionName = null) { Check.NotNullOrWhiteSpace(name, nameof(name)); Check.NotNullOrWhiteSpace(displayName, nameof(displayName)); @@ -109,6 +113,7 @@ namespace Volo.Abp.UI.Navigation Target = target; ElementId = elementId ?? GetDefaultElementId(); CssClass = cssClass; + RequiredPermissionName = requiredPermissionName; Items = new ApplicationMenuItemList(); } diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index 5c33866aa2..6fe6102622 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -2,7 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; namespace Volo.Abp.UI.Navigation @@ -13,7 +15,7 @@ namespace Volo.Abp.UI.Navigation protected IHybridServiceScopeFactory ServiceScopeFactory { get; } public MenuManager( - IOptions options, + IOptions options, IHybridServiceScopeFactory serviceScopeFactory) { ServiceScopeFactory = serviceScopeFactory; @@ -32,6 +34,8 @@ namespace Volo.Abp.UI.Navigation { await contributor.ConfigureMenuAsync(context); } + + await CheckPermissionsAsync(scope.ServiceProvider, menu); } NormalizeMenu(menu); @@ -39,6 +43,52 @@ namespace Volo.Abp.UI.Navigation return menu; } + protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, IHasMenuItems menuWithItems) + { + var requiredPermissionMenus = new List(); + GetRequiredPermissionNameMenus(menuWithItems, requiredPermissionMenus); + + if (requiredPermissionMenus.Any()) + { + var permissionChecker = serviceProvider.GetRequiredService(); + var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionMenus.Select(x => x.RequiredPermissionName).ToArray()); + + var toBeDeletedMenus = new List(); + foreach (var menu in requiredPermissionMenus) + { + if (grantResult.Result[menu.RequiredPermissionName!] != PermissionGrantResult.Granted) + { + toBeDeletedMenus.Add(menu); + } + } + + RemoveMenus(menuWithItems, toBeDeletedMenus); + } + } + + protected virtual void GetRequiredPermissionNameMenus(IHasMenuItems menuWithItems, List output) + { + foreach (var menuItem in menuWithItems.Items) + { + if (!menuItem.RequiredPermissionName.IsNullOrWhiteSpace()) + { + output.Add(menuItem); + } + + GetRequiredPermissionNameMenus(menuItem, output); + } + } + + protected virtual void RemoveMenus(IHasMenuItems menuWithItems, List toBeDeleted) + { + menuWithItems.Items.RemoveAll(toBeDeleted.Contains); + + foreach (var menuItem in menuWithItems.Items) + { + RemoveMenus(menuItem, toBeDeleted); + } + } + protected virtual void NormalizeMenu(IHasMenuItems menuWithItems) { foreach (var menuItem in menuWithItems.Items) @@ -49,4 +99,4 @@ namespace Volo.Abp.UI.Navigation menuWithItems.Items.Normalize(); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj index ecfd73c615..a59bb11e0f 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj @@ -9,6 +9,8 @@ + + diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs new file mode 100644 index 0000000000..35b368cc1b --- /dev/null +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs @@ -0,0 +1,21 @@ +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace Volo.Abp.UI.Navigation +{ + [DependsOn(typeof(AbpUiNavigationModule))] + [DependsOn(typeof(AbpAuthorizationModule))] + [DependsOn(typeof(AbpAutofacModule))] + public class AbpUiNavigationTestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor1()); + options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor2()); + }); + } + } +} diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/FakePermissionStore.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/FakePermissionStore.cs new file mode 100644 index 0000000000..ac074220f5 --- /dev/null +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/FakePermissionStore.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.UI.Navigation +{ + public class FakePermissionStore : IPermissionStore, ITransientDependency + { + public Task IsGrantedAsync(string name, string providerName, string providerKey) + { + var result = (name.Contains("Administration") || name.Contains("Dashboard")) && !name.Contains("SubMenu1"); + return Task.FromResult(result); + } + + public Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, (name.Contains("Administration") || name.Contains("Dashboard")) && !name.Contains("SubMenu1") + ? PermissionGrantResult.Granted + : PermissionGrantResult.Prohibited); + } + + return Task.FromResult(result); + } + } +} diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs index 96db1622b5..c72082945b 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs @@ -1,13 +1,17 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using NSubstitute; using Shouldly; -using Volo.Abp.Modularity; +using Volo.Abp.Security.Claims; using Volo.Abp.Testing; using Xunit; namespace Volo.Abp.UI.Navigation { - public class MenuManager_Tests : AbpIntegratedTest + public class MenuManager_Tests : AbpIntegratedTest { private readonly IMenuManager _menuManager; @@ -16,6 +20,24 @@ namespace Volo.Abp.UI.Navigation _menuManager = ServiceProvider.GetRequiredService(); } + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + var claims = new List() { + new Claim(AbpClaimTypes.UserId, "1fcf46b2-28c3-48d0-8bac-fa53268a2775"), + }; + + var identity = new ClaimsIdentity(claims); + var claimsPrincipal = new ClaimsPrincipal(identity); + var principalAccessor = Substitute.For(); + principalAccessor.Principal.Returns(ci => claimsPrincipal); + Thread.CurrentPrincipal = claimsPrincipal; + } + [Fact] public async Task Should_Get_Menu() { @@ -29,22 +51,8 @@ namespace Volo.Abp.UI.Navigation mainMenu.Items[1].Items[0].Name.ShouldBe("Administration.UserManagement"); mainMenu.Items[1].Items[1].Name.ShouldBe("Administration.RoleManagement"); mainMenu.Items[1].Items[2].Name.ShouldBe("Administration.DashboardSettings"); - mainMenu.Items[1].Items[3].Name.ShouldBe("Administration.SubMenu1"); - mainMenu.Items[1].Items[3].Items[0].Name.ShouldBe("Administration.SubMenu1.1"); - mainMenu.Items[1].Items[3].Items[1].Name.ShouldBe("Administration.SubMenu1.2"); - } - - [DependsOn(typeof(AbpUiNavigationModule))] - public class TestModule : AbpModule - { - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.MenuContributors.Add(new TestMenuContributor1()); - options.MenuContributors.Add(new TestMenuContributor2()); - }); - } + mainMenu.Items[1].Items[3].Name.ShouldBe("Administration.SubMenu1"); //No need permission. + // Administration.SubMenu1.1 and Administration.SubMenu1.2 are removed because of don't have permissions. } /* Adds menu items: @@ -65,8 +73,8 @@ namespace Volo.Abp.UI.Navigation var administration = context.Menu.GetAdministration(); - administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users")); - administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles")); + administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users", requiredPermissionName: "Administration.UserManagement")); + administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles", requiredPermissionName: "Administration.RoleManagement")); return Task.CompletedTask; } @@ -86,16 +94,16 @@ namespace Volo.Abp.UI.Navigation return Task.CompletedTask; } - context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard")); + context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard", requiredPermissionName: "Dashboard")); var administration = context.Menu.GetAdministration(); - administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard")); + administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard", requiredPermissionName: "Administration.DashboardSettings")); administration.AddItem( - new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1") - .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1")) - .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2")) + new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1", url: "/submenu1") + .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1", requiredPermissionName: "Administration.SubMenu1.1")) + .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2", requiredPermissionName: "Administration.SubMenu1.2")) ); return Task.CompletedTask; diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/TestPermissionDefinitionProvider.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/TestPermissionDefinitionProvider.cs new file mode 100644 index 0000000000..c9afe5a1f0 --- /dev/null +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/TestPermissionDefinitionProvider.cs @@ -0,0 +1,24 @@ +using Volo.Abp.Authorization.Permissions; + +namespace Volo.Abp.UI.Navigation +{ + public class TestPermissionDefinitionProvider : PermissionDefinitionProvider + { + public override void Define(IPermissionDefinitionContext context) + { + var group = context.AddGroup("TestGroup"); + + group.AddPermission("Dashboard"); + + group.AddPermission("Administration"); + group.AddPermission("Administration.UserManagement"); + group.AddPermission("Administration.RoleManagement"); + + group.AddPermission("Administration.DashboardSettings"); + + group.AddPermission("Administration.SubMenu1"); + group.AddPermission("Administration.SubMenu1.1"); + group.AddPermission("Administration.SubMenu1.2"); + } + } +} From 0c65fec5610f6d2694dd0e5b4a95ed956a17b375 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 22 Feb 2021 22:13:04 +0800 Subject: [PATCH 002/101] Add RequiredPermissionName to ToolbarItem. --- .../Toolbars/ToolbarItem.cs | 8 +- .../Toolbars/ToolbarManager.cs | 31 ++++- .../Abp/Ui/Navigation/ApplicationMenuItem.cs | 2 +- .../Volo/Abp/Ui/Navigation/MenuManager.cs | 32 ++--- .../Shared/Permissions/FakePermissionStore.cs | 28 ++++ .../TestPermissionDefinitionProvider.cs | 16 +++ .../UI/Theme/Shared/Toolbars/Toolbar_Tests.cs | 129 ++++++++++++++++++ 7 files changed, 225 insertions(+), 21 deletions(-) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/FakePermissionStore.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/TestPermissionDefinitionProvider.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs index 9b6ef4becb..4676202c24 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarItem.cs @@ -14,10 +14,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars public int Order { get; set; } - public ToolbarItem([NotNull] Type componentType, int order = 0) + [CanBeNull] + public string RequiredPermissionName { get; set; } + + public ToolbarItem([NotNull] Type componentType, int order = 0, string requiredPermissionName = null) { Order = order; ComponentType = Check.NotNull(componentType, nameof(componentType)); + RequiredPermissionName = requiredPermissionName; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs index f1ac30779a..1f48b2825b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.UI.Theming; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars @@ -14,7 +17,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars protected IServiceProvider ServiceProvider { get; } public ToolbarManager( - IOptions options, + IOptions options, IServiceProvider serviceProvider, IThemeManager themeManager) { @@ -35,9 +38,33 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { await contributor.ConfigureToolbarAsync(context); } + + await CheckPermissionsAsync(scope.ServiceProvider, toolbar); } return toolbar; } + + protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, Toolbar toolbar) + { + var requiredPermissionItems = toolbar.Items.Where(x => !x.RequiredPermissionName.IsNullOrWhiteSpace()).ToList(); + + if (requiredPermissionItems.Any()) + { + var permissionChecker = serviceProvider.GetRequiredService(); + var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).ToArray()); + + var toBeDeleted = new List(); + foreach (var item in requiredPermissionItems) + { + if (grantResult.Result[item.RequiredPermissionName!] != PermissionGrantResult.Granted) + { + toBeDeleted.Add(item); + } + } + + toolbar.Items.RemoveAll(toBeDeleted.Contains); + } + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index c1e4896513..63f4d7239d 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -72,7 +72,7 @@ namespace Volo.Abp.UI.Navigation public ApplicationMenuItemList Items { get; } [CanBeNull] - public string RequiredPermissionName { get; } + public string RequiredPermissionName { get; set; } /// /// Can be used to store a custom object related to this menu item. Optional. diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index 6fe6102622..d1f3ee330a 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -45,37 +45,37 @@ namespace Volo.Abp.UI.Navigation protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, IHasMenuItems menuWithItems) { - var requiredPermissionMenus = new List(); - GetRequiredPermissionNameMenus(menuWithItems, requiredPermissionMenus); + var requiredPermissionItems = new List(); + GetRequiredPermissionNameMenus(menuWithItems, requiredPermissionItems); - if (requiredPermissionMenus.Any()) + if (requiredPermissionItems.Any()) { var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionMenus.Select(x => x.RequiredPermissionName).ToArray()); + var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).ToArray()); - var toBeDeletedMenus = new List(); - foreach (var menu in requiredPermissionMenus) + var toBeDeleted = new List(); + foreach (var menu in requiredPermissionItems) { if (grantResult.Result[menu.RequiredPermissionName!] != PermissionGrantResult.Granted) { - toBeDeletedMenus.Add(menu); + toBeDeleted.Add(menu); } } - RemoveMenus(menuWithItems, toBeDeletedMenus); + RemoveMenus(menuWithItems, toBeDeleted); } } protected virtual void GetRequiredPermissionNameMenus(IHasMenuItems menuWithItems, List output) { - foreach (var menuItem in menuWithItems.Items) + foreach (var item in menuWithItems.Items) { - if (!menuItem.RequiredPermissionName.IsNullOrWhiteSpace()) + if (!item.RequiredPermissionName.IsNullOrWhiteSpace()) { - output.Add(menuItem); + output.Add(item); } - GetRequiredPermissionNameMenus(menuItem, output); + GetRequiredPermissionNameMenus(item, output); } } @@ -83,17 +83,17 @@ namespace Volo.Abp.UI.Navigation { menuWithItems.Items.RemoveAll(toBeDeleted.Contains); - foreach (var menuItem in menuWithItems.Items) + foreach (var item in menuWithItems.Items) { - RemoveMenus(menuItem, toBeDeleted); + RemoveMenus(item, toBeDeleted); } } protected virtual void NormalizeMenu(IHasMenuItems menuWithItems) { - foreach (var menuItem in menuWithItems.Items) + foreach (var item in menuWithItems.Items) { - NormalizeMenu(menuItem); + NormalizeMenu(item); } menuWithItems.Items.Normalize(); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/FakePermissionStore.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/FakePermissionStore.cs new file mode 100644 index 0000000000..f8f9d21b27 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/FakePermissionStore.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Permissions +{ + public class FakePermissionStore : IPermissionStore, ITransientDependency + { + public Task IsGrantedAsync(string name, string providerName, string providerKey) + { + var result = (name.Contains("MyComponent1") || name.Contains("MyComponent3")); + return Task.FromResult(result); + } + + public Task IsGrantedAsync(string[] names, string providerName, string providerKey) + { + var result = new MultiplePermissionGrantResult(); + foreach (var name in names) + { + result.Result.Add(name, (name.Contains("MyComponent1") || name.Contains("MyComponent3")) + ? PermissionGrantResult.Granted + : PermissionGrantResult.Prohibited); + } + + return Task.FromResult(result); + } + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/TestPermissionDefinitionProvider.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/TestPermissionDefinitionProvider.cs new file mode 100644 index 0000000000..ef706a6c0a --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Permissions/TestPermissionDefinitionProvider.cs @@ -0,0 +1,16 @@ +using Volo.Abp.Authorization.Permissions; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Permissions +{ + public class TestPermissionDefinitionProvider : PermissionDefinitionProvider + { + public override void Define(IPermissionDefinitionContext context) + { + var group = context.AddGroup("TestGroup"); + + group.AddPermission("MyComponent1"); + group.AddPermission("MyComponent2"); + group.AddPermission("MyComponent3"); + } + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs new file mode 100644 index 0000000000..70ca907fac --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Toolbars/Toolbar_Tests.cs @@ -0,0 +1,129 @@ +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; +using NSubstitute; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; +using Volo.Abp.AspNetCore.Mvc.UI.Theming; +using Volo.Abp.Security.Claims; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars +{ + public class Toolbar_Tests : AbpAspNetCoreMvcUiThemeSharedTestBase + { + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + services.Configure(options => + { + options.Contributors.Add(new MyToolbarContributor()); + options.Contributors.Add(new MyToolbarContributor2()); + }); + + var claims = new List() { + new Claim(AbpClaimTypes.UserId, "1fcf46b2-28c3-48d0-8bac-fa53268a2775"), + }; + + var identity = new ClaimsIdentity(claims); + var claimsPrincipal = new ClaimsPrincipal(identity); + var principalAccessor = Substitute.For(); + principalAccessor.Principal.Returns(ci => claimsPrincipal); + Thread.CurrentPrincipal = claimsPrincipal; + + var themeManager = Substitute.For(); + themeManager.CurrentTheme.Returns(x => null); + services.Replace(ServiceDescriptor.Singleton(themeManager)); + } + + [Fact] + public void AbpToolbarOptions_Should_Contain_Contributors() + { + var options = GetRequiredService>().Value; + options.Contributors.Count.ShouldBe(2); + options.Contributors.ShouldContain(x => x.GetType() == typeof(MyToolbarContributor)); + options.Contributors.ShouldContain(x => x.GetType() == typeof(MyToolbarContributor2)); + } + + [Fact] + public async Task ToolbarManager_Should_Return_Toolbar() + { + var toolbarManager = GetRequiredService(); + var toolbar = await toolbarManager.GetAsync(StandardToolbars.Main); + + toolbar.Items.Count.ShouldBe(3); + toolbar.Items[0].ComponentType.ShouldBe(typeof(MyComponent1)); + toolbar.Items[1].ComponentType.ShouldBe(typeof(MyComponent3)); + toolbar.Items[2].ComponentType.ShouldBe(typeof(MyComponent4)); + } + + public class MyToolbarContributor : IToolbarContributor + { + public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) + { + if (context.Toolbar.Name != StandardToolbars.Main) + { + return Task.CompletedTask; + } + + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent1), requiredPermissionName: "MyComponent1")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent2), requiredPermissionName: "MyComponent2")); + + return Task.CompletedTask; + } + } + + public class MyToolbarContributor2 : IToolbarContributor + { + public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) + { + if (context.Toolbar.Name != StandardToolbars.Main) + { + return Task.CompletedTask; + } + + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent3), requiredPermissionName: "MyComponent3")); + context.Toolbar.Items.Add(new ToolbarItem(typeof(MyComponent4))); + + return Task.CompletedTask; + } + } + + public class MyComponent1 : AbpViewComponent + { + public IViewComponentResult InvokeAsync() + { + return Content("MyComponent1"); + } + } + + public class MyComponent2 : AbpViewComponent + { + public IViewComponentResult InvokeAsync() + { + return Content("MyComponent2"); + } + } + + public class MyComponent3 : AbpViewComponent + { + public IViewComponentResult InvokeAsync() + { + return Content("MyComponent3"); + } + } + + public class MyComponent4 : AbpViewComponent + { + public IViewComponentResult InvokeAsync() + { + return Content("MyComponent4"); + } + } + } +} From def5167177309620f90fa33b41598bc5381dce88 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 26 Feb 2021 14:41:57 +0300 Subject: [PATCH 003/101] Cli: AppTemplate ConfigureTenantSchema --- .../Templates/App/AppTemplateBase.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs index 2a596b73a7..a725a513e7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs @@ -24,6 +24,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App { var steps = new List(); + ConfigureTenantSchema(context, steps); SwitchDatabaseProvider(context, steps); DeleteUnrelatedProjects(context, steps); RemoveMigrations(context, steps); @@ -38,6 +39,19 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App return steps; } + private static void ConfigureTenantSchema(ProjectBuildContext context, List steps) + { + if (context.BuildArgs.ExtraProperties.ContainsKey("separate-tenant-schema")) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations")); + steps.Add(new AppTemplateProjectRenameStep("MyCompanyName.MyProjectName.EntityFrameworkCore.SeparateDbMigrations", "MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations")); + } + else + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.EntityFrameworkCore.SeparateDbMigrations")); + } + } + private static void SwitchDatabaseProvider(ProjectBuildContext context, List steps) { if (context.BuildArgs.DatabaseProvider == DatabaseProvider.MongoDb) From 167e3a8fd52a9e2e6a47f43c906e4ba78e387c79 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 26 Feb 2021 14:48:36 +0300 Subject: [PATCH 004/101] CmsKit - Initial commit of Admin Pages --- ...20210226112040_BlogPost_Author.Designer.cs | 2007 +++++++++++++++++ .../20210226112040_BlogPost_Author.cs | 109 + .../UnifiedDbContextModelSnapshot.cs | 29 +- .../host/Volo.CmsKit.Web.Unified/package.json | 3 +- .../Bundles/SlugifyScriptContributor.cs | 17 + .../CmsKitAdminWebModule.cs | 72 + .../Menus/CmsKitAdminMenuContributor.cs | 81 +- .../Menus/CmsKitAdminMenus.cs | 28 +- .../Pages/CmsKit/BlogPosts/Create.cshtml | 79 + .../Pages/CmsKit/BlogPosts/Create.cshtml.cs | 63 + .../Pages/CmsKit/BlogPosts/Index.cshtml | 33 + .../Pages/CmsKit/BlogPosts/Index.cshtml.cs | 7 + .../Pages/CmsKit/BlogPosts/Update.cshtml | 77 + .../Pages/CmsKit/BlogPosts/Update.cshtml.cs | 77 + .../Pages/CmsKit/BlogPosts/create.js | 212 ++ .../Pages/CmsKit/BlogPosts/index.js | 68 + .../Pages/CmsKit/BlogPosts/update.js | 180 ++ .../Pages/CmsKit/Blogs/CreateModal.cshtml | 23 + .../Pages/CmsKit/Blogs/CreateModal.cshtml.cs | 44 + .../Pages/CmsKit/Blogs/FeaturesModal.cshtml | 44 + .../CmsKit/Blogs/FeaturesModal.cshtml.cs | 77 + .../Pages/CmsKit/Blogs/Index.cshtml | 38 + .../Pages/CmsKit/Blogs/Index.cshtml.cs | 7 + .../Pages/CmsKit/Blogs/UpdateModal.cshtml | 23 + .../Pages/CmsKit/Blogs/UpdateModal.cshtml.cs | 60 + .../Pages/CmsKit/Blogs/createModal.js | 47 + .../Pages/CmsKit/Blogs/index.js | 85 + .../Pages/CmsKit/Blogs/updateModal.js | 30 + .../Pages/CmsKit/Comments/Details.cshtml | 108 + .../Pages/CmsKit/Comments/Details.cshtml.cs | 33 + .../Pages/CmsKit/Comments/Index.cshtml | 71 + .../Pages/CmsKit/Comments/Index.cshtml.cs | 17 + .../Pages/CmsKit/Comments/details.css | 3 + .../Pages/CmsKit/Comments/details.js | 146 ++ .../Pages/CmsKit/Comments/index.css | 3 + .../Pages/CmsKit/Comments/index.js | 158 ++ .../ContentEditorViewComponent.cs | 44 + .../Components/ContentEditor/Default.cshtml | 7 + .../Components/ContentEditor/default.js | 80 + .../EntityContentEditor/ContentViewModel.cs | 28 + .../EntityContentEditor/Default.cshtml | 27 + .../EntityContentEditorViewComponent.cs | 65 + .../Components/EntityContentEditor/default.js | 34 + .../Pages/CmsKit/Pages/Create.cshtml | 44 + .../Pages/CmsKit/Pages/Create.cshtml.cs | 47 + .../Pages/CmsKit/Pages/Index.cshtml | 40 + .../Pages/CmsKit/Pages/Index.cshtml.cs | 11 + .../Pages/CmsKit/Pages/Update.cshtml | 45 + .../Pages/CmsKit/Pages/Update.cshtml.cs | 62 + .../Pages/CmsKit/Pages/create.js | 72 + .../Pages/CmsKit/Pages/index.js | 81 + .../Pages/CmsKit/Pages/update.js | 65 + .../Tags/Components/TagEditor/Default.cshtml | 22 + .../TagEditor/TagEditorViewComponent.cs | 49 + .../Tags/Components/TagEditor/default.js | 26 + .../Pages/CmsKit/Tags/CreateModal.cshtml | 23 + .../Pages/CmsKit/Tags/CreateModal.cshtml.cs | 58 + .../Pages/CmsKit/Tags/EditModal.cshtml | 24 + .../Pages/CmsKit/Tags/EditModal.cshtml.cs | 54 + .../Pages/CmsKit/Tags/Index.cshtml | 38 + .../Pages/CmsKit/Tags/Index.cshtml.cs | 8 + .../Pages/CmsKit/Tags/Index.js | 83 + .../Pages/CmsKitAdminPageBase.cs | 20 + .../Volo.CmsKit.Admin.Web.csproj | 2 +- 64 files changed, 5290 insertions(+), 28 deletions(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.Designer.cs create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Bundles/SlugifyScriptContributor.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/createModal.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/index.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.css create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.css create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/TagEditorViewComponent.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.js create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKitAdminPageBase.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.Designer.cs new file mode 100644 index 0000000000..8ace403879 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.Designer.cs @@ -0,0 +1,2007 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20210226112040_BlogPost_Author")] + partial class BlogPost_Author + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.3") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)") + .HasColumnName("Exceptions"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpFeatureValues"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogs"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogFeature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeatureName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogFeatures"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ShortDescription") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("Slug", "BlogId"); + + b.ToTable("CmsBlogPosts"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.MediaDescriptors.MediaDescriptor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Size") + .HasMaxLength(2147483647) + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsMediaDescriptors"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Slug"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.HasOne("Volo.CmsKit.Users.CmsUser", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.cs new file mode 100644 index 0000000000..48186c4918 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210226112040_BlogPost_Author.cs @@ -0,0 +1,109 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class BlogPost_Author : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_CreatorId", + table: "CmsBlogPosts"); + + migrationBuilder.DropForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_DeleterId", + table: "CmsBlogPosts"); + + migrationBuilder.DropForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_LastModifierId", + table: "CmsBlogPosts"); + + migrationBuilder.DropIndex( + name: "IX_CmsBlogPosts_CreatorId", + table: "CmsBlogPosts"); + + migrationBuilder.DropIndex( + name: "IX_CmsBlogPosts_DeleterId", + table: "CmsBlogPosts"); + + migrationBuilder.DropIndex( + name: "IX_CmsBlogPosts_LastModifierId", + table: "CmsBlogPosts"); + + migrationBuilder.AddColumn( + name: "AuthorId", + table: "CmsBlogPosts", + type: "uniqueidentifier", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_AuthorId", + table: "CmsBlogPosts", + column: "AuthorId"); + + migrationBuilder.AddForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_AuthorId", + table: "CmsBlogPosts", + column: "AuthorId", + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_AuthorId", + table: "CmsBlogPosts"); + + migrationBuilder.DropIndex( + name: "IX_CmsBlogPosts_AuthorId", + table: "CmsBlogPosts"); + + migrationBuilder.DropColumn( + name: "AuthorId", + table: "CmsBlogPosts"); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_CreatorId", + table: "CmsBlogPosts", + column: "CreatorId"); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_DeleterId", + table: "CmsBlogPosts", + column: "DeleterId"); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_LastModifierId", + table: "CmsBlogPosts", + column: "LastModifierId"); + + migrationBuilder.AddForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_CreatorId", + table: "CmsBlogPosts", + column: "CreatorId", + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_DeleterId", + table: "CmsBlogPosts", + column: "DeleterId", + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_LastModifierId", + table: "CmsBlogPosts", + column: "LastModifierId", + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index ed07831276..63c57a4390 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1257,6 +1257,9 @@ namespace Volo.CmsKit.Migrations .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + b.Property("BlogId") .HasColumnType("uniqueidentifier"); @@ -1320,11 +1323,7 @@ namespace Volo.CmsKit.Migrations b.HasKey("Id"); - b.HasIndex("CreatorId"); - - b.HasIndex("DeleterId"); - - b.HasIndex("LastModifierId"); + b.HasIndex("AuthorId"); b.HasIndex("Slug", "BlogId"); @@ -1952,23 +1951,13 @@ namespace Volo.CmsKit.Migrations modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => { - b.HasOne("Volo.CmsKit.Users.CmsUser", "Creator") - .WithMany() - .HasForeignKey("CreatorId"); - - b.HasOne("Volo.CmsKit.Users.CmsUser", "Deleter") + b.HasOne("Volo.CmsKit.Users.CmsUser", "Author") .WithMany() - .HasForeignKey("DeleterId"); - - b.HasOne("Volo.CmsKit.Users.CmsUser", "LastModifier") - .WithMany() - .HasForeignKey("LastModifierId"); - - b.Navigation("Creator"); - - b.Navigation("Deleter"); + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.Navigation("LastModifier"); + b.Navigation("Author"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json index a373644dd2..09764bdd29 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json @@ -7,6 +7,7 @@ "@abp/cms-kit": "4.2.1", "@abp/tui-editor": "^4.2.1", "tui-code-snippet": "1.5.2", - "@abp/uppy": "^4.2.1" + "@abp/uppy": "^4.2.1", + "slugify": "1.4.6" } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Bundles/SlugifyScriptContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Bundles/SlugifyScriptContributor.cs new file mode 100644 index 0000000000..942f484ebe --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Bundles/SlugifyScriptContributor.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.CmsKit.Admin.Web.Bundles +{ + public class SlugifyScriptContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.Add("/libs/slugify/slugify.js"); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs index 075d700720..fa93175efc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs @@ -7,6 +7,9 @@ using Volo.Abp.UI.Navigation; using Volo.Abp.VirtualFileSystem; using Volo.CmsKit.Localization; using Volo.CmsKit.Web; +using Volo.CmsKit.Permissions; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.PageToolbars; +using Volo.Abp.Localization; namespace Volo.CmsKit.Admin.Web { @@ -46,10 +49,79 @@ namespace Volo.CmsKit.Admin.Web options.FileSets.AddEmbedded("Volo.CmsKit.Admin.Web"); }); + Configure(options => + { + options.Conventions.AuthorizeFolder("/CmsKit/Tags/", CmsKitAdminPermissions.Tags.Default); + options.Conventions.AuthorizeFolder("/CmsKit/Tags/CreateModal", CmsKitAdminPermissions.Tags.Create); + options.Conventions.AuthorizeFolder("/CmsKit/Tags/UpdateModal", CmsKitAdminPermissions.Tags.Update); + options.Conventions.AuthorizeFolder("/CmsKit/Pages", CmsKitAdminPermissions.Pages.Default); + options.Conventions.AuthorizeFolder("/CmsKit/Pages/Create", CmsKitAdminPermissions.Pages.Create); + options.Conventions.AuthorizeFolder("/CmsKit/Pages/Update", CmsKitAdminPermissions.Pages.Update); + options.Conventions.AuthorizeFolder("/CmsKit/Blogs", CmsKitAdminPermissions.Blogs.Default); + options.Conventions.AuthorizeFolder("/CmsKit/Blogs/Create", CmsKitAdminPermissions.Blogs.Create); + options.Conventions.AuthorizeFolder("/CmsKit/Blogs/Update", CmsKitAdminPermissions.Blogs.Update); + options.Conventions.AuthorizeFolder("/CmsKit/BlogPosts", CmsKitAdminPermissions.BlogPosts.Default); + options.Conventions.AuthorizeFolder("/CmsKit/BlogPosts/Create", CmsKitAdminPermissions.BlogPosts.Create); + options.Conventions.AuthorizeFolder("/CmsKit/BlogPosts/Update", CmsKitAdminPermissions.BlogPosts.Update); + options.Conventions.AuthorizeFolder("/CmsKit/Comments/", CmsKitAdminPermissions.Comments.Default); + options.Conventions.AuthorizeFolder("/CmsKit/Comments/Details", CmsKitAdminPermissions.Comments.Default); + }); + Configure(options => { //Configure authorization. }); + + Configure(options => + { + + options.Configure( + toolbar => + { + toolbar.AddButton( + LocalizableString.Create("New"), + icon: "plus", + name: "NewButton", + requiredPolicyName: CmsKitAdminPermissions.Tags.Create + ); + } + ); + + options.Configure( + toolbar => + { + toolbar.AddButton( + LocalizableString.Create("New"), + icon: "plus", + name: "CreatePage", + requiredPolicyName: CmsKitAdminPermissions.Pages.Create + ); + }); + + options.Configure( + toolbar => + { + toolbar.AddButton( + LocalizableString.Create("New"), + icon: "plus", + name: "CreateBlog", + id: "CreateBlog", + requiredPolicyName: CmsKitAdminPermissions.Blogs.Create + ); + }); + + options.Configure( + toolbar => + { + toolbar.AddButton( + LocalizableString.Create("New"), + icon: "plus", + name: "CreateBlogPost", + id: "CreateBlogPost", + requiredPolicyName: CmsKitAdminPermissions.BlogPosts.Create + ); + }); + }); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs index 403715b1bf..bf7d6be0d1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs @@ -1,5 +1,9 @@ using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; using Volo.Abp.UI.Navigation; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Localization; +using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Web.Menus { @@ -13,11 +17,82 @@ namespace Volo.CmsKit.Admin.Web.Menus } } - private Task ConfigureMainMenuAsync(MenuConfigurationContext context) + private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) { - //Add main menu items. + await AddCmsMenuAsync(context); + } + + private async Task AddCmsMenuAsync(MenuConfigurationContext context) + { + var l = context.GetLocalizer(); + + var cmsMenu = context.Menu.FindMenuItem(CmsKitAdminMenus.GroupName); + + cmsMenu ??= new ApplicationMenuItem( + CmsKitAdminMenus.GroupName, + l["Cms"], + icon: "far fa-newspaper"); + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + if (await context.IsGrantedAsync(CmsKitAdminPermissions.Comments.Default)) + { + cmsMenu.AddItem(new ApplicationMenuItem( + CmsKitAdminMenus.Comments.CommentsMenu, + l["Comments"].Value, + "/CmsKit/Comments" + ) + ); + } + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + if (await context.IsGrantedAsync(CmsKitAdminPermissions.Tags.Default)) + { + cmsMenu.AddItem(new ApplicationMenuItem( + CmsKitAdminMenus.Tags.TagsMenu, + l["Tags"].Value, + "/CmsKit/Tags")); + } + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + if (await context.IsGrantedAsync(CmsKitAdminPermissions.Pages.Default)) + { + cmsMenu.AddItem(new ApplicationMenuItem( + CmsKitAdminMenus.Pages.PagesMenu, + l["Pages"].Value, + "/CmsKit/Pages")); + } + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + if (await context.IsGrantedAsync(CmsKitAdminPermissions.Blogs.Default)) + { + cmsMenu.AddItem(new ApplicationMenuItem( + CmsKitAdminMenus.Blogs.BlogsMenu, + l["Blogs"], + "/CmsKit/Blogs" + )); + } + + if (await context.IsGrantedAsync(CmsKitAdminPermissions.BlogPosts.Default)) + { + cmsMenu.AddItem(new ApplicationMenuItem( + CmsKitAdminMenus.BlogPosts.BlogPostsMenu, + l["BlogPosts"], + "/CmsKit/BlogPosts" + )); + } + } - return Task.CompletedTask; + if (cmsMenu.Items.Count > 0) + { + context.Menu.AddItem(cmsMenu); + } } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenus.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenus.cs index e6a42db4fa..b9024692df 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenus.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenus.cs @@ -2,10 +2,32 @@ { public class CmsKitAdminMenus { - private const string Prefix = "CmsKit.Admin"; + public const string GroupName = "Cms"; - //Add your menu items here... - //public const string Home = Prefix + ".MyNewMenuItem"; + public static class Comments + { + public const string CommentsMenu = GroupName + ".Comments"; + } + + public static class Tags + { + public const string TagsMenu = GroupName + ".Tags"; + } + + public static class Pages + { + public const string PagesMenu = GroupName + ".Pages"; + } + + public static class Blogs + { + public const string BlogsMenu = GroupName + ".Blogs"; + } + + public static class BlogPosts + { + public const string BlogPostsMenu = GroupName + ".BlogPosts"; + } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml new file mode 100644 index 0000000000..ae5c3ce9bd --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml @@ -0,0 +1,79 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor +@using Volo.CmsKit.Blogs +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy +@using Volo.CmsKit.Admin.Web.Bundles + +@inherits CmsKitAdminPageBase + +@model CreateModel + +@{ + PageLayout.Content.Title = L["BlogPosts"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.BlogPosts.BlogPostsMenu; +} + +@section scripts { + + + + + +} + +@section content_toolbar { + @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(CreateModel).FullName }) +} + + + + +
+ + +
+ + +
+ + + +
+ + + + + + @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new + { + entityType = BlogPostConsts.EntityType, + displaySubmitButton = false + }) + + + +
+ +
+ +
+ + @await Component.InvokeAsync(typeof(TagEditorViewComponent), new + { + entityType = BlogPostConsts.EntityType, + displaySubmitButton = false + }) +
+ +
+ + + +
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs new file mode 100644 index 0000000000..2d01e55668 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs @@ -0,0 +1,63 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Blogs; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts +{ + public class CreateModel : CmsKitAdminPageModel + { + protected IBlogPostAdminAppService BlogPostAdminAppService { get; } + + [BindProperty] + public CreateBlogPostViewModel ViewModel { get; set; } + + public CreateModel( + IBlogPostAdminAppService blogPostAdminAppService) + { + BlogPostAdminAppService = blogPostAdminAppService; + } + + public async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + + var created = await BlogPostAdminAppService.CreateAsync(dto); + + return new OkObjectResult(created); + } + + [AutoMap(typeof(CreateBlogPostDto), ReverseMap = true)] + public class CreateBlogPostViewModel + { + [Required] + [DynamicFormIgnore] + public Guid BlogId { get; set; } + + [Required] + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))] + [DynamicFormIgnore] + public string Title { get; set; } + + [Required] + [DynamicStringLength( + typeof(BlogPostConsts), + nameof(BlogPostConsts.MaxSlugLength), + nameof(BlogPostConsts.MinSlugLength))] + [DynamicFormIgnore] + public string Slug { get; set; } + + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] + public string ShortDescription { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml new file mode 100644 index 0000000000..caea6d3754 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml @@ -0,0 +1,33 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar + +@inherits CmsKitAdminPageBase + +@model IndexModel + +@{ + PageLayout.Content.Title = L["BlogPosts"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.BlogPosts.BlogPostsMenu; +} + +@section scripts { + +} + + +@section content_toolbar { + @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName }) +} + +
+ + + + + +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml.cs new file mode 100644 index 0000000000..02afe21fc1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Index.cshtml.cs @@ -0,0 +1,7 @@ +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts +{ + public class IndexModel : CmsKitAdminPageModel + { + + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml new file mode 100644 index 0000000000..b4692365ef --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml @@ -0,0 +1,77 @@ +@page "{Id}" + +@using Volo.CmsKit.Blogs +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy +@using Volo.CmsKit.Admin.Web.Bundles + +@inherits CmsKitAdminPageBase + +@model UpdateModel + +@{ + PageLayout.Content.Title = L["BlogPosts"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.BlogPosts.BlogPostsMenu; +} + +@section scripts { + + + + + +} + +@section content_toolbar { + @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(UpdateModel).FullName }) +} + + + + + +
+ + + +
+ + + + + + + + + @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new + { + entityType = BlogPostConsts.EntityType, + entityId = Model.Id.ToString(), + displaySubmitButton = false + }) + + + + + @if (Model.TagsFeature?.IsEnabled == true) + { +
+ + @await Component.InvokeAsync(typeof(TagEditorViewComponent), new + { + entityType = BlogPostConsts.EntityType, + entityId = Model.Id.ToString(), + displaySubmitButton = false + }) + } +
+ + + +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs new file mode 100644 index 0000000000..29c839a947 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs @@ -0,0 +1,77 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Blogs; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts +{ + public class UpdateModel : CmsKitAdminPageModel + { + protected IBlogPostAdminAppService BlogPostAdminAppService { get; } + protected IBlogFeatureAppService BlogFeatureAppService { get; } + + [BindProperty] + public virtual UpdateBlogPostViewModel ViewModel { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public virtual Guid Id { get; set; } + + public virtual BlogFeatureDto TagsFeature { get; protected set; } + + public UpdateModel( + IBlogPostAdminAppService blogPostAdminAppService, + IBlogFeatureAppService blogFeatureAppService) + { + BlogPostAdminAppService = blogPostAdminAppService; + BlogFeatureAppService = blogFeatureAppService; + } + + public virtual async Task OnGetAsync() + { + var blogPost = await BlogPostAdminAppService.GetAsync(Id); + + ViewModel = ObjectMapper.Map(blogPost); + + TagsFeature = await BlogFeatureAppService.GetOrDefaultAsync(blogPost.BlogId, GlobalFeatures.TagsFeature.Name); + } + + public virtual async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + + await BlogPostAdminAppService.UpdateAsync(Id, dto); + + return NoContent(); + } + + [AutoMap(typeof(BlogPostDto))] + [AutoMap(typeof(UpdateBlogPostDto), ReverseMap = true)] + public class UpdateBlogPostViewModel + { + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))] + [Required] + [DynamicFormIgnore] + public string Title { get; set; } + + [DynamicStringLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxSlugLength), nameof(BlogPostConsts.MinSlugLength))] + [Required] + [DisplayOrder(10000)] + [DynamicFormIgnore] + public string Slug { get; set; } + + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] + [DisplayOrder(10001)] + public string ShortDescription { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js new file mode 100644 index 0000000000..dece495320 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js @@ -0,0 +1,212 @@ +$(function () { + + var l = abp.localization.getResource("CmsKit"); + + var $selectBlog = $('#BlogSelectionSelect'); + var $formCreate = $('#form-blog-post-create'); + var $title = $('#ViewModel_Title'); + var $shortDescription = $('#ViewModel_ShortDescription'); + var $url = $('#ViewModel_Slug'); + var $buttonSubmit = $('#button-blog-post-create'); + var $pageContentInput = $('#ViewModel_Value'); + var $tagsInput = $('.tag-editor-form input[name=tags]'); + var $fileInput = $('#BlogPostCoverImage'); + var $tagsWrapper = $('#blog-post-tags-wrapper'); + + var UPPY_UPLOAD_ENDPOINT = "/api/cms-kit-admin/blogs/blog-posts/{0}/cover-image"; + var UPPY_FILE_ID = "uppy-upload-file"; + + var isTagsEnabled = true; + + $formCreate.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; + + function initSelectBlog() { + $selectBlog.data('autocompleteApiUrl', '/api/cms-kit-admin/blogs'); + $selectBlog.data('autocompleteDisplayProperty', 'name'); + $selectBlog.data('autocompleteValueProperty', 'id'); + $selectBlog.data('autocompleteItemsProperty', 'items'); + $selectBlog.data('autocompleteFilterParamName', 'filter'); + + abp.dom.initializers.initializeAutocompleteSelects($selectBlog); + } + + initSelectBlog(); + + $formCreate.on('submit', function (e) { + e.preventDefault(); + + if ($formCreate.valid()) { + + abp.ui.setBusy(); + + $formCreate.ajaxSubmit({ + success: function (result) { + submitEntityContent(result.id); + }, + error: function (result) { + abp.notify.error(result.responseJSON.error.message); + abp.ui.clearBusy(); + } + }); + } + }); + + $buttonSubmit.click(function (e) { + e.preventDefault(); + $formCreate.submit(); + }); + + function submitEntityContent(blogPostId) { + volo.cmsKit.admin.contents.contentAdmin + .create( + { + entityType: 'BlogPost', + entityId: blogPostId, + value: $pageContentInput.val() + }) + .then(function (result) { + if (isTagsEnabled) { + submitEntityTags(blogPostId) + } + else { + submitCoverImage(blogPostId); + } + }); + } + + function submitEntityTags(blogPostId) { + + var tags = $tagsInput.val().split(","); + + volo.cmsKit.admin.tags.entityTagAdmin + .setEntityTags({ + entityType: 'BlogPost', + entityId: blogPostId, + tags: tags + }) + .then(function (result) { + submitCoverImage(blogPostId); + }); + } + + function getUppyHeaders() { + var headers = {}; + headers[abp.security.antiForgery.tokenHeaderName] = abp.security.antiForgery.getToken(); + + return headers; + } + + function submitCoverImage(blogPostId) { + var UPPY_OPTIONS = { + endpoint: UPPY_UPLOAD_ENDPOINT.replace("{0}", blogPostId), + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + var file = $fileInput[0].files[0]; + + if (file) { + + UPPY.addFile({ + id: UPPY_FILE_ID, + name: file.name, // file name + type: file.type, // file type + data: file, // file + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error(l("UploadFailedMessage")); + } else { + finishSaving(); + } + }); + } + else { + finishSaving(); + } + } + + function finishSaving() { + abp.notify.success(l('SuccessfullySaved')); + abp.ui.clearBusy(); + location.href = "/Admin/BlogPosts/"; + } + + var urlEdited = false; + var reflectedChange = false; + + $url.on('change', function () { + reflectUrlChanges(); + }); + + $title.on('keyup paste', function () { + reflectUrlChanges(); + }); + + function reflectUrlChanges() { + var title = $title.val().toLocaleLowerCase(); + + if (urlEdited) { + title = $url.val(); + } + + var slugified = slugify(title, { + lower: true + }); + + if (slugified != $url.val()) { + reflectedChange = true; + + $url.val(slugified); + + reflectedChange = false; + } + } + + $url.change(function () { + if (!reflectedChange) { + urlEdited = true; + } + }); + + var shorDescriptionEdited = false; + $pageContentInput.on('change', function () { + if (shorDescriptionEdited) { + return; + } + + var htmlValue = $pageContentInput.val(); + + var plainValue = jQuery('
').html(htmlValue).text().replace(/\n/g, ' ').substring(0, 120); + + $shortDescription.val(plainValue); + }); + + $shortDescription.on('change', function () { + shorDescriptionEdited = true; + }); + + $selectBlog.on('change', function () { + var blogId = $selectBlog.val(); + volo.cmsKit.blogs.blogFeature + .getOrDefault(blogId, 'CmsKit.Tags') + .then(function (result) { + if (result) { + isTagsEnabled = result.isEnabled == true + if (isTagsEnabled === true) { + $tagsWrapper.removeClass('d-none'); + } + else { + $tagsWrapper.addClass('d-none'); + } + } + }); + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js new file mode 100644 index 0000000000..7302299419 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js @@ -0,0 +1,68 @@ + +$(function () { + var l = abp.localization.getResource("CmsKit"); + + var blogsService = volo.cmsKit.admin.blogs.blogPostAdmin; + + var $blogPostWrapper = $('#CmsKitBlogPostsWrapper'); + + var dataTable = $("#BlogPostsTable").DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + scrollX: true, + ordering: true, + order: [[1, "desc"]], + ajax: abp.libs.datatables.createAjax(blogsService.getList), + columnDefs: [ + { + title: l("Details"), + targets: 0, + rowAction: { + items: [ + { + text: l('Edit'), + visible: abp.auth.isGranted('CmsKit.Blogs.Update'), + action: function (data) { + location.href = "/CmsKit/BlogPosts/Update/" + data.record.id + } + }, + { + text: l('Delete'), + visible: abp.auth.isGranted('CmsKit.Blogs.Delete'), + confirmMessage: function (data) { + return l("BlogPostDeletionConfirmationMessage", data.record.title) + }, + action: function (data) { + blogsService + .delete(data.record.id) + .then(function () { + abp.notify.info(l("SuccessfullyDeleted")); + dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { + title: l("Title"), + orderable: true, + data: "title" + }, + { + title: l("Slug"), + orderable: true, + data: "slug" + } + ] + })); + + $('#AbpContentToolbar button[name=CreateBlogPost]').on('click', function (e) { + e.preventDefault(); + window.location.href = "/CmsKit/BlogPosts/Create" + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js new file mode 100644 index 0000000000..60b618135b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js @@ -0,0 +1,180 @@ +$(function () { + + var l = abp.localization.getResource("CmsKit"); + + var $selectBlog = $('#BlogSelectionSelect'); + var $formUpdate = $('#form-blog-post-update'); + var $title = $('#ViewModel_Title'); + var $titleClone = $('#title-clone'); + var $slug = $('#ViewModel_Slug'); + var $buttonSubmit = $('#button-blog-post-update'); + var $contentValueInput = $('#ViewModel_Value'); + var $blogPostIdInput = $('#Id'); + var $contentIdInput = $('#ViewModel_Id'); + var $tagsInput = $('.tag-editor-form input[name=tags]'); + var $fileInput = $('#BlogPostCoverImage'); + + var UPPY_UPLOAD_ENDPOINT = "/api/cms-kit-admin/blogs/blog-posts/{0}/cover-image"; + var UPPY_FILE_ID = "uppy-upload-file"; + + $formUpdate.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; + + function initSelectBlog() { + $selectBlog.data('autocompleteApiUrl', '/api/cms-kit-admin/blogs/blogs'); + $selectBlog.data('autocompleteDisplayProperty', 'name'); + $selectBlog.data('autocompleteValueProperty', 'id'); + $selectBlog.data('autocompleteItemsProperty', 'items'); + $selectBlog.data('autocompleteFilterParamName', 'filter'); + + abp.dom.initializers.initializeAutocompleteSelects($selectBlog); + } + + initSelectBlog(); + + $formUpdate.on('submit', function (e) { + e.preventDefault(); + + if ($formUpdate.valid()) { + + abp.ui.setBusy(); + + $formUpdate.ajaxSubmit({ + success: function (result) { + submitEntityContent(); + }, + error: function (result) { + abp.ui.clearBusy(); abp.notify.error(result.responseJSON.error.message); + } + }); + } + }); + + $buttonSubmit.click(function (e) { + e.preventDefault(); + $formUpdate.submit(); + }); + + function submitEntityContent() { + + var contentId = $contentIdInput.val(); + var blogPostId = $blogPostIdInput.val(); + var contentValue = $contentValueInput.val(); + + if (contentId) { + volo.cmsKit.admin.contents.contentAdmin + .update(contentId, + { + value: contentValue + }) + .then(function (result) { + entityContentCallback(blogPostId); + }); + } + else { + volo.cmsKit.admin.contents.contentAdmin + .create({ + entityType: 'BlogPost', + entityId: blogPostId, + value: contentValue + }) + .then(function (result) { + entityContentCallback(blogPostId); + }); + } + } + + function entityContentCallback(blogPostId) { + if ($tagsInput.val()) { + submitEntityTags(blogPostId); + } + else { + submitCoverImage(blogPostId); + } + } + + function submitEntityTags(blogPostId) { + + var tags = $tagsInput.val().split(","); + + volo.cmsKit.admin.tags.entityTagAdmin + .setEntityTags({ + entityType: 'BlogPost', + entityId: blogPostId, + tags: tags + }) + .then(function (result) { + submitCoverImage(blogPostId); + }); + } + + function getUppyHeaders() { + var headers = {}; + headers[abp.security.antiForgery.tokenHeaderName] = abp.security.antiForgery.getToken(); + + return headers; + } + + function submitCoverImage(blogPostId) { + var UPPY_OPTIONS = { + endpoint: UPPY_UPLOAD_ENDPOINT.replace("{0}", blogPostId), + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + var file = $fileInput[0].files[0]; + + if (file) { + + UPPY.addFile({ + id: UPPY_FILE_ID, + name: file.name, // file name + type: file.type, // file type + data: file, // file + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error(l("UploadFailedMessage")); + } else { + finishSaving(); + } + }); + } + else { + finishSaving(); + } + } + + function finishSaving(result) { + abp.notify.success(l('SuccessfullySaved')); + abp.ui.clearBusy(); + location.href = "/Admin/BlogPosts/"; + } + + $titleClone.on('change paste keyup', function () { + $title.val($titleClone.val()); + }); + + $slug.on('change', function () { + reflectUrlChanges(); + }); + + function reflectUrlChanges() { + + var title = $slug.val(); + + var slugified = slugify(title); + + if (slugified != title) { + $slug.val(slugified, { + lower: true + }); + } + } +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml new file mode 100644 index 0000000000..d6cd7c26f5 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml @@ -0,0 +1,23 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal + +@inherits CmsKitAdminPageBase + +@model CreateModalModel + +@{ + Layout = null; +} + + + + + + + + + + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs new file mode 100644 index 0000000000..3681e04624 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs @@ -0,0 +1,44 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Blogs; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +{ + public class CreateModalModel : CmsKitAdminPageModel + { + protected IBlogAdminAppService BlogAdminAppService { get; } + + [BindProperty] + public CreateBlogViewModel ViewModel { get; set; } + + public CreateModalModel(IBlogAdminAppService blogAdminAppService) + { + BlogAdminAppService = blogAdminAppService; + } + + public async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + + await BlogAdminAppService.CreateAsync(dto); + + return NoContent(); + } + + [AutoMap(typeof(BlogDto), ReverseMap = true)] + public class CreateBlogViewModel + { + [Required] + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] + public string Name { get; set; } + + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxSlugLength))] + [Required] + public string Slug { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml new file mode 100644 index 0000000000..428131c596 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml @@ -0,0 +1,44 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal + +@inherits CmsKitAdminPageBase + +@model FeaturesModalModel + +@{ + Layout = null; +} + +
+ + + + + @for (int i = 0; i < Model.Items.Count; i++) + { +
+ + @if (Model.Items[i].IsAvailable) + { + + } + else + { +
+ +
+ } + +
+ } + +
+ +
+
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml.cs new file mode 100644 index 0000000000..c788e2cf4a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/FeaturesModal.cshtml.cs @@ -0,0 +1,77 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.Admin.Blogs; +using Volo.CmsKit.Admin.Web.Pages; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +{ + public class FeaturesModalModel : CmsKitAdminPageModel + { + [BindProperty(SupportsGet = true)] + [HiddenInput] + public Guid BlogId { get; set; } + + [BindProperty] + public List Items { get; set; } + + protected IBlogFeatureAdminAppService BlogFeatureAdminAppService { get; } + + public FeaturesModalModel(IBlogFeatureAdminAppService blogFeatureAdminAppService) + { + BlogFeatureAdminAppService = blogFeatureAdminAppService; + } + + public async Task OnGetAsync() + { + var blogFeatureDtos = await BlogFeatureAdminAppService.GetListAsync(BlogId); + + Items = ObjectMapper.Map, List>(blogFeatureDtos); + } + + public async Task OnPostAsync() + { + var dtos = ObjectMapper.Map, List>(Items); + + foreach (var item in dtos) + { + await BlogFeatureAdminAppService.SetAsync(BlogId, item); + } + + return NoContent(); + } + + [AutoMap(typeof(BlogFeatureDto), ReverseMap = true)] + [AutoMap(typeof(BlogFeatureInputDto), ReverseMap = true)] + public class BlogFeatureViewModel + { + private string featureName; + [HiddenInput] + public string FeatureName { get => featureName; set => SetFeatureName(value); } + + public bool IsEnabled { get; set; } + + public bool IsAvailable { get; private set; } + + private void SetFeatureName(string value) + { + featureName = value; + + IsAvailable = GlobalFeatureManager.Instance.Modules.CmsKit().GetFeatures().Any(a => a.FeatureName == FeatureName) ? + GlobalFeatureManager.Instance.IsEnabled(FeatureName) : + true; + + if (!IsAvailable) + { + IsEnabled = false; + } + } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml new file mode 100644 index 0000000000..9e51d54421 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -0,0 +1,38 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Admin.Web.Bundles +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar + +@inherits CmsKitAdminPageBase + +@model IndexModel + +@{ + PageLayout.Content.Title = L["Blogs"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Blogs.BlogsMenu; +} + +@section scripts { + + + + + + +} + +@section content_toolbar { + @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName }) +} + +
+ + + + + +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml.cs new file mode 100644 index 0000000000..77ca47493b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/Index.cshtml.cs @@ -0,0 +1,7 @@ +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +{ + public class IndexModel : CmsKitAdminPageModel + { + + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml new file mode 100644 index 0000000000..5a23933a0a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml @@ -0,0 +1,23 @@ +@page +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal + +@inherits CmsKitAdminPageBase + +@model UpdateModalModel + +@{ + Layout = null; +} + + + + + + + + + + + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs new file mode 100644 index 0000000000..57b51026b6 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs @@ -0,0 +1,60 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Blogs; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs +{ + public class UpdateModalModel : CmsKitAdminPageModel + { + protected IBlogAdminAppService BlogAdminAppService { get; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + [BindProperty] + public UpdateBlogViewModel ViewModel { get; set; } + + public UpdateModalModel(IBlogAdminAppService blogAdminAppService) + { + BlogAdminAppService = blogAdminAppService; + } + + public async Task OnGetAsync() + { + var blog = await BlogAdminAppService.GetAsync(Id); + + ViewModel = ObjectMapper.Map(blog); + } + + public async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + + await BlogAdminAppService.UpdateAsync(Id, dto); + + return NoContent(); + } + + [AutoMap(typeof(BlogDto), ReverseMap = true)] + public class UpdateBlogViewModel + { + [Required] + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] + public string Name { get; set; } + + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxSlugLength))] + [Required] + public string Slug { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/createModal.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/createModal.js new file mode 100644 index 0000000000..f42a96f500 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/createModal.js @@ -0,0 +1,47 @@ +var abp = abp || {}; +$(function () { + abp.modals.createBlog = function () { + var initModal = function (publicApi, args) { + + var $name = $('#ViewModel_Name'); + var $slug = $('#ViewModel_Slug'); + + var urlEdited = false; + + $name.on('change paste keyup', function () { + reflectUrlChanges(); + }); + + $slug.on('change', function () { + reflectUrlChanges(); + }); + + function reflectUrlChanges() { + var title = $name.val(); + + if (urlEdited) { + title = $slug.val(); + } + + var slugified = slugify(title, { + lower: true + }); + + if (slugified != $slug.val()) { + reflectedChange = true; + + $slug.val(slugified); + + reflectedChange = false; + } + } + + $slug.change(function () { + urlEdited = true; + }); + } + return { + initModal: initModal + }; + }; +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/index.js new file mode 100644 index 0000000000..ac1a7ce484 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/index.js @@ -0,0 +1,85 @@ + +$(function () { + var l = abp.localization.getResource("CmsKit"); + + var createModal = new abp.ModalManager({ viewUrl: abp.appPath + "CmsKit/Blogs/CreateModal", modalClass: 'createBlog' }); + var updateModal = new abp.ModalManager({ viewUrl: abp.appPath + "CmsKit/Blogs/UpdateModal", modalClass: 'updateBlog' }); + var featuresModal = new abp.ModalManager(abp.appPath + "CmsKit/Blogs/FeaturesModal"); + + var blogsService = volo.cmsKit.admin.blogs.blogAdmin; + + var dataTable = $("#BlogsTable").DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + scrollX: true, + ordering: true, + order: [[1, "desc"]], + ajax: abp.libs.datatables.createAjax(blogsService.getList), + columnDefs: [ + { + title: l("Details"), + targets: 0, + rowAction: { + items: [ + { + text: l('Features'), + visible: abp.auth.isGranted('CmsKit.Blogs.Features'), + action: function (data) { + featuresModal.open({ blogId: data.record.id }); + } + }, + { + text: l('Edit'), + visible: abp.auth.isGranted('CmsKit.Blogs.Update'), + action: function (data) { + updateModal.open({ id: data.record.id }); + } + }, + { + text: l('Delete'), + visible: abp.auth.isGranted('CmsKit.Blogs.Delete'), + confirmMessage: function (data) { + return l("BlogDeletionConfirmationMessage", data.record.name) + }, + action: function (data) { + blogsService + .delete(data.record.id) + .then(function () { + abp.notify.info(l("SuccessfullyDeleted")); + dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { + title: l("Name"), + orderable: true, + data: "name" + }, + { + title: l("Slug"), + orderable: true, + data: "slug" + } + ] + })); + + $('#AbpContentToolbar button[name=CreateBlog]').on('click', function (e) { + e.preventDefault(); + createModal.open(); + }); + + createModal.onResult(function () { + dataTable.ajax.reload(); + }); + + updateModal.onResult(function () { + dataTable.ajax.reload(); + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js new file mode 100644 index 0000000000..669a25ee8c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js @@ -0,0 +1,30 @@ +var abp = abp || {}; +$(function () { + abp.modals.updateBlog = function () { + var initModal = function (publicApi, args) { + debugger; + var $slug = $('#ViewModel_Slug'); + + $slug.on('change', function () { + reflectUrlChanges(); + }); + + function reflectUrlChanges() { + + var title = $slug.val(); + + var slugified = slugify(title); + + if (slugified != title) { + + $slug.val(slugified, { + lower: true + }); + } + } + } + return { + initModal: initModal + }; + }; +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml new file mode 100644 index 0000000000..ae2e11713c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml @@ -0,0 +1,108 @@ +@page "{id}" + +@using System.Globalization +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Comments +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Localization + +@inject IPageLayout PageLayout +@inject IHtmlLocalizer L + +@model DetailsModel + +@{ + PageLayout.Content.Title = L["Details"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.BreadCrumb.Add(L["Comments"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Comments.CommentsMenu; +} + +@section styles{ + + + +} + +@section scripts { + + + +} + +
+ + + + + + + + @L["EntityType"]: + @Model.CommentWithAuthorDto.EntityType + + + @L["EntityId"]: + @Model.CommentWithAuthorDto.EntityId + + + @L["CreationTime"]: + @Model.CommentWithAuthorDto.CreationTime.ToString(CultureInfo.CurrentUICulture) + + + @L["Username"]: + @Model.CommentWithAuthorDto.Author.Name + + @if (Model.CommentWithAuthorDto.RepliedCommentId.HasValue) + { + + @L["ReplyTo"]: + @Model.CommentWithAuthorDto.RepliedCommentId + + } + + @L["Text"]: + @Model.CommentWithAuthorDto.Text + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +

@L["RepliesToThisComment"]

+ + +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml.cs new file mode 100644 index 0000000000..7e8b757b1a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Details.cshtml.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.CmsKit.Admin.Comments; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Comments +{ + public class DetailsModel : CmsKitAdminPageModel + { + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + public string Author { get; set; } + + public DateTime? CreationStartDate { get; set; } + + public DateTime? CreationEndDate { get; set; } + + public CommentWithAuthorDto CommentWithAuthorDto { get; protected set; } + + protected readonly ICommentAdminAppService CommentAdminAppService; + + public DetailsModel(ICommentAdminAppService commentAdminAppService) + { + CommentAdminAppService = commentAdminAppService; + } + + public async Task OnGetAsync() + { + CommentWithAuthorDto = await CommentAdminAppService.GetAsync(Id); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml new file mode 100644 index 0000000000..8841d656b0 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml @@ -0,0 +1,71 @@ +@page + +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Comments +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Localization + +@inject IPageLayout PageLayout +@inject IHtmlLocalizer L + +@model IndexModel + +@{ + PageLayout.Content.Title = L["Comments"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Comments.CommentsMenu; + + var defaultStartDate = DateTime.Now.AddDays(-7).Date.ToShortDateString(); +} + +@section styles{ + + + +} + +@section scripts { + + + +} + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml.cs new file mode 100644 index 0000000000..4e8a03593b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/Index.cshtml.cs @@ -0,0 +1,17 @@ +using System; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Comments +{ + public class IndexModel : CmsKitAdminPageModel + { + public string EntityType { get; set; } + + public string EntityId { get; set; } + + public string Author { get; set; } + + public DateTime? CreationStartDate { get; set; } + + public DateTime? CreationEndDate { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.css b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.css new file mode 100644 index 0000000000..80c815e1c5 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.css @@ -0,0 +1,3 @@ +.datatableCell{ + cursor: pointer; +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.js new file mode 100644 index 0000000000..31e32d37e3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/details.js @@ -0,0 +1,146 @@ +$(function (){ + var l = abp.localization.getResource("CmsKit"); + + var commentsService = volo.cmsKit.admin.comments.commentAdmin; + + var detailsModal = new abp.ModalManager(abp.appPath + "CmsKit/Comments/DetailsModal"); + + $(".input-daterange") + .datepicker({ + todayBtn: "linked", + autoclose: true, + language: abp.localization.currentCulture.cultureName, + }) + .on("hide", function (e) { + e.stopPropagation(); + }); + + var filterForm = $('#CmsKitCommentsFilterForm'); + + var getFilter = function () { + var filterObj = filterForm.serializeFormToObject(); + + var startDate = luxon.DateTime.fromFormat( + filterObj.creationStartDate, + abp.localization.currentCulture.dateTimeFormat.shortDatePattern, + { locale: abp.localization.currentCulture.cultureName } + ); + if (!startDate.invalid) { + filterObj.creationStartDate = startDate.toFormat("yyyy-MM-dd"); + } + + var endDate = luxon.DateTime.fromFormat( + filterObj.creationEndDate, + abp.localization.currentCulture.dateTimeFormat.shortDatePattern, + { locale: abp.localization.currentCulture.cultureName } + ); + if (!endDate.invalid) { + filterObj.creationEndDate = endDate.toFormat("yyyy-MM-dd"); + } + + return filterObj; + }; + + var _dataTable = $('#CommentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + scrollX: true, + searching: false, + scrollCollapse: true, + ajax: abp.libs.datatables.createAjax(commentsService.getList, getFilter), + columnDefs: [ + { + width: "10%", + title: l("Actions"), + targets: 0, + orderable: false, + rowAction: { + items: [ + { + text: l('Details'), + action: function (data) { + window.location = abp.appPath + 'CmsKit/Comments/Details/' + data.record.id; + } + }, + { + text: l('Delete'), + visible: abp.auth.isGranted('CmsKit.Comments.Delete'), + confirmMessage: function (data) { + return l("CommentDeletionConfirmationMessage") + }, + action: function (data) { + commentsService + .delete(data.record.id) + .then(function () { + abp.notify.info(l("SuccessfullyDeleted")); + _dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { + width: "10%", + title: l("Username"), + orderable: false, + data: "author.userName", + render: function (data) { + if (data !== null) { + return GetFilterableDatatableContent('#Author', data); + } + return ""; + } + }, + { + title: l("Text"), + data: "text", + orderable: false, + render: function (data) { + data = data || ""; + + var maxChars = 64; + + if (data.length > maxChars) { + return ( + '' + + data.substring(0, maxChars) + + "..." + + "" + ); + } else { + return data; + } + } + }, + { + width: "15%", + title: l("CreationTime"), + data: "creationTime", + orderable: true, + dataFormat: "datetime" + } + ] + })); + + function GetFilterableDatatableContent(filterSelector, data){ + return '' + data + ''; + } + + $(document).on('click', '.datatableCell', function () { + var inputSelector = $(this).attr('data-field'); + var value = $(this).attr('data-val'); + + $(inputSelector).val(value); + + _dataTable.ajax.reload(); + }); + + filterForm.submit(function (e){ + e.preventDefault(); + _dataTable.ajax.reload(); + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.css b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.css new file mode 100644 index 0000000000..80c815e1c5 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.css @@ -0,0 +1,3 @@ +.datatableCell{ + cursor: pointer; +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js new file mode 100644 index 0000000000..c4453c1a9c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js @@ -0,0 +1,158 @@ +$(function (){ + var l = abp.localization.getResource("CmsKit"); + + var commentsService = volo.cmsKit.admin.comments.commentAdmin; + + var detailsModal = new abp.ModalManager(abp.appPath + "CmsKit/Comments/DetailsModal"); + + $(".input-daterange") + .datepicker({ + todayBtn: "linked", + autoclose: true, + language: abp.localization.currentCulture.cultureName, + }) + .on("hide", function (e) { + e.stopPropagation(); + }); + + var filterForm = $('#CmsKitCommentsFilterForm'); + + var getFilter = function () { + var filterObj = filterForm.serializeFormToObject(); + + var startDate = luxon.DateTime.fromFormat( + filterObj.creationStartDate, + abp.localization.currentCulture.dateTimeFormat.shortDatePattern, + { locale: abp.localization.currentCulture.cultureName } + ); + if (!startDate.invalid) { + filterObj.creationStartDate = startDate.toFormat("yyyy-MM-dd"); + } + + var endDate = luxon.DateTime.fromFormat( + filterObj.creationEndDate, + abp.localization.currentCulture.dateTimeFormat.shortDatePattern, + { locale: abp.localization.currentCulture.cultureName } + ); + if (!endDate.invalid) { + filterObj.creationEndDate = endDate.toFormat("yyyy-MM-dd"); + } + + return filterObj; + }; + + var _dataTable = $('#CommentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + scrollX: true, + searching: false, + scrollCollapse: true, + ajax: abp.libs.datatables.createAjax(commentsService.getList, getFilter), + columnDefs: [ + { + width: "10%", + title: l("Actions"), + targets: 0, + orderable: false, + rowAction: { + items: [ + { + text: l('Details'), + action: function (data) { + window.location = abp.appPath + 'CmsKit/Comments/Details/' + data.record.id; + } + }, + { + text: l('Delete'), + visible: abp.auth.isGranted('CmsKit.Comments.Delete'), + confirmMessage: function (data) { + return l("CommentDeletionConfirmationMessage") + }, + action: function (data) { + commentsService + .delete(data.record.id) + .then(function () { + abp.notify.info(l("SuccessfullyDeleted")); + _dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { + width: "10%", + title: l("Username"), + orderable: false, + data: "author.userName", + render: function (data) { + if (data !== null) { + return GetFilterableDatatableContent('#Author', data); + } + return ""; + } + }, + { + width: "15%", + title: l("EntityType"), + orderable: false, + data: "entityType", + render: function (data) { + if (data !== null) { + return GetFilterableDatatableContent('#EntityType', data); + } + return ""; + } + }, + { + title: l("Text"), + data: "text", + orderable: false, + render: function (data) { + data = data || ""; + + var maxChars = 64; + + if (data.length > maxChars) { + return ( + '' + + data.substring(0, maxChars) + + "..." + + "" + ); + } else { + return data; + } + } + }, + { + width: "15%", + title: l("CreationTime"), + data: "creationTime", + orderable: true, + dataFormat: "datetime" + } + ] + })); + + function GetFilterableDatatableContent(filterSelector, data){ + return '' + data + ''; + } + + $(document).on('click', '.datatableCell', function () { + var inputSelector = $(this).attr('data-field'); + var value = $(this).attr('data-val'); + + $(inputSelector).val(value); + + _dataTable.ajax.reload(); + }); + + filterForm.submit(function (e){ + e.preventDefault(); + _dataTable.ajax.reload(); + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs new file mode 100644 index 0000000000..bba95a0e45 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs @@ -0,0 +1,44 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.ContentEditor +{ + [Widget( + StyleTypes = new[] + { + typeof(TuiEditorStyleContributor) + }, + ScriptTypes = new[] + { + typeof(TuiEditorScriptContributor), + typeof(UppyScriptContributor) + }, + ScriptFiles = new[] + { + "/Pages/CmsKit/Contents/Components/ContentEditor/default.js" + })] + public class ContentEditorViewComponent : AbpViewComponent + { + public async Task InvokeAsync(string inputId) + { + return View( + "~/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml", + new ContentEditorViewModel(inputId)); + } + + public class ContentEditorViewModel + { + public ContentEditorViewModel(string inputId) + { + InputId = inputId; + } + + public string InputId { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml new file mode 100644 index 0000000000..cde532b02c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml @@ -0,0 +1,7 @@ +@using System.Globalization +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.ContentEditor + +@model ContentEditorViewComponent.ContentEditorViewModel + +
+
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js new file mode 100644 index 0000000000..a6ccbbde65 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js @@ -0,0 +1,80 @@ +$(function () { + var fileUploadUri = "/api/cms-kit-admin/media"; + var fileUriPrefix = "/api/cms-kit/media/"; + + var editorDataKey = "tuiEditor"; + + initAllEditors(); + + function initAllEditors() { + $('.content-editor').each(function (i, item) { + initEditor(item); + }); + } + + function initEditor(element) { + var $editorContainer = $(element); + var inputName = $editorContainer.data('input-id'); + var $editorInput = $('#' + inputName); + var initialValue = $editorInput.val(); + + var editor = $editorContainer.tuiEditor({ + usageStatistics: false, + useCommandShortcut: true, + initialValue: initialValue, + previewStyle: 'tab', + height: "25em", + minHeight: "25em", + initialEditType: initialValue ? 'wysiwyg' : 'markdown', + language: $editorContainer.data("language"), + hooks: { + addImageBlobHook: uploadFile, + }, + events: { + change: function (_val) { + $editorInput.val(editor.getHtml()); + $editorInput.trigger("change"); + } + } + }).data(editorDataKey); + } + + function getUppyHeaders() { + var headers = {}; + headers[abp.security.antiForgery.tokenHeaderName] = abp.security.antiForgery.getToken(); + + return headers; + } + + function uploadFile(blob, callback, source) { + var UPPY_OPTIONS = { + endpoint: fileUploadUri, + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + UPPY.addFile({ + id: "content-file", + name: blob.name, + type: blob.type, + data: blob, + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error("File upload failed"); + } else { + var mediaDto = result.successful[0].response.body; + var fileUrl = (fileUriPrefix + mediaDto.id); + + callback(fileUrl, mediaDto.name); + } + }); + } +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs new file mode 100644 index 0000000000..891fe50bd1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc; +using System; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +{ + public class ContentViewModel + { + public ContentViewModel(string entityType, string entityId, string value = null, Guid? id = null) + { + EntityType = entityType; + EntityId = entityId; + Value = value; + Id = id; + } + + [HiddenInput] + public string EntityType { get; set; } + + [HiddenInput] + public string EntityId { get; set; } + + [HiddenInput] + public string Value { get; set; } + + [HiddenInput] + public Guid? Id { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml new file mode 100644 index 0000000000..ba8132ccc1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml @@ -0,0 +1,27 @@ +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.ContentEditor +@using Volo.CmsKit.Localization +@using Microsoft.Extensions.Localization + +@model EntityContentEditorViewComponent.EntityContentEditorViewModel + +@inject IStringLocalizer L + +@if (Model.DisplaySubmitButton) +{ + + + + + + +} +else +{ + + + + +} + +@await Component.InvokeAsync(typeof(ContentEditorViewComponent), new { inputId = Html.IdFor(m => m.ViewModel.Value) }) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs new file mode 100644 index 0000000000..44db557f16 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs @@ -0,0 +1,65 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; +using Volo.Abp.Domain.Entities; +using Volo.CmsKit.Admin.Contents; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +{ + [Widget( + ScriptFiles = new[] + { + "/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js" + })] + public class EntityContentEditorViewComponent : AbpViewComponent + { + private readonly IContentAdminAppService contentAdminAppService; + + public EntityContentEditorViewComponent(IContentAdminAppService contentAdminAppService) + { + this.contentAdminAppService = contentAdminAppService; + } + + public async Task InvokeAsync(string entityType, string entityId, bool displaySubmitButton = true) + { + var viewModel = new ContentViewModel(entityType, entityId); + + try + { + if (entityId != null) + { + var content = await contentAdminAppService.GetAsync(entityType, entityId); + viewModel.Value = content.Value; + viewModel.Id = content.Id; + } + } + catch (EntityNotFoundException) + { + // Initialize editor even content doesn't exist. + } + + return View( + "~/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml", + new EntityContentEditorViewModel(viewModel, displaySubmitButton)); + } + + public class EntityContentEditorViewModel + { + public ContentViewModel ViewModel { get; set; } + + public bool DisplaySubmitButton { get; set; } + + public EntityContentEditorViewModel(ContentViewModel viewModel, bool displaySubmitButton) + { + ViewModel = viewModel; + DisplaySubmitButton = displaySubmitButton; + } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js new file mode 100644 index 0000000000..34f84f8419 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js @@ -0,0 +1,34 @@ +$(function () { + + $entityContentEditors = $('.form-entity-content-editor'); + + var contentAdminService = volo.cmsKit.admin.contents.contentAdmin; + + $entityContentEditors.on('submit', function (e, obj) { + e.preventDefault(); + + var $form = $(e.currentTarget); + + if ($form.valid()) { + + var data = form.serializeFormToObject().viewModel; + + abp.ui.setBusy(e); + if (data.id) { + contentAdminService + .update(data.id, data) + .then(function (result) { + abp.ui.clearBusy(); + }); + + } + else { + contentAdminService + .create(data) + .then(function (result) { + abp.ui.clearBusy(); + }); + } + } + }) +}) \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml new file mode 100644 index 0000000000..1330dde48a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml @@ -0,0 +1,44 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages + +@inherits CmsKitAdminPageBase + +@model CreateModel + +@{ + PageLayout.Content.Title = L["Pages"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Pages.PagesMenu; +} + +@section scripts { + + + + +} + + + + + + + + + + + @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new + { + entityType = "Page", + displaySubmitButton = false + }) + + + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs new file mode 100644 index 0000000000..a4d90abafb --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs @@ -0,0 +1,47 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Pages; +using Volo.CmsKit.Admin.Web.Pages; +using Volo.CmsKit.Pages; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages +{ + public class CreateModel : CmsKitAdminPageModel + { + protected readonly IPageAdminAppService pageAdminAppService; + + [BindProperty] + public CreatePageViewModel ViewModel { get; set; } + + public CreateModel(IPageAdminAppService pageAdminAppService) + { + this.pageAdminAppService = pageAdminAppService; + } + + public async Task OnPostAsync() + { + var createInput = ObjectMapper.Map(ViewModel); + + var created = await pageAdminAppService.CreateAsync(createInput); + + return new OkObjectResult(created); + } + + [AutoMap(typeof(CreatePageInputDto), ReverseMap = true)] + public class CreatePageViewModel + { + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] + [Required] + public string Title { get; set; } + + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] + [Required] + [DynamicFormIgnore] + public string Slug { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml new file mode 100644 index 0000000000..59fa975e24 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml @@ -0,0 +1,40 @@ +@page + +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageSearchBox +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages + +@inherits CmsKitAdminPageBase + +@model IndexModel + +@{ + PageLayout.Content.Title = L["Pages"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Pages.PagesMenu; +} + +@section scripts { + +} + +@section content_toolbar { + @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new {pageName = typeof(IndexModel).FullName}) +} + +
+ + + + + @await Component.InvokeAsync(typeof(AbpPageSearchBoxViewComponent)) + + + + + + +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml.cs new file mode 100644 index 0000000000..9c4eea078b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml.cs @@ -0,0 +1,11 @@ + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages +{ + public class IndexModel : CmsKitAdminPageModel + { + public void OnGet() + { + + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml new file mode 100644 index 0000000000..90f043e89e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml @@ -0,0 +1,45 @@ +@page "{Id}" + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages +@using Volo.CmsKit.Admin.Web.Pages + +@inherits CmsKitAdminPageBase + +@model UpdateModel + +@{ + PageLayout.Content.Title = L["Pages"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Pages.PagesMenu; +} + + +@section scripts { + +} + + + + + + + + + + + + + @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new + { + entityType = "Page", + entityId = Model.Id.ToString(), + displaySubmitButton = false + }) + + + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs new file mode 100644 index 0000000000..e0b2d8b1b1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs @@ -0,0 +1,62 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Pages; +using Volo.CmsKit.Pages; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages +{ + public class UpdateModel : CmsKitAdminPageModel + { + [BindProperty(SupportsGet = true)] + [HiddenInput] + public Guid Id { get; set; } + + [BindProperty] + public UpdatePageViewModel ViewModel { get; set; } + + protected readonly IPageAdminAppService pageAdminAppService; + + public UpdateModel(IPageAdminAppService pageAdminAppService) + { + this.pageAdminAppService = pageAdminAppService; + } + + public async Task OnGetAsync() + { + var dto = await pageAdminAppService.GetAsync(Id); + + ViewModel = ObjectMapper.Map(dto); + } + + public async Task OnPostAsync() + { + var updateInput = ObjectMapper.Map(ViewModel); + + await pageAdminAppService.UpdateAsync(Id, updateInput); + + return NoContent(); + } + + [AutoMap(typeof(PageDto))] + [AutoMap(typeof(UpdatePageInputDto), ReverseMap = true)] + public class UpdatePageViewModel + { + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] + [Required] + public string Title { get; set; } + + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] + [Required] + [DynamicFormIgnore] + public string Slug { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js new file mode 100644 index 0000000000..d0a27aefe3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js @@ -0,0 +1,72 @@ +$(function () { + var l = abp.localization.getResource("CmsKit"); + + var $formCreate = $('#form-page-create'); + var $title = $('#ViewModel_Title'); + var $slug = $('#ViewModel_Slug'); + var $buttonSubmit = $('#button-page-create'); + var $pageContentInput = $('#ViewModel_Value'); + + $formCreate.on('submit', function (e) { + e.preventDefault(); + + if ($formCreate.valid()) { + + abp.ui.setBusy(); + + $formCreate.ajaxSubmit({ + success: function (result) { + submitEntityContent(result.id); + } + }); + } + }); + + $buttonSubmit.click(function (e) { + e.preventDefault(); + $formCreate.submit(); + }); + + function submitEntityContent(pageId) { + volo.cmsKit.admin.contents.contentAdmin + .create( + { + entityType: 'Page', + entityId: pageId, + value: $pageContentInput.val() + }) + .then(function (result) { + finishSaving(); + }); + } + + function finishSaving() { + abp.notify.success(l('SuccessfullySaved')); + abp.ui.clearBusy(); + location.href = "/CmsKit/Pages/"; + } + + var slugEdited = false; + + $title.on('change paste keyup', function () { + var title = $title.val(); + + if (slugEdited) { + title = $slug.val(); + } + + var slugified = slugify(title, { + lower: true + }); + + if (slugified != $slug.val()) { + reflectedChange = true; + $slug.val(slugified); + reflectedChange = false; + } + }); + + $slug.change(function () { + slugEdited = true; + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js new file mode 100644 index 0000000000..4d4ea4c9e3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js @@ -0,0 +1,81 @@ +$(function (){ + var l = abp.localization.getResource("CmsKit"); + + var pagesService = volo.cmsKit.admin.pages.pageAdmin; + + var getFilter = function () { + return { + filter: $('#CmsKitPagesWrapper input.page-search-filter-text').val() + }; + }; + + var _dataTable = $("#PagesTable").DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + scrollX: true, + ordering: true, + order: [[3, "desc"]], + ajax: abp.libs.datatables.createAjax(pagesService.getList, getFilter), + columnDefs: [ + { + title: l("Details"), + targets: 0, + rowAction: { + items: [ + { + text: l('Edit'), + visible: abp.auth.isGranted('CmsKit.Pages.Update'), + action: function (data) { + location.href = '/CmsKit/Pages/Update/' + data.record.id; + } + }, + { + text: l('Delete'), + visible: abp.auth.isGranted('CmsKit.Pages.Delete'), + confirmMessage: function (data) { + return l("PageDeletionConfirmationMessage") + }, + action: function (data) { + pagesService + .delete(data.record.id) + .then(function () { + abp.notify.info(l("SuccessfullyDeleted")); + _dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { + title: l("Title"), + orderable: true, + data: "title" + }, + { + title: l("Slug"), + orderable: true, + data: "slug" + }, + { + title: l("CreationTime"), + orderable: true, + data: 'creationTime' + } + ] + })); + + $('#CmsKitPagesWrapper form.page-search-form').submit(function (e) { + e.preventDefault(); + _dataTable.ajax.reload(); + }); + + $('#AbpContentToolbar button[name=CreatePage]').on('click', function (e) { + e.preventDefault(); + window.location.href = "/CmsKit/Pages/Create" + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js new file mode 100644 index 0000000000..3f8b971866 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js @@ -0,0 +1,65 @@ +$(function () { + + var l = abp.localization.getResource("CmsKit"); + + var $formUpdate = $('#form-page-update'); + var $buttonSubmit = $('#button-page-update'); + var $pageContentInput = $('#ViewModel_Value'); + var $pageIdInput = $('#Id'); + var $contentIdInput = $('#ViewModel_Id'); + + $formUpdate.on('submit', function (e) { + e.preventDefault(); + + if ($formUpdate.valid()) { + + abp.ui.setBusy(); + + $formUpdate.ajaxSubmit({ + success: function (result) { + submitEntityContent(); + } + }); + } + }); + + $buttonSubmit.click(function (e) { + e.preventDefault(); + $formUpdate.submit(); + }); + + function submitEntityContent() { + + var contentId = $contentIdInput.val(); + var pageId = $pageIdInput.val(); + var contentValue = $pageContentInput.val(); + + if (contentId) { + volo.cmsKit.admin.contents.contentAdmin + .update(contentId, + { + value: contentValue + }) + .then(function (result) { + finishSaving(result); + }); + } + else { + volo.cmsKit.admin.contents.contentAdmin + .create({ + entityType: 'Page', + entityId: pageId, + value: contentValue + }) + .then(function (result) { + finishSaving(result); + }); + } + } + + function finishSaving(result) { + abp.notify.success(l('SuccessfullySaved')); + abp.ui.clearBusy(); + location.href = "/CmsKit/Pages/"; + } +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/Default.cshtml new file mode 100644 index 0000000000..b647de10a8 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/Default.cshtml @@ -0,0 +1,22 @@ +@model TagEditorViewComponent.TagEditorViewModel + +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor +@using Volo.CmsKit.Localization +@using Microsoft.Extensions.Localization + +@inject IStringLocalizer L + +
+ +
+ + +
+ + @if (Model.DisplaySubmitButton) + { + + + + } +
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/TagEditorViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/TagEditorViewComponent.cs new file mode 100644 index 0000000000..3c77f8c0c2 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/TagEditorViewComponent.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; +using Volo.CmsKit.Tags; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor +{ + [Widget( + ScriptFiles = new[] + { + "/Pages/CmsKit/Tags/Components/TagEditor/default.js" + })] + public class TagEditorViewComponent : AbpViewComponent + { + protected ITagAppService TagAppService { get; } + + public TagEditorViewComponent(ITagAppService tagAppService) + { + TagAppService = tagAppService; + } + + public async Task InvokeAsync(string entityType, string entityId, bool displaySubmitButton = true) + { + var tags = + entityId.IsNullOrWhiteSpace() ? + new List() : + await TagAppService.GetAllRelatedTagsAsync(entityType, entityId); + + return View("~/Pages/CmsKit/Tags/Components/TagEditor/Default.cshtml", new TagEditorViewModel + { + EntityId = entityId, + EntityType = entityType, + Tags = tags, + DisplaySubmitButton = displaySubmitButton + }); + } + + public class TagEditorViewModel + { + public string EntityType { get; set; } + public string EntityId { get; set; } + public List Tags { get; set; } + public bool DisplaySubmitButton { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js new file mode 100644 index 0000000000..debb0ed084 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Components/TagEditor/default.js @@ -0,0 +1,26 @@ +$(function () { + + var $tagEditorForms = $('.tag-editor-form'); + + $tagEditorForms.on('submit', function (e) { + e.preventDefault(); + + var $form = $(e.currentTarget); + + if ($form.valid()) { + + abp.ui.setBusy(); + + var entityId = $form.data('entity-id'); + var entityType = $form.data('entity-type'); + var tags = $form.find('input').val().split(","); + + volo.cmsKit.admin.tags.entityTagAdmin + .setEntityTags({ + entityId: entityId, + entityType: entityType, + tags: tags + }) + } + }) +}) \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml new file mode 100644 index 0000000000..35ca3df9da --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml @@ -0,0 +1,23 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using Volo.CmsKit.Localization + +@inject IHtmlLocalizer L + +@model CreateModalModel + +@{ + Layout = null; +} + + + + + + + + + + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml.cs new file mode 100644 index 0000000000..5ce3d0cb1f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml.cs @@ -0,0 +1,58 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Tags; +using Volo.CmsKit.Tags; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags +{ + public class CreateModalModel : CmsKitAdminPageModel + { + protected ITagAdminAppService TagAdminAppService { get; } + + [BindProperty] + public TagCreateViewModel ViewModel { get; set; } + + public List TagDefinitions { get; set; } + + public CreateModalModel(ITagAdminAppService tagAdminAppService) + { + TagAdminAppService = tagAdminAppService; + } + + public async Task OnGetAsync() + { + var definitions = await TagAdminAppService.GetTagDefinitionsAsync(); + + TagDefinitions = definitions.Select(s => new SelectListItem(s.DisplayName, s.EntityType)).ToList(); + } + + public async Task OnPostAsync() + { + var tagCreateDto = ObjectMapper.Map(ViewModel); + + await TagAdminAppService.CreateAsync(tagCreateDto); + + return NoContent(); + } + + [AutoMap(typeof(TagCreateDto), ReverseMap = true)] + public class TagCreateViewModel + { + [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxEntityTypeLength))] + [Required] + [SelectItems(nameof(TagDefinitions))] + public string EntityType { get; set; } + + [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxNameLength))] + [Required] + public string Name { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml new file mode 100644 index 0000000000..3146915cef --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml @@ -0,0 +1,24 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using Volo.CmsKit.Localization + +@inject IHtmlLocalizer L +@model EditModalModel + +@{ + Layout = null; +} + + + + + + + + + + + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml.cs new file mode 100644 index 0000000000..7845a1b474 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml.cs @@ -0,0 +1,54 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Validation; +using Volo.CmsKit.Admin.Tags; +using Volo.CmsKit.Tags; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags +{ + public class EditModalModel : CmsKitAdminPageModel + { + protected ITagAdminAppService TagAdminAppService { get; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + [BindProperty] + public TagEditViewModel ViewModel { get; set; } + + public EditModalModel(ITagAdminAppService tagAdminAppService) + { + this.TagAdminAppService = tagAdminAppService; + } + + public async Task OnGetAsync() + { + var dto = await TagAdminAppService.GetAsync(Id); + + ViewModel = ObjectMapper.Map(dto); + } + + public async Task OnPostAsync() + { + var tagDto = ObjectMapper.Map(ViewModel); + await TagAdminAppService.UpdateAsync(Id, tagDto); + return NoContent(); + } + + [AutoMap(typeof(TagDto))] + [AutoMap(typeof(TagUpdateDto), ReverseMap = true)] + public class TagEditViewModel + { + [Required] + [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxNameLength))] + public string Name { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml new file mode 100644 index 0000000000..b568c2737c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml @@ -0,0 +1,38 @@ +@page + +@using Volo.CmsKit.Admin.Web.Pages +@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags +@using Volo.CmsKit.Admin.Web.Menus +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar +@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageSearchBox + +@inherits CmsKitAdminPageBase + +@model IndexModel + +@{ + PageLayout.Content.Title = L["Tags"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); + PageLayout.Content.MenuItemName = CmsKitAdminMenus.Tags.TagsMenu; +} +@section scripts { + +} + +@section content_toolbar { + @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName }) +} + +
+ + + + + @await Component.InvokeAsync(typeof(AbpPageSearchBoxViewComponent)) + + + + + +
+ diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml.cs new file mode 100644 index 0000000000..268e61ab0e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.cshtml.cs @@ -0,0 +1,8 @@ +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags +{ + public class IndexModel : CmsKitAdminPageModel + { + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.js new file mode 100644 index 0000000000..85e91908d6 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/Index.js @@ -0,0 +1,83 @@ +$(function () { + var l = abp.localization.getResource("CmsKit"); + + var createModal = new abp.ModalManager(abp.appPath + "CmsKit/Tags/CreateModal"); + var updateModal = new abp.ModalManager(abp.appPath + "CmsKit/Tags/EditModal"); + + var service = volo.cmsKit.admin.tags.tagAdmin; + + var getFilter = function () { + return { + filter: $('#CmsKitTagsWrapper input.page-search-filter-text').val() + }; + }; + + let dataTable = $("#TagsTable").DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + scrollX: true, + ordering: false, + ajax: abp.libs.datatables.createAjax(service.getList, getFilter), + columnDefs: [ + { + title: l("Actions"), + rowAction: { + items: [ + { + text: l("Edit"), + visible: abp.auth.isGranted('CmsKit.Tags.Update'), + action: function (data) { + updateModal.open({ id: data.record.id }); + } + }, + { + text: l("Delete"), + visible: abp.auth.isGranted('CmsKit.Tags.Delete'), + confirmMessage: function (data) { + return l("TagDeletionConfirmationMessage", data.record.name) + }, + action: function (data) { + service + .delete(data.record.id) + .then(function () { + abp.notify.info(l("SuccessfullyDeleted")); + dataTable.ajax.reload(null, false); + }); + } + } + ] + } + }, + { + title: l("EntityType"), + data: "entityType" + }, + { + title: l("Name"), + data: "name" + } + ] + })); + + $('#CmsKitTagsWrapper form.page-search-form').on('submit', function (e) { + e.preventDefault(); + dataTable.ajax.reload(); + }); + + $('#AbpContentToolbar button[name=NewButton]').on('click', function (e) { + e.preventDefault(); + createModal.open(); + }); + + createModal.onResult(function () { + dataTable.ajax.reload(); + }); + + updateModal.onResult(function () { + dataTable.ajax.reload(); + }); +}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKitAdminPageBase.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKitAdminPageBase.cs new file mode 100644 index 0000000000..b45176453a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKitAdminPageBase.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Mvc.Razor.Internal; +using Microsoft.Extensions.Localization; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Layout; +using Volo.CmsKit.Localization; + +namespace Volo.CmsKit.Admin.Web.Pages +{ + public class CmsKitAdminPageBase : Microsoft.AspNetCore.Mvc.RazorPages.Page + { + [RazorInject] public IStringLocalizer L { get; set; } + + [RazorInject] public IPageLayout PageLayout { get; set; } + + public override Task ExecuteAsync() + { + return Task.CompletedTask; // Will be overriden by razor pages. (.cshtml) + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Volo.CmsKit.Admin.Web.csproj b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Volo.CmsKit.Admin.Web.csproj index d1d1f28fac..9ba777ace5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Volo.CmsKit.Admin.Web.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Volo.CmsKit.Admin.Web.csproj @@ -1,4 +1,4 @@ - + From f4e324f486458fcd959d0214616e4ed5259346d6 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 26 Feb 2021 14:49:25 +0300 Subject: [PATCH 005/101] added slugify to test proj --- .../wwwroot/libs/slugify/LICENSE | 21 +++++ .../wwwroot/libs/slugify/README.md | 90 +++++++++++++++++++ .../wwwroot/libs/slugify/package.json | 40 +++++++++ .../wwwroot/libs/slugify/slugify.d.ts | 23 +++++ .../wwwroot/libs/slugify/slugify.js | 66 ++++++++++++++ .../host/Volo.CmsKit.Web.Unified/yarn.lock | 5 ++ 6 files changed, 245 insertions(+) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/LICENSE create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/README.md create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/package.json create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.d.ts create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.js diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/LICENSE b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/LICENSE new file mode 100644 index 0000000000..ebbb2c2b97 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Simeon Velichkov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/README.md b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/README.md new file mode 100644 index 0000000000..cc5783b32e --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/README.md @@ -0,0 +1,90 @@ + +# slugify + +[![npm-version]][npm] [![travis-ci]][travis] [![coveralls-status]][coveralls] + +```js +var slugify = require('slugify') + +slugify('some string') // some-string + +// if you prefer something other than '-' as separator +slugify('some string', '_') // some_string +``` + +- Vanilla ES5 JavaScript +- No dependencies +- Coerces foreign symbols to their English equivalent (check out the [charMap][charmap] for more details) +- Works in the browser (window.slugify) and AMD/CommonJS-flavored module loaders + +## Options + +```js +slugify('some string', { + replacement: '-', // replace spaces with replacement character, defaults to `-` + remove: undefined, // remove characters that match regex, defaults to `undefined` + lower: false, // convert to lower case, defaults to `false` + strict: false, // strip special characters except replacement, defaults to `false` + locale: 'vi' // language code of the locale to use +}) +``` + +## Remove + +For example, to remove `*+~.()'"!:@` from the result slug, you can use `slugify('..', {remove: /[*+~.()'"!:@]/g})`. + +## Locales + +The main `charmap.json` file contains all known characters and their transliteration. All new characters should be added there first. In case you stumble upon a character already set in `charmap.json`, but not transliterated correctly according to your language, then you have to add those characters in `locales.json` to override the already existing transliteration in `charmap.json`, but for your locale only. + +You can get the correct language code of your language from [here](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). + +## Extend + +Out of the box `slugify` comes with support for a handful of Unicode symbols. For example the `☢` (radioactive) symbol is not defined in the [`charMap`][charmap] and therefore it will be stripped by default: + +```js +slugify('unicode ♥ is ☢') // unicode-love-is +``` + +However you can extend the supported symbols, or override the existing ones with your own: + +```js +slugify.extend({'☢': 'radioactive'}) +slugify('unicode ♥ is ☢') // unicode-love-is-radioactive +``` + +Keep in mind that the `extend` method extends/overrides the default `charMap` for the entire process. In case you need a fresh instance of the slugify's `charMap` object you have to clean up the module cache first: + +```js +delete require.cache[require.resolve('slugify')] +var slugify = require('slugify') +``` + +## Contribute + +1. Add chars to `charmap.json` +2. Run tests `npm test` +3. The tests will build the charmap in `index.js` and will sort the `charmap.json` +4. Commit **all** modified files + +--- + +> This module was originally a vanilla javascript port of [node-slug][node-slug].
+> Note that the original [slug][slug] module has been ported to vanilla javascript too.
+> One major difference between the two modules is that `slugify` does not depend on the external [unicode][unicode] module. + + + [npm-version]: https://img.shields.io/npm/v/slugify.svg?style=flat-square (NPM Package Version) + [travis-ci]: https://img.shields.io/travis/simov/slugify/master.svg?style=flat-square (Build Status - Travis CI) + [coveralls-status]: https://img.shields.io/coveralls/simov/slugify.svg?style=flat-square (Test Coverage - Coveralls) + + [npm]: https://www.npmjs.com/package/slugify + [travis]: https://travis-ci.org/simov/slugify + [coveralls]: https://coveralls.io/r/simov/slugify?branch=master + + [node-slug]: https://github.com/dodo/node-slug + [slug]: https://www.npmjs.com/package/slug + [unicode]: https://www.npmjs.com/package/unicode + [index]: https://github.com/simov/slugify/blob/master/index.js + [charmap]: https://github.com/simov/slugify/blob/master/config/charmap.json diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/package.json new file mode 100644 index 0000000000..5f5ea9dd61 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/package.json @@ -0,0 +1,40 @@ +{ + "name": "slugify", + "version": "1.4.6", + "description": "Slugifies a String", + "keywords": [ + "slugify", + "slug", + "url", + "urlify" + ], + "license": "MIT", + "homepage": "https://github.com/simov/slugify", + "author": "Simeon Velichkov (https://simov.github.io)", + "repository": { + "type": "git", + "url": "https://github.com/simov/slugify.git" + }, + "devDependencies": { + "coveralls": "^3.1.0", + "mocha": "^7.2.0", + "nyc": "^15.1.0" + }, + "main": "./slugify.js", + "files": [ + "LICENSE", + "README.md", + "slugify.d.ts", + "slugify.js" + ], + "types": "slugify.d.ts", + "scripts": { + "build": "node bin/build", + "test:ci": "npx mocha --recursive", + "test:cov": "npx nyc --reporter=lcov --reporter=text-summary mocha -- --recursive", + "test": "npm run build && npm run test:ci" + }, + "engines": { + "node": ">=8.0.0" + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.d.ts b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.d.ts new file mode 100644 index 0000000000..ade1592584 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.d.ts @@ -0,0 +1,23 @@ +declare module slugify { + type ExtendArgs = { + [key: string]: any; + } + + export function extend (args: ExtendArgs): void; +} + +declare function slugify( + string: string, + options?: + | { + replacement?: string; + remove?: RegExp; + lower?: boolean; + strict?: boolean; + locale?: string; + } + | string, + +): string; + +export default slugify; diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.js new file mode 100644 index 0000000000..692c8e8d69 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/slugify/slugify.js @@ -0,0 +1,66 @@ + +;(function (name, root, factory) { + if (typeof exports === 'object') { + module.exports = factory() + module.exports['default'] = factory() + } + /* istanbul ignore next */ + else if (typeof define === 'function' && define.amd) { + define(factory) + } + else { + root[name] = factory() + } +}('slugify', this, function () { + var charMap = JSON.parse('{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","‘":"\'","’":"\'","“":"\\\"","”":"\\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial"}') + var locales = JSON.parse('{"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue"},"vi":{"Đ":"D","đ":"d"}}') + + function replace (string, options) { + if (typeof string !== 'string') { + throw new Error('slugify: string argument expected') + } + + options = (typeof options === 'string') + ? {replacement: options} + : options || {} + + var locale = locales[options.locale] || {} + + var replacement = options.replacement === undefined ? '-' : options.replacement + + var slug = string.split('') + // replace characters based on charMap + .reduce(function (result, ch) { + return result + (locale[ch] || charMap[ch] || ch) + // remove not allowed characters + .replace(options.remove || /[^\w\s$*_+~.()'"!\-:@]+/g, '') + }, '') + // trim leading/trailing spaces + .trim() + // convert spaces to replacement character + // also remove duplicates of the replacement character + .replace(new RegExp('[\\s' + replacement + ']+', 'g'), replacement) + + if (options.lower) { + slug = slug.toLowerCase() + } + + if (options.strict) { + // remove anything besides letters, numbers, and the replacement char + slug = slug + .replace(new RegExp('[^a-zA-Z0-9' + replacement + ']', 'g'), '') + // remove duplicates of the replacement character + .replace(new RegExp('[\\s' + replacement + ']+', 'g'), replacement) + } + + return slug + } + + replace.extend = function (customMap) { + for (var key in customMap) { + charMap[key] = customMap[key] + } + } + + return replace +})) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock index bf9985a470..6a5bf91700 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock @@ -3032,6 +3032,11 @@ signal-exit@^3.0.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +slugify@1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.4.6.tgz#ef288d920a47fb01c2be56b3487b6722f5e34ace" + integrity sha512-ZdJIgv9gdrYwhXqxsH9pv7nXxjUEyQ6nqhngRxoAAOlmMGA28FDq5O4/5US4G2/Nod7d1ovNcgURQJ7kHq50KQ== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" From 6fbb6bb7550a18cd503b46c0353557b6ae645af5 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 26 Feb 2021 15:29:48 +0300 Subject: [PATCH 006/101] CmsKit - Fix Admin Page Issues --- .../cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs | 4 ++++ .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js | 2 +- .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js | 2 +- .../Pages/CmsKit/Blogs/CreateModal.cshtml.cs | 2 +- .../Pages/CmsKit/Blogs/UpdateModal.cshtml.cs | 3 ++- .../Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml | 1 + .../Volo.CmsKit.Admin.Web/Pages/CmsKit/_ViewImports.cshtml | 4 ++++ .../src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs | 2 ++ .../Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml | 2 +- .../Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml | 2 +- 10 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/_ViewImports.cshtml diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs index fa93175efc..52241a8c87 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs @@ -10,6 +10,7 @@ using Volo.CmsKit.Web; using Volo.CmsKit.Permissions; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.PageToolbars; using Volo.Abp.Localization; +using Volo.Abp.AutoMapper; namespace Volo.CmsKit.Admin.Web { @@ -49,6 +50,9 @@ namespace Volo.CmsKit.Admin.Web options.FileSets.AddEmbedded("Volo.CmsKit.Admin.Web"); }); + context.Services.AddAutoMapperObjectMapper(); + Configure(options => { options.AddMaps(validate: true); }); + Configure(options => { options.Conventions.AuthorizeFolder("/CmsKit/Tags/", CmsKitAdminPermissions.Tags.Default); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js index dece495320..b2fd0613e6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js @@ -136,7 +136,7 @@ function finishSaving() { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = "/Admin/BlogPosts/"; + location.href = "../BlogPosts"; } var urlEdited = false; diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js index 60b618135b..9a2fb3c69a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js @@ -154,7 +154,7 @@ function finishSaving(result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = "/Admin/BlogPosts/"; + location.href = "../BlogPosts/"; } $titleClone.on('change paste keyup', function () { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs index 3681e04624..05996b6f87 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs @@ -29,7 +29,7 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs return NoContent(); } - [AutoMap(typeof(BlogDto), ReverseMap = true)] + [AutoMap(typeof(CreateBlogDto), ReverseMap = true)] public class CreateBlogViewModel { [Required] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs index 57b51026b6..75c15018d4 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs @@ -45,7 +45,8 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs return NoContent(); } - [AutoMap(typeof(BlogDto), ReverseMap = true)] + [AutoMap(typeof(BlogDto))] + [AutoMap(typeof(UpdateBlogDto), ReverseMap = true)] public class UpdateBlogViewModel { [Required] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml index 1330dde48a..fe9f8d4b69 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml @@ -4,6 +4,7 @@ @using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages +@using Volo.CmsKit.Admin.Web.Bundles @inherits CmsKitAdminPageBase diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/_ViewImports.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/_ViewImports.cshtml new file mode 100644 index 0000000000..c1da1f5f10 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs index fe30d70b50..28f5f66d5e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs @@ -64,6 +64,8 @@ namespace Volo.CmsKit.Public.Web Configure(options => { options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"/pages/{slug:minlength(1)}"); + options.Conventions.AddPageRoute("/CmsKit/Blogs/Index", @"/blogs/{blogSlug:minlength(1)}"); + options.Conventions.AddPageRoute("/CmsKit/Blogs/BlogPost", @"/blogs/{blogSlug}/{blogPostSlug}"); }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml index 4eb2fa0ccd..d19b66f409 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml @@ -1,4 +1,4 @@ -@page "/blogs/{blogSlug}/{blogPostSlug}" +@page @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml index a58648f382..9a3f805bf1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -1,4 +1,4 @@ -@page "/blogs/{blogSlug}" +@page @using Volo.CmsKit.Public.Web.Pages From d83d8ec76133131916ebee8a65f5c6cb4d28e4d9 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 26 Feb 2021 15:34:52 +0300 Subject: [PATCH 007/101] CmsKit - Add localization resources --- .../CmsKit/Localization/Resources/en.json | 69 ++++++++++++++++++ .../CmsKit/Localization/Resources/tr.json | 71 +++++++++++++++++++ 2 files changed, 140 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 212d495459..8102350c6a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -1,6 +1,18 @@ { "culture": "en", "texts": { + "BlogDeletionConfirmationMessage": "The blog '{0}' will be deleted. Are you sure?", + "BlogFeatureNotAvailable": "This feature is not available now. Enable with 'GlobalFeatureManager' to use it.", + "BlogId": "Blog", + "BlogPostDeletionConfirmationMessage": "The blog post '{0}' will be deleted. Are you sure?", + "BlogPosts": "Blog Posts", + "Blogs": "Blogs", + "ChoosePreference": "Choose Preference...", + "Cms": "Cms", + "CmsKit.Comments": "Comments", + "CmsKit.Ratings": "Ratings", + "CmsKit.Reactions": "Reactions", + "CmsKit.Tags": "Tags", "CmsKit:0002": "Content already exists!", "CmsKit:0003": "The entity {0} is not taggable.", "CmsKit:Blog:0001": "The given slug ({Slug}) already exists!", @@ -9,16 +21,45 @@ "CmsKit:Page:0001": "The given url ({0}) already exists.", "CmsKit:Tag:0002": "The entity is not taggable!", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", + "CommentDeletionConfirmationMessage": "This comment and all replies will be deleted!", "Comments": "Comments", + "ContentDeletionConfirmationMessage": "Are you sure to delete this content?", + "Contents": "Contents", + "CoverImage": "Cover Image", + "CreateBlogPostPage": "New Blog Post", + "CreationTime": "Creation Time", "Delete": "Delete", + "Detail": "Detail", + "Details": "Details", + "DoYouPreferAdditionalEmails": "Do you prefer additional emails?", "Edit": "Edit", + "EndDate": "End Date", + "EntityId": "Entity Id", + "EntityType": "Entity Type", + "ExportCSV": "Export CSV", + "Features": "Features", + "GenericDeletionConfirmationMessage": "Are you sure to delete '{0}'?", "LastModification": "Last Modification", "LoginToAddComment": "Login to add comment", "LoginToRate": "Login to rate", "LoginToReply": "Login to reply", "Menu:CMS": "CMS", + "Message": "Message", "MessageDeletionConfirmationMessage": "This comment will be deleted completely.", + "Name": "Name", + "New": "New", + "OK": "OK", + "PageDeletionConfirmationMessage": "Are you sure to delete this page?", + "PageSlugInformation": "Slug is used on url. Your url will be '/pages/{{slug}}'.", + "Permission:BlogManagement": "Blog Management", + "Permission:BlogManagement.Create": "Create", + "Permission:BlogManagement.Delete": "Delete", "Permission:BlogManagement.Features": "Features", + "Permission:BlogManagement.Update": "Update", + "Permission:BlogPostManagement": "Blog Post Management", + "Permission:BlogPostManagement.Create": "Create", + "Permission:BlogPostManagement.Delete": "Delete", + "Permission:BlogPostManagement.Update": "Update", "Permission:CmsKit": "CmsKit", "Permission:Comments": "Comment Management", "Permission:Comments.Delete": "Delete", @@ -40,14 +81,42 @@ "PickYourReaction": "Pick your reaction", "RatingUndoMessage": "Your rating will be undo.", "Read": "Read", + "RepliesToThisComment": "Replies to this comment", "Reply": "Reply", + "ReplyTo": "Reply to", + "SamplePageMessage": "A sample page for the Pro module", + "SaveChanges": "Save Changes", + "SelectAll": "Select All", "Send": "Send", + "SendMessage": "Send Message", + "ShortDescription": "Short description", + "Slug": "Slug", + "Source": "Source", + "SourceUrl": "Source Url", "Star": "Star", + "StartDate": "Start Date", + "Subject": "Subject", + "SubjectPlaceholder": "Please type a subject", + "Submit": "Submit", + "Subscribe": "Subscribe", + "SuccessfullyDeleted": "Successfully deleted!", + "SuccessfullySaved": "Successfully saved!", "TagDeletionConfirmationMessage": "Are you sure to delete '{0}' tag?", "Tags": "Tags", + "Text": "Text", + "ThankYou": "Thank you", + "Title": "Title", "Undo": "Undo", "Update": "Update", + "UpdatePreferenceSuccessMessage": "Your preferences have been saved.", + "UpdateYourEmailPreferences": "Update your email preferences", + "UploadFailedMessage": "Upload failed.", + "UserId": "User Id", + "Username": "Username", "YourComment": "Your comment", + "YourEmailAddress": "Your e-mail address", + "YourFullName": "Your full name", + "YourMessage": "Your Message", "YourReply": "Your reply" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index af032d5480..5701c631f2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -1,22 +1,64 @@ { "culture": "tr", "texts": { + "BlogDeletionConfirmationMessage": "'{0}' adlı blog silinecek. Emin misiniz?", + "BlogFeatureNotAvailable": "Bu özellik kullanılabilir değil. 'GlobalFeatureManager' ile aktif ederek kullanabilisiniz.", + "BlogId": "Blog", + "BlogPostDeletionConfirmationMessage": "'{0}' başlıklı blog yazısı silinecek. Emin misiniz?", + "BlogPosts": "Blog Yazıları", + "Blogs": "Bloglar", + "ChoosePreference": "Tercih seçiniz...", + "Cms": "Cms", + "CmsKit.Comments": "Yorumlar", + "CmsKit.Ratings": "Puanlama", + "CmsKit.Reactions": "Tepkiler", + "CmsKit.Tags": "Etiketler", "CmsKit:0002": "İçerik zaten mevcut!", "CmsKit:0003": "{0} ögesi etiketlenebilir değil.", "CmsKit:BlogPost:0001": "Aynı url etiketi zaten mevcut.", "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır.", "CmsKit:Tag:0002": "Bu öge etiketlenebilir değil.", "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.", + "CommentDeletionConfirmationMessage": "Bu yorum ve buna yapılan tüm yorumlan silinecektir!", "Comments": "Yorumlar", + "ContentDeletionConfirmationMessage": "Bu içeriği gerçekten silmek istediğinize emin misiniz?", + "Contents": "İçerikler", + "CoverImage": "Kapak Resmi", + "CreateBlogPostPage": "Yeni Blog Yazısı", + "CreationTime": "Oluşturulma Zamanı", "Delete": "Sil", + "DeleteSubscriptionSubject": "E-posta adresiniz silinmiştir.", + "Detail": "Detay", + "Details": "Detaylar", + "DoYouPreferAdditionalEmails": "Ek e-postaları tercih ediyor musunuz?", "Edit": "Düzenle", + "EndDate": "Bitiş Tarihi", + "EntityId": "Entity Id", + "EntityType": "Entity Tür", + "ExportCSV": "CSV olarak dışa aktar", + "Features": "Özellikler", + "GenericDeletionConfirmationMessage": "'{0}' kaydını silmek istediğinize emin misiniz?", "LastModification": "Son Güncellenme", "LoginToAddComment": "Yorum yapmak için giriş yap", "LoginToRate": "Oylamak için giriş yapın", "LoginToReply": "Cevap vermek için giriş yap", "Menu:CMS": "CMS", + "Message": "Mesaj", "MessageDeletionConfirmationMessage": "Bu yorum tamamen silinecektir", + "Name": "Ad", + "New": "Yeni", + "OK": "Tamam", + "PageDeletionConfirmationMessage": "Bu sayfayı silmek istediğinize emin misiniz?", + "PageSlugInformation": "Etiket URL'de kullanılır. Url şöyle görünür: '/pages/{{slug}}'.", + "Permission:BlogManagement": "Blog Yönetimi", + "Permission:BlogManagement.Create": "Oluşturma", + "Permission:BlogManagement.Delete": "Silme", "Permission:BlogManagement.Features": "Özellikler", + "Permission:BlogManagement.Update": "Güncelleme", + "Permission:BlogPostManagement": "Blog Yazıları Yönetimi", + "Permission:BlogPostManagement.Create": "Oluşturma", + "Permission:BlogPostManagement.Delete": "Silme", + "Permission:BlogPostManagement.Update": "Güncelleme", "Permission:CmsKit": "CmsKit", "Permission:Contents": "İçerik Yönetimi", "Permission:Contents.Create": "İçerik Oluşturma", @@ -29,14 +71,43 @@ "PickYourReaction": "Tepkinizi seçin", "RatingUndoMessage": "Oylamanız geri alınacak.", "Read": "Oku", + "RepliesToThisComment": "Bu yoruma yapılan yorumlar", "Reply": "Cevapla", + "ReplyTo": "Cevap", + "SamplePageMessage": "Pro modulünden örnek bir sayfa", + "SaveChanges": "Değişiklikleri Kaydet", + "SelectAll": "Hepsini seç", "Send": "Gönder", + "SendMessage": "Mesajı Gönder", + "ShortDescription": "Kısa açıklama", + "Slug": "Etiket", + "Source": "Kaynak", + "SourceUrl": "Kaynak Link", "Star": "Yıldız", + "StartDate": "Başlangıç Tarihi", + "Subject": "Konu", + "SubjectPlaceholder": "Lütfen bir konu yazınız", + "Submit": "Kaydet", + "Subscribe": "Abone ol", + "SuccessfullyDeleted": "Başarıyla silindi!", + "SuccessfullySaved": "Başarıyla kaydedildi!", "TagDeletionConfirmationMessage": "'{0}' etiketini silmek istediğinize emin misiniz?", "Tags": "Etiketler", + "Text": "Metin", + "ThankYou": "Teşekkürler", + "Title": "Başlık", "Undo": "Geri al", "Update": "Güncelle", + "UpdatePreference": "Tercihleri Güncelle", + "UpdatePreferenceSuccessMessage": "Tercihleriniz kaydedilmiştir.", + "UpdateYourEmailPreferences": "E-posta tercihlerinizi güncelleyin", + "UploadFailedMessage": "Karşıya yükleme işlemi başarısız oldu.", + "UserId": "Kullanıcı Id", + "Username": "Kullanıcı adı", "YourComment": "Yorumunuz", + "YourEmailAddress": "Email adresiniz", + "YourFullName": "Tam adınız", + "YourMessage": "Mesajınız", "YourReply": "Cevabınız" } } From e8342fe2edf10508ce61954dbe47bb2e56d55689 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 26 Feb 2021 22:23:04 +0800 Subject: [PATCH 008/101] Use HashSet for toBeDeleted. --- .../Toolbars/ToolbarManager.cs | 2 +- .../Volo/Abp/Ui/Navigation/MenuManager.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs index 1f48b2825b..d6fc02f153 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs @@ -54,7 +54,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars var permissionChecker = serviceProvider.GetRequiredService(); var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).ToArray()); - var toBeDeleted = new List(); + var toBeDeleted = new HashSet(); foreach (var item in requiredPermissionItems) { if (grantResult.Result[item.RequiredPermissionName!] != PermissionGrantResult.Granted) diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index d1f3ee330a..28ac86d4d2 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -53,7 +53,7 @@ namespace Volo.Abp.UI.Navigation var permissionChecker = serviceProvider.GetRequiredService(); var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).ToArray()); - var toBeDeleted = new List(); + var toBeDeleted = new HashSet(); foreach (var menu in requiredPermissionItems) { if (grantResult.Result[menu.RequiredPermissionName!] != PermissionGrantResult.Granted) @@ -79,7 +79,7 @@ namespace Volo.Abp.UI.Navigation } } - protected virtual void RemoveMenus(IHasMenuItems menuWithItems, List toBeDeleted) + protected virtual void RemoveMenus(IHasMenuItems menuWithItems, HashSet toBeDeleted) { menuWithItems.Items.RemoveAll(toBeDeleted.Contains); From 055e33cb50cd7d5bedb9012d584f40392308bd01 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Mon, 1 Mar 2021 10:10:32 +0800 Subject: [PATCH 009/101] Improve MongoDbCoreRepositoryExtensions As same as #5697, and fix a bug. --- .../MongoDbCoreRepositoryExtensions.cs | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs index bcbdc00d9e..0f74592391 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs @@ -11,60 +11,56 @@ namespace Volo.Abp.Domain.Repositories public static class MongoDbCoreRepositoryExtensions { [Obsolete("Use GetDatabaseAsync method.")] - public static IMongoDatabase GetDatabase(this IBasicRepository repository) - where TEntity : class, IEntity + public static IMongoDatabase GetDatabase(this IBasicRepository repository) + where TEntity : class, IEntity { return repository.ToMongoDbRepository().Database; } - public static Task GetDatabaseAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) - where TEntity : class, IEntity + public static Task GetDatabaseAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetDatabaseAsync(cancellationToken); } [Obsolete("Use GetCollectionAsync method.")] - public static IMongoCollection GetCollection(this IBasicRepository repository) - where TEntity : class, IEntity + public static IMongoCollection GetCollection(this IBasicRepository repository) + where TEntity : class, IEntity { return repository.ToMongoDbRepository().Collection; } - public static Task> GetCollectionAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) - where TEntity : class, IEntity + public static Task> GetCollectionAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetCollectionAsync(cancellationToken); } [Obsolete("Use GetMongoQueryableAsync method.")] - public static IMongoQueryable GetMongoQueryable(this IBasicRepository repository) - where TEntity : class, IEntity + public static IMongoQueryable GetMongoQueryable(this IBasicRepository repository) + where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetMongoQueryable(); } - public static Task> GetMongoQueryableAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) - where TEntity : class, IEntity + public static Task> GetMongoQueryableAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetMongoQueryableAsync(cancellationToken); } - public static Task> GetAggregateAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) - where TEntity : class, IEntity + public static async Task> GetAggregateAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + where TEntity : class, IEntity { - return repository.ToMongoDbRepository().GetAggregateAsync(cancellationToken); + var collection = await repository.ToMongoDbRepository().GetCollectionAsync(cancellationToken); + return collection.Aggregate(); } - public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository) - where TEntity : class, IEntity + public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository) + where TEntity : class, IEntity { - var mongoDbRepository = repository as IMongoDbRepository; - if (mongoDbRepository == null) - { - throw new ArgumentException("Given repository does not implement " + typeof(IMongoDbRepository).AssemblyQualifiedName, nameof(repository)); - } - - return mongoDbRepository; + if (repository is IMongoDbRepository mongoDbRepository) return mongoDbRepository; + throw new ArgumentException("Given repository does not implement " + typeof(IMongoDbRepository).AssemblyQualifiedName, nameof(repository)); } } } From 020bffaa90d99c0929d5050ecc03c424e2dbcccc Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 1 Mar 2021 10:21:22 +0800 Subject: [PATCH 010/101] Update MongoDbCoreRepositoryExtensions.cs --- .../Domain/Repositories/MongoDbCoreRepositoryExtensions.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs index 0f74592391..3d27de6df6 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs @@ -59,7 +59,10 @@ namespace Volo.Abp.Domain.Repositories public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository) where TEntity : class, IEntity { - if (repository is IMongoDbRepository mongoDbRepository) return mongoDbRepository; + if (repository is IMongoDbRepository mongoDbRepository) + { + return mongoDbRepository; + } throw new ArgumentException("Given repository does not implement " + typeof(IMongoDbRepository).AssemblyQualifiedName, nameof(repository)); } } From af3881ba80238272f732008cf125735b1bbe016a Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 09:46:49 +0300 Subject: [PATCH 011/101] Update CreateMigrationAndRunMigrator to support --separate-tenant-schema --- .../CreateMigrationAndRunMigratorCommand.cs | 76 ++++++++++++++++--- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs index 68fae779ce..5152e7af2e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs @@ -26,7 +26,9 @@ namespace Volo.Abp.Cli.Commands throw new CliUsageException("DbMigrations folder path is missing!"); } - var dbMigratorProjectPath = GetDbMigratorProjectPath(commandLineArgs.Target); + var dbMigrationsFolder = commandLineArgs.Target; + + var dbMigratorProjectPath = GetDbMigratorProjectPath(dbMigrationsFolder); if (dbMigratorProjectPath == null) { throw new Exception("DbMigrator is not found!"); @@ -37,13 +39,17 @@ namespace Volo.Abp.Cli.Commands InstallDotnetEfTool(); } - var addMigrationCmd = $"cd \"{commandLineArgs.Target}\" && " + - $"dotnet ef migrations add Initial -s \"{dbMigratorProjectPath}\""; + var tenantDbContextName = FindTenantDbContextName(dbMigrationsFolder); + var dbContextName = tenantDbContextName != null ? + FindDbContextName(dbMigrationsFolder) + : null; + + var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbMigratorProjectPath, dbContextName); + var tenantMigrationOutput = tenantDbContextName != null ? + AddMigrationAndGetOutput(dbMigrationsFolder, dbMigratorProjectPath, tenantDbContextName) + : null; - var output = CmdHelper.RunCmdAndGetOutput(addMigrationCmd); - if (output.Contains("Done.") && - output.Contains("To undo this action") && - output.Contains("ef migrations remove")) + if (CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput)) { // Migration added successfully CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigratorProjectPath) + "\" && dotnet run"); @@ -51,22 +57,70 @@ namespace Volo.Abp.Cli.Commands } else { - var exceptionMsg = "Migrations failed! The following command didn't run successfully:" + + var exceptionMsg = "Migrations failed! A migration command didn't run successfully:" + Environment.NewLine + - addMigrationCmd + - Environment.NewLine + output; + Environment.NewLine + migrationOutput + + Environment.NewLine + + Environment.NewLine + tenantMigrationOutput; Logger.LogError(exceptionMsg); throw new Exception(exceptionMsg); } } + private string FindTenantDbContextName(string dbMigrationsFolder) + { + var tenantDbContext = Directory + .GetFiles(dbMigrationsFolder, "*TenantMigrationsDbContext.cs", SearchOption.AllDirectories) + .FirstOrDefault(); + + if (tenantDbContext == null) + { + return null; + } + + return Path.GetFileName(tenantDbContext).RemovePostFix(".cs"); + } + + private string FindDbContextName(string dbMigrationsFolder) + { + var dbContext = Directory + .GetFiles(dbMigrationsFolder, "*MigrationsDbContext.cs", SearchOption.AllDirectories) + .FirstOrDefault(fp => !fp.EndsWith("TenantMigrationsDbContext.cs")); + + if (dbContext == null) + { + return null; + } + + return Path.GetFileName(dbContext).RemovePostFix(".cs"); + } + + private static string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbMigratorProjectPath, string dbContext) + { + var dbContextOption = string.IsNullOrWhiteSpace(dbContext) + ? string.Empty + : $"--context {dbContext}"; + + var addMigrationCmd = $"cd \"{dbMigrationsFolder}\" && " + + $"dotnet ef migrations add Initial -s \"{dbMigratorProjectPath}\" {dbContextOption}"; + + return CmdHelper.RunCmdAndGetOutput(addMigrationCmd); + } + private static bool IsDotNetEfToolInstalled() { var output = CmdHelper.RunCmdAndGetOutput("dotnet tool list -g"); return output.Contains("dotnet-ef"); } + private static bool CheckMigrationOutput(string output) + { + return output == null || (output.Contains("Done.") && + output.Contains("To undo this action") && + output.Contains("ef migrations remove")); + } + private void InstallDotnetEfTool() { Logger.LogInformation("Installing dotnet-ef tool..."); @@ -95,4 +149,4 @@ namespace Volo.Abp.Cli.Commands return string.Empty; } } -} \ No newline at end of file +} From 6836cf9e7192047d243488c135e6ae4e7ea3bdb6 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 10:04:05 +0300 Subject: [PATCH 012/101] Update RemoveCmsKitStep to support --separate-tenant-schema --- .../Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs index 4f63d377ea..789f9e47cb 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs @@ -11,6 +11,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps f.Name.EndsWith(".csproj") || f.Name.EndsWith("Module.cs") || f.Name.EndsWith("MyProjectNameMigrationsDbContext.cs") || + f.Name.EndsWith("MyProjectNameMigrationsDbContextBase.cs") || f.Name.EndsWith("MyProjectNameGlobalFeatureConfigurator.cs") || (f.Name.EndsWith(".cshtml") && f.Name.Contains("MyCompanyName.MyProjectName.Web.Public")) ); From 43d16e1defbc46653bedbbc4ad2b795800ccaf47 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 10:04:28 +0300 Subject: [PATCH 013/101] update DatabaseManagementSystemChangeStep to support --separate-tenant-schema --- .../Building/Steps/DatabaseManagementSystemChangeStep.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/DatabaseManagementSystemChangeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/DatabaseManagementSystemChangeStep.cs index 4286710899..605cc842f5 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/DatabaseManagementSystemChangeStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/DatabaseManagementSystemChangeStep.cs @@ -54,7 +54,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps private void AdjustOracleDbContextOptionsBuilder(ProjectBuildContext context) { - var dbContextFactoryFile = context.Files.First(f => f.Name.EndsWith("MigrationsDbContextFactory.cs", StringComparison.OrdinalIgnoreCase)); + var dbContextFactoryFile = context.Files.FirstOrDefault(f => f.Name.EndsWith("MigrationsDbContextFactoryBase.cs", StringComparison.OrdinalIgnoreCase)) + ?? context.Files.First(f => f.Name.EndsWith("MigrationsDbContextFactory.cs", StringComparison.OrdinalIgnoreCase)); dbContextFactoryFile.ReplaceText("new DbContextOptionsBuilder", $"(DbContextOptionsBuilder<{context.BuildArgs.SolutionName.ProjectName}MigrationsDbContext>) new DbContextOptionsBuilder"); @@ -62,7 +63,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps private void AddMySqlServerVersion(ProjectBuildContext context) { - var dbContextFactoryFile = context.Files.First(f => f.Name.EndsWith("MigrationsDbContextFactory.cs", StringComparison.OrdinalIgnoreCase)); + var dbContextFactoryFile = context.Files.FirstOrDefault(f => f.Name.EndsWith("MigrationsDbContextFactoryBase.cs", StringComparison.OrdinalIgnoreCase)) + ?? context.Files.First(f => f.Name.EndsWith("MigrationsDbContextFactory.cs", StringComparison.OrdinalIgnoreCase)); dbContextFactoryFile.ReplaceText("configuration.GetConnectionString(\"Default\")", "configuration.GetConnectionString(\"Default\"), MySqlServerVersion.LatestSupportedServerVersion"); @@ -90,7 +92,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var efCoreModuleClass = context.Files.First(f => f.Name.EndsWith("EntityFrameworkCoreModule.cs", StringComparison.OrdinalIgnoreCase)); efCoreModuleClass.ReplaceText(oldUseMethod, newUseMethodForEfModule); - var dbContextFactoryFile = context.Files.First(f => f.Name.EndsWith("MigrationsDbContextFactory.cs", StringComparison.OrdinalIgnoreCase)); + var dbContextFactoryFile = context.Files.FirstOrDefault(f => f.Name.EndsWith("MigrationsDbContextFactoryBase.cs", StringComparison.OrdinalIgnoreCase)) + ?? context.Files.First(f => f.Name.EndsWith("MigrationsDbContextFactory.cs", StringComparison.OrdinalIgnoreCase)); dbContextFactoryFile.ReplaceText(oldUseMethod, newUseMethodForDbContext); } } From 9ba7fb885957e471382d9b65de8b8a4981f61ac7 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 1 Mar 2021 16:00:32 +0800 Subject: [PATCH 014/101] Use RequiredPermissionName for all ApplicationMenuItem & ToolbarItem. Resolve #7883 --- .../Toolbars/ToolbarManager.cs | 2 +- .../Volo/Abp/Ui/Navigation/MenuManager.cs | 2 +- .../BloggingAdminMenuContributor.cs | 13 +++---------- .../Navigation/DocsMenuContributor.cs | 11 ++--------- .../AbpTenantManagementWebMainMenuContributor.cs | 5 +---- 5 files changed, 8 insertions(+), 25 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs index d6fc02f153..2e97cebecb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarManager.cs @@ -52,7 +52,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars if (requiredPermissionItems.Any()) { var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).ToArray()); + var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).Distinct().ToArray()); var toBeDeleted = new HashSet(); foreach (var item in requiredPermissionItems) diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index 28ac86d4d2..960389230e 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -51,7 +51,7 @@ namespace Volo.Abp.UI.Navigation if (requiredPermissionItems.Any()) { var permissionChecker = serviceProvider.GetRequiredService(); - var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).ToArray()); + var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionItems.Select(x => x.RequiredPermissionName).Distinct().ToArray()); var toBeDeleted = new HashSet(); foreach (var menu in requiredPermissionItems) diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs index 95a403678f..e2011acf43 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs @@ -18,18 +18,11 @@ namespace Volo.Blogging.Admin { var l = context.GetLocalizer(); - if (await context.IsGrantedAsync(BloggingPermissions.Blogs.Management)) - { - var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"]); + var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"], requiredPermissionName: BloggingPermissions.Blogs.Management); - //TODO: Using the same permission. Reconsider. - if (await context.IsGrantedAsync(BloggingPermissions.Blogs.Management)) - { - managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs")); - } + managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs", requiredPermissionName: BloggingPermissions.Blogs.Management)); - context.Menu.GetAdministration().AddItem(managementRootMenuItem); - } + context.Menu.GetAdministration().AddItem(managementRootMenuItem); } } } diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs index 9bc55d543f..8b53069132 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs @@ -27,15 +27,8 @@ namespace Volo.Docs.Admin.Navigation administrationMenu.AddItem(rootMenuItem); - if (await context.IsGrantedAsync(DocsAdminPermissions.Projects.Default)) - { - rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects")); - } - - if (await context.IsGrantedAsync(DocsAdminPermissions.Documents.Default)) - { - rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents")); - } + rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects", requiredPermissionName: DocsAdminPermissions.Projects.Default)); + rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents", requiredPermissionName: DocsAdminPermissions.Documents.Default)); } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs index 0a36e9d130..45f9b75487 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs @@ -23,10 +23,7 @@ namespace Volo.Abp.TenantManagement.Web.Navigation var tenantManagementMenuItem = new ApplicationMenuItem(TenantManagementMenuNames.GroupName, l["Menu:TenantManagement"], icon: "fa fa-users"); administrationMenu.AddItem(tenantManagementMenuItem); - if (await context.IsGrantedAsync(TenantManagementPermissions.Tenants.Default)) - { - tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants")); - } + tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants", requiredPermissionName: TenantManagementPermissions.Tenants.Default)); } } } From 216fd95548e173a57c3b6472150f551a690e56d8 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 11:16:27 +0300 Subject: [PATCH 015/101] Update EfCoreMigrationManager to support --separate-tenant-schema --- .../EfCoreMigrationManager.cs | 57 ++++++++++++++++++- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs index b15ffaa274..7bb3929f45 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs @@ -19,12 +19,35 @@ namespace Volo.Abp.Cli.ProjectModification public void AddMigration(string dbMigrationsCsprojFile, string module, string startupProject) { + var dbMigrationsProjectFolder = Path.GetDirectoryName(dbMigrationsCsprojFile); var moduleName = ParseModuleName(module); var migrationName = "Added_" + moduleName + "_Module" + GetUniquePostFix(); - CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigrationsCsprojFile) + - "\" && dotnet ef migrations add " + migrationName + - GetStartupProjectOption(startupProject)); + var tenantDbContextName = FindTenantDbContextName(dbMigrationsProjectFolder); + var dbContextName = tenantDbContextName != null ? + FindDbContextName(dbMigrationsProjectFolder) + : null; + + if (!string.IsNullOrEmpty(tenantDbContextName)) + { + RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, startupProject, tenantDbContextName); + } + + RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, startupProject, dbContextName); + } + + protected virtual void RunAddMigrationCommand( + string dbMigrationsProjectFolder, + string migrationName, + string startupProject, + string dbContext) + { + var dbContextOption = string.IsNullOrWhiteSpace(dbContext) + ? string.Empty + : $"--context {dbContext}"; + + CmdHelper.RunCmd($"cd \"{dbMigrationsProjectFolder}\" && dotnet ef migrations add {migrationName}" + + $" {GetStartupProjectOption(startupProject)} {dbContextOption}"); } protected virtual string ParseModuleName(string fullModuleName) @@ -47,5 +70,33 @@ namespace Volo.Abp.Cli.ProjectModification { return startupProject.IsNullOrWhiteSpace() ? "" : $" -s {startupProject}"; } + + protected virtual string FindDbContextName(string dbMigrationsFolder) + { + var dbContext = Directory + .GetFiles(dbMigrationsFolder, "*MigrationsDbContext.cs", SearchOption.AllDirectories) + .FirstOrDefault(fp => !fp.EndsWith("TenantMigrationsDbContext.cs")); + + if (dbContext == null) + { + return null; + } + + return Path.GetFileName(dbContext).RemovePostFix(".cs"); + } + + protected virtual string FindTenantDbContextName(string dbMigrationsFolder) + { + var tenantDbContext = Directory + .GetFiles(dbMigrationsFolder, "*TenantMigrationsDbContext.cs", SearchOption.AllDirectories) + .FirstOrDefault(); + + if (tenantDbContext == null) + { + return null; + } + + return Path.GetFileName(tenantDbContext).RemovePostFix(".cs"); + } } } From 17239580d9926664172affece543e1530437b374 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Mon, 1 Mar 2021 16:30:32 +0800 Subject: [PATCH 016/101] Rollback GetAggregateAsync --- .../Domain/Repositories/MongoDbCoreRepositoryExtensions.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs index 3d27de6df6..f3ca43b80e 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs @@ -49,11 +49,10 @@ namespace Volo.Abp.Domain.Repositories return repository.ToMongoDbRepository().GetMongoQueryableAsync(cancellationToken); } - public static async Task> GetAggregateAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + public static Task> GetAggregateAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) where TEntity : class, IEntity { - var collection = await repository.ToMongoDbRepository().GetCollectionAsync(cancellationToken); - return collection.Aggregate(); + return repository.ToMongoDbRepository().GetAggregateAsync(cancellationToken); } public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository) From 149755af7170321f9fbf7ca00fa020097ff8a613 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Mon, 1 Mar 2021 16:37:08 +0800 Subject: [PATCH 017/101] Replace IBasicRepository with IReadOnlyBasicRepository. --- .../MongoDbCoreRepositoryExtensions.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs index f3ca43b80e..27e031fe58 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs @@ -11,51 +11,51 @@ namespace Volo.Abp.Domain.Repositories public static class MongoDbCoreRepositoryExtensions { [Obsolete("Use GetDatabaseAsync method.")] - public static IMongoDatabase GetDatabase(this IBasicRepository repository) + public static IMongoDatabase GetDatabase(this IReadOnlyBasicRepository repository) where TEntity : class, IEntity { return repository.ToMongoDbRepository().Database; } - public static Task GetDatabaseAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + public static Task GetDatabaseAsync(this IReadOnlyBasicRepository repository, CancellationToken cancellationToken = default) where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetDatabaseAsync(cancellationToken); } [Obsolete("Use GetCollectionAsync method.")] - public static IMongoCollection GetCollection(this IBasicRepository repository) + public static IMongoCollection GetCollection(this IReadOnlyBasicRepository repository) where TEntity : class, IEntity { return repository.ToMongoDbRepository().Collection; } - public static Task> GetCollectionAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + public static Task> GetCollectionAsync(this IReadOnlyBasicRepository repository, CancellationToken cancellationToken = default) where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetCollectionAsync(cancellationToken); } [Obsolete("Use GetMongoQueryableAsync method.")] - public static IMongoQueryable GetMongoQueryable(this IBasicRepository repository) + public static IMongoQueryable GetMongoQueryable(this IReadOnlyBasicRepository repository) where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetMongoQueryable(); } - public static Task> GetMongoQueryableAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + public static Task> GetMongoQueryableAsync(this IReadOnlyBasicRepository repository, CancellationToken cancellationToken = default) where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetMongoQueryableAsync(cancellationToken); } - public static Task> GetAggregateAsync(this IBasicRepository repository, CancellationToken cancellationToken = default) + public static Task> GetAggregateAsync(this IReadOnlyBasicRepository repository, CancellationToken cancellationToken = default) where TEntity : class, IEntity { return repository.ToMongoDbRepository().GetAggregateAsync(cancellationToken); } - public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository) + public static IMongoDbRepository ToMongoDbRepository(this IReadOnlyBasicRepository repository) where TEntity : class, IEntity { if (repository is IMongoDbRepository mongoDbRepository) From a36f9bdec7dea5c8e41f006a91317e4b61ba7eae Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 11:37:44 +0300 Subject: [PATCH 018/101] Cli: RemoveFolderStep TenantMigrations --- .../Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs index a725a513e7..7541894181 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs @@ -298,6 +298,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App SemanticVersion.Parse(context.BuildArgs.Version) > new SemanticVersion(4,1,99)) { steps.Add(new RemoveFolderStep("/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations")); + steps.Add(new RemoveFolderStep("/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/TenantMigrations")); } } From a317f19694aa265b2917b41377cd8c0c10b2f7a8 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 1 Mar 2021 18:54:15 +0800 Subject: [PATCH 019/101] Update AbpIdentityWebMainMenuContributor --- .../AbpIdentityWebMainMenuContributor.cs | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs index 279ea16278..e5d1f31f13 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs @@ -16,28 +16,13 @@ namespace Volo.Abp.Identity.Web.Navigation return; } - var hasRolePermission = await context.IsGrantedAsync(IdentityPermissions.Roles.Default); - var hasUserPermission = await context.IsGrantedAsync(IdentityPermissions.Users.Default); + var l = context.GetLocalizer(); - if (hasRolePermission || hasUserPermission) - { - var administrationMenu = context.Menu.GetAdministration(); - - var l = context.GetLocalizer(); - - var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o"); - administrationMenu.AddItem(identityMenuItem); + var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o"); + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "~/Identity/Roles", requiredPermissionName: IdentityPermissions.Roles.Default)); + identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users", requiredPermissionName: IdentityPermissions.Users.Default)); - if (hasRolePermission) - { - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "~/Identity/Roles")); - } - - if (hasUserPermission) - { - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users")); - } - } + context.Menu.GetAdministration().AddItem(identityMenuItem); } } } From 9b64278e52d2e281acd3b472fd1d416ddacfe5e7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 14:46:53 +0300 Subject: [PATCH 020/101] Cli: remove startup-project option when adding migration --- .../Volo/Abp/Cli/Commands/AddModuleCommand.cs | 7 ------- .../CreateMigrationAndRunMigratorCommand.cs | 8 ++++---- .../ProjectModification/EfCoreMigrationManager.cs | 15 ++++----------- .../ProjectModification/SolutionModuleAdder.cs | 13 +++---------- 4 files changed, 11 insertions(+), 32 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs index 8129435266..a2c47af69b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs @@ -59,7 +59,6 @@ namespace Volo.Abp.Cli.Commands await SolutionModuleAdder.AddAsync( solutionFile, commandLineArgs.Target, - commandLineArgs.Options.GetOrNull(Options.StartupProject.Short, Options.StartupProject.Long), version, skipDbMigrations, withSourceCode, @@ -167,12 +166,6 @@ namespace Volo.Abp.Cli.Commands public const string Skip = "skip-db-migrations"; } - public static class StartupProject - { - public const string Short = "sp"; - public const string Long = "startup-project"; - } - public static class SourceCode { public const string Long = "with-source-code"; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs index 5152e7af2e..c1bb6e6aca 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs @@ -44,9 +44,9 @@ namespace Volo.Abp.Cli.Commands FindDbContextName(dbMigrationsFolder) : null; - var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbMigratorProjectPath, dbContextName); + var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbContextName); var tenantMigrationOutput = tenantDbContextName != null ? - AddMigrationAndGetOutput(dbMigrationsFolder, dbMigratorProjectPath, tenantDbContextName) + AddMigrationAndGetOutput(dbMigrationsFolder, tenantDbContextName) : null; if (CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput)) @@ -96,14 +96,14 @@ namespace Volo.Abp.Cli.Commands return Path.GetFileName(dbContext).RemovePostFix(".cs"); } - private static string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbMigratorProjectPath, string dbContext) + private static string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext) { var dbContextOption = string.IsNullOrWhiteSpace(dbContext) ? string.Empty : $"--context {dbContext}"; var addMigrationCmd = $"cd \"{dbMigrationsFolder}\" && " + - $"dotnet ef migrations add Initial -s \"{dbMigratorProjectPath}\" {dbContextOption}"; + $"dotnet ef migrations add Initial {dbContextOption}"; return CmdHelper.RunCmdAndGetOutput(addMigrationCmd); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs index 7bb3929f45..ee93b6c04d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Cli.ProjectModification Logger = NullLogger.Instance; } - public void AddMigration(string dbMigrationsCsprojFile, string module, string startupProject) + public void AddMigration(string dbMigrationsCsprojFile, string module) { var dbMigrationsProjectFolder = Path.GetDirectoryName(dbMigrationsCsprojFile); var moduleName = ParseModuleName(module); @@ -30,24 +30,22 @@ namespace Volo.Abp.Cli.ProjectModification if (!string.IsNullOrEmpty(tenantDbContextName)) { - RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, startupProject, tenantDbContextName); + RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, tenantDbContextName); } - RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, startupProject, dbContextName); + RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, dbContextName); } protected virtual void RunAddMigrationCommand( string dbMigrationsProjectFolder, string migrationName, - string startupProject, string dbContext) { var dbContextOption = string.IsNullOrWhiteSpace(dbContext) ? string.Empty : $"--context {dbContext}"; - CmdHelper.RunCmd($"cd \"{dbMigrationsProjectFolder}\" && dotnet ef migrations add {migrationName}" + - $" {GetStartupProjectOption(startupProject)} {dbContextOption}"); + CmdHelper.RunCmd($"cd \"{dbMigrationsProjectFolder}\" && dotnet ef migrations add {migrationName} {dbContextOption}"); } protected virtual string ParseModuleName(string fullModuleName) @@ -66,11 +64,6 @@ namespace Volo.Abp.Cli.ProjectModification return "_" + new Random().Next(1, 99999); } - protected virtual string GetStartupProjectOption(string startupProject) - { - return startupProject.IsNullOrWhiteSpace() ? "" : $" -s {startupProject}"; - } - protected virtual string FindDbContextName(string dbMigrationsFolder) { var dbContext = Directory diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index c84713ffcb..d550912691 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -78,7 +78,6 @@ namespace Volo.Abp.Cli.ProjectModification public virtual async Task AddAsync( [NotNull] string solutionFile, [NotNull] string moduleName, - string startupProject, string version, bool skipDbMigrations = false, bool withSourceCode = false, @@ -128,7 +127,7 @@ namespace Volo.Abp.Cli.ProjectModification await RunBundleForBlazorAsync(projectFiles, module); - ModifyDbContext(projectFiles, module, startupProject, skipDbMigrations); + ModifyDbContext(projectFiles, module, skipDbMigrations); } private async Task RunBundleForBlazorAsync(string[] projectFiles, ModuleWithMastersInfo module) @@ -450,8 +449,7 @@ namespace Volo.Abp.Cli.ProjectModification } } - protected void ModifyDbContext(string[] projectFiles, ModuleInfo module, string startupProject, - bool skipDbMigrations = false) + protected void ModifyDbContext(string[] projectFiles, ModuleInfo module, bool skipDbMigrations = false) { if (string.IsNullOrWhiteSpace(module.EfCoreConfigureMethodName)) { @@ -463,11 +461,6 @@ namespace Volo.Abp.Cli.ProjectModification return; } - if (string.IsNullOrWhiteSpace(startupProject)) - { - startupProject = projectFiles.FirstOrDefault(p => p.EndsWith(".DbMigrator.csproj")); - } - var dbMigrationsProject = projectFiles.FirstOrDefault(p => p.EndsWith(".DbMigrations.csproj")); if (dbMigrationsProject == null) @@ -498,7 +491,7 @@ namespace Volo.Abp.Cli.ProjectModification { if (addedNewBuilder) { - EfCoreMigrationManager.AddMigration(dbMigrationsProject, module.Name, startupProject); + EfCoreMigrationManager.AddMigration(dbMigrationsProject, module.Name); } RunMigrator(projectFiles); From 15c69d047b3a07aaf07ecde6569dbc826d6662a4 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 1 Mar 2021 15:00:05 +0300 Subject: [PATCH 021/101] Cli migrations: specify --output-dir --- .../Commands/CreateMigrationAndRunMigratorCommand.cs | 8 ++++---- .../Cli/ProjectModification/EfCoreMigrationManager.cs | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs index c1bb6e6aca..2a3c4652af 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs @@ -44,9 +44,9 @@ namespace Volo.Abp.Cli.Commands FindDbContextName(dbMigrationsFolder) : null; - var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbContextName); + var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbContextName, "Migrations"); var tenantMigrationOutput = tenantDbContextName != null ? - AddMigrationAndGetOutput(dbMigrationsFolder, tenantDbContextName) + AddMigrationAndGetOutput(dbMigrationsFolder, tenantDbContextName, "TenantMigrations") : null; if (CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput)) @@ -96,14 +96,14 @@ namespace Volo.Abp.Cli.Commands return Path.GetFileName(dbContext).RemovePostFix(".cs"); } - private static string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext) + private static string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext, string outputDirectory) { var dbContextOption = string.IsNullOrWhiteSpace(dbContext) ? string.Empty : $"--context {dbContext}"; var addMigrationCmd = $"cd \"{dbMigrationsFolder}\" && " + - $"dotnet ef migrations add Initial {dbContextOption}"; + $"dotnet ef migrations add Initial --output-dir {outputDirectory} {dbContextOption}"; return CmdHelper.RunCmdAndGetOutput(addMigrationCmd); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs index ee93b6c04d..8143acf7b8 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationManager.cs @@ -30,22 +30,25 @@ namespace Volo.Abp.Cli.ProjectModification if (!string.IsNullOrEmpty(tenantDbContextName)) { - RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, tenantDbContextName); + RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, tenantDbContextName, "TenantMigrations"); } - RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, dbContextName); + RunAddMigrationCommand(dbMigrationsProjectFolder, migrationName, dbContextName, "Migrations"); } protected virtual void RunAddMigrationCommand( string dbMigrationsProjectFolder, string migrationName, - string dbContext) + string dbContext, + string outputDirectory) { var dbContextOption = string.IsNullOrWhiteSpace(dbContext) ? string.Empty : $"--context {dbContext}"; - CmdHelper.RunCmd($"cd \"{dbMigrationsProjectFolder}\" && dotnet ef migrations add {migrationName} {dbContextOption}"); + CmdHelper.RunCmd($"cd \"{dbMigrationsProjectFolder}\" && dotnet ef migrations add {migrationName}" + + $" --output-dir {outputDirectory}" + + $" {dbContextOption}"); } protected virtual string ParseModuleName(string fullModuleName) From e52bafeb2059aae7627deb5327e925524ee0cab8 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Mar 2021 15:09:50 +0300 Subject: [PATCH 022/101] CmsKit - Public route contlict fix --- .../src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs | 6 +++--- .../Pages/{ => Public}/CmsKit/Blogs/BlogPost.cshtml | 3 +-- .../Pages/{ => Public}/CmsKit/Blogs/BlogPost.cshtml.cs | 2 +- .../Pages/{ => Public}/CmsKit/Blogs/Index.cshtml | 3 ++- .../Pages/{ => Public}/CmsKit/Blogs/Index.cshtml.cs | 2 +- .../Pages/{ => Public}/CmsKit/Pages/Index.cshtml | 2 +- .../Pages/{ => Public}/CmsKit/Pages/Index.cshtml.cs | 2 +- .../Pages/{CmsKit => }/_ViewImports.cshtml | 0 8 files changed, 10 insertions(+), 10 deletions(-) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{ => Public}/CmsKit/Blogs/BlogPost.cshtml (96%) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{ => Public}/CmsKit/Blogs/BlogPost.cshtml.cs (97%) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{ => Public}/CmsKit/Blogs/Index.cshtml (95%) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{ => Public}/CmsKit/Blogs/Index.cshtml.cs (95%) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{ => Public}/CmsKit/Pages/Index.cshtml (82%) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{ => Public}/CmsKit/Pages/Index.cshtml.cs (93%) rename modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/{CmsKit => }/_ViewImports.cshtml (100%) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs index 28f5f66d5e..c8519b33f0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs @@ -63,9 +63,9 @@ namespace Volo.CmsKit.Public.Web { Configure(options => { - options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"/pages/{slug:minlength(1)}"); - options.Conventions.AddPageRoute("/CmsKit/Blogs/Index", @"/blogs/{blogSlug:minlength(1)}"); - options.Conventions.AddPageRoute("/CmsKit/Blogs/BlogPost", @"/blogs/{blogSlug}/{blogPostSlug}"); + options.Conventions.AddPageRoute("/Public/CmsKit/Pages/Index", @"/pages/{slug:minlength(1)}"); + options.Conventions.AddPageRoute("/Public/CmsKit/Blogs/Index", @"/blogs/{blogSlug:minlength(1)}"); + options.Conventions.AddPageRoute("/Public/CmsKit/Blogs/BlogPost", @"/blogs/{blogSlug}/{blogPostSlug:minlength(1)}"); }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml similarity index 96% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml index d19b66f409..abff0a475e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml @@ -2,7 +2,6 @@ @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment -@using Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs @using Volo.CmsKit.Public.Web.Pages @using Volo.Abp.GlobalFeatures @using Volo.CmsKit.GlobalFeatures @@ -12,7 +11,7 @@ @inherits CmsKitPublicPageBase -@model BlogPostModel +@model Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs.BlogPostModel @{ PageLayout.Content.Title = Model.BlogPost.Title; diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs similarity index 97% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs index 896ca37d67..6683f02cc8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs @@ -10,7 +10,7 @@ using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Public.Blogs; -namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs +namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs { public class BlogPostModel : CmsKitPublicPageModelBase { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml similarity index 95% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml index 9a3f805bf1..34f6a456d5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml @@ -1,10 +1,11 @@ @page @using Volo.CmsKit.Public.Web.Pages +@using Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs @inherits CmsKitPublicPageBase -@model Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs.IndexModel +@model IndexModel @foreach (var blog in Model.Blogs.Items) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs similarity index 95% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs index 9f44d9beaa..eca0917d85 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs @@ -8,7 +8,7 @@ using Volo.Abp.Application.Dtos; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; using Volo.CmsKit.Public.Blogs; -namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs +namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs { public class IndexModel : CmsKitPublicPageModelBase { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml similarity index 82% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml index 4f4129b6d7..6060c00304 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml @@ -2,7 +2,7 @@ @using Microsoft.AspNetCore.Mvc.Localization @using Volo.CmsKit.Localization @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages -@model Volo.CmsKit.Public.Web.Pages.CmsKit.Pages.IndexModel +@model Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Pages.IndexModel @inject IHtmlLocalizer L @await Component.InvokeAsync(typeof(DefaultPageViewComponent), diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs similarity index 93% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs index 155a85d94f..2a30af8ae7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc; using Volo.CmsKit.Public.Pages; using Volo.CmsKit.Web.Pages; -namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Pages +namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Pages { public class IndexModel : CommonPageModel { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/_ViewImports.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/_ViewImports.cshtml similarity index 100% rename from modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/_ViewImports.cshtml rename to modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/_ViewImports.cshtml From 350f3d64694a1ec00cc1df66d38807c3499a0aa6 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Mar 2021 15:10:19 +0300 Subject: [PATCH 023/101] CmsKit - Convert /CmsKit convention to /Cms --- .../src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs | 11 ++++++++++- .../Menus/CmsKitAdminMenuContributor.cs | 10 +++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs index 52241a8c87..4834670b3c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs @@ -73,7 +73,16 @@ namespace Volo.CmsKit.Admin.Web Configure(options => { - //Configure authorization. + options.Conventions.AddPageRoute("/CmsKit/Tags/Index", "/Cms/Tags"); + options.Conventions.AddPageRoute("/CmsKit/Pages/Index", "/Cms/Pages"); + options.Conventions.AddPageRoute("/CmsKit/Pages/Create", "/Cms/Pages/Create"); + options.Conventions.AddPageRoute("/CmsKit/Pages/Update", "/Cms/Pages/Update"); + options.Conventions.AddPageRoute("/CmsKit/Blogs/Index", "/Cms/Blogs"); + options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Index", "/Cms/BlogPosts"); + options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Create", "/Cms/BlogPosts/Create"); + options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update"); + options.Conventions.AddPageRoute("/CmsKit/Comments/Index", "/Cms/Comments"); + options.Conventions.AddPageRoute("/CmsKit/Comments/Details", "/Cms/Details"); }); Configure(options => diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs index bf7d6be0d1..824660da11 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs @@ -40,7 +40,7 @@ namespace Volo.CmsKit.Admin.Web.Menus cmsMenu.AddItem(new ApplicationMenuItem( CmsKitAdminMenus.Comments.CommentsMenu, l["Comments"].Value, - "/CmsKit/Comments" + "/Cms/Comments" ) ); } @@ -53,7 +53,7 @@ namespace Volo.CmsKit.Admin.Web.Menus cmsMenu.AddItem(new ApplicationMenuItem( CmsKitAdminMenus.Tags.TagsMenu, l["Tags"].Value, - "/CmsKit/Tags")); + "/Cms/Tags")); } } @@ -64,7 +64,7 @@ namespace Volo.CmsKit.Admin.Web.Menus cmsMenu.AddItem(new ApplicationMenuItem( CmsKitAdminMenus.Pages.PagesMenu, l["Pages"].Value, - "/CmsKit/Pages")); + "/Cms/Pages")); } } @@ -75,7 +75,7 @@ namespace Volo.CmsKit.Admin.Web.Menus cmsMenu.AddItem(new ApplicationMenuItem( CmsKitAdminMenus.Blogs.BlogsMenu, l["Blogs"], - "/CmsKit/Blogs" + "/Cms/Blogs" )); } @@ -84,7 +84,7 @@ namespace Volo.CmsKit.Admin.Web.Menus cmsMenu.AddItem(new ApplicationMenuItem( CmsKitAdminMenus.BlogPosts.BlogPostsMenu, l["BlogPosts"], - "/CmsKit/BlogPosts" + "/Cms/BlogPosts" )); } } From 7efba79d46ba23d3d377c330bc80bdd9544fc99b Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 1 Mar 2021 15:44:03 +0300 Subject: [PATCH 024/101] update cms menu contributor --- .../Menus/CmsKitAdminMenuContributor.cs | 92 +++++++++++-------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs index 824660da11..e38a9e486b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.GlobalFeatures; using Volo.Abp.UI.Navigation; using Volo.CmsKit.GlobalFeatures; @@ -26,72 +28,82 @@ namespace Volo.CmsKit.Admin.Web.Menus { var l = context.GetLocalizer(); - var cmsMenu = context.Menu.FindMenuItem(CmsKitAdminMenus.GroupName); - - cmsMenu ??= new ApplicationMenuItem( - CmsKitAdminMenus.GroupName, - l["Cms"], - icon: "far fa-newspaper"); - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (await context.IsGrantedAsync(CmsKitAdminPermissions.Comments.Default)) - { - cmsMenu.AddItem(new ApplicationMenuItem( - CmsKitAdminMenus.Comments.CommentsMenu, - l["Comments"].Value, - "/Cms/Comments" - ) - ); - } - } - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (await context.IsGrantedAsync(CmsKitAdminPermissions.Tags.Default)) - { - cmsMenu.AddItem(new ApplicationMenuItem( - CmsKitAdminMenus.Tags.TagsMenu, - l["Tags"].Value, - "/Cms/Tags")); - } - } - + var cmsMenus = new List(); + if (GlobalFeatureManager.Instance.IsEnabled()) { if (await context.IsGrantedAsync(CmsKitAdminPermissions.Pages.Default)) { - cmsMenu.AddItem(new ApplicationMenuItem( + cmsMenus.Add(new ApplicationMenuItem( CmsKitAdminMenus.Pages.PagesMenu, l["Pages"].Value, "/Cms/Pages")); } } - + if (GlobalFeatureManager.Instance.IsEnabled()) { if (await context.IsGrantedAsync(CmsKitAdminPermissions.Blogs.Default)) { - cmsMenu.AddItem(new ApplicationMenuItem( + cmsMenus.Add(new ApplicationMenuItem( CmsKitAdminMenus.Blogs.BlogsMenu, l["Blogs"], "/Cms/Blogs" - )); + )); } if (await context.IsGrantedAsync(CmsKitAdminPermissions.BlogPosts.Default)) { - cmsMenu.AddItem(new ApplicationMenuItem( + cmsMenus.Add(new ApplicationMenuItem( CmsKitAdminMenus.BlogPosts.BlogPostsMenu, l["BlogPosts"], "/Cms/BlogPosts" - )); + )); + } + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + if (await context.IsGrantedAsync(CmsKitAdminPermissions.Tags.Default)) + { + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.Tags.TagsMenu, + l["Tags"].Value, + "/Cms/Tags")); + } + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + if (await context.IsGrantedAsync(CmsKitAdminPermissions.Comments.Default)) + { + cmsMenus.Add(new ApplicationMenuItem( + CmsKitAdminMenus.Comments.CommentsMenu, + l["Comments"].Value, + "/Cms/Comments" + ) + ); } } - if (cmsMenu.Items.Count > 0) + if (cmsMenus.Any()) { - context.Menu.AddItem(cmsMenu); + var cmsMenu = context.Menu.FindMenuItem(CmsKitAdminMenus.GroupName); + + if (cmsMenu == null) + { + cmsMenu = new ApplicationMenuItem( + CmsKitAdminMenus.GroupName, + l["Cms"], + icon: "far fa-newspaper"); + + context.Menu.AddItem(cmsMenu); + } + + foreach (var menu in cmsMenus) + { + cmsMenu.AddItem(menu); + } } } } From 23e263678f23d0377bf99cc928c14c3c85c3380a Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 1 Mar 2021 21:07:10 +0800 Subject: [PATCH 025/101] Mark all *.abp.io websites available in Chinese --- .../Base/Localization/Resources/en.json | 3 +- .../Base/Localization/Resources/zh-Hans.json | 3 +- .../Commercial/Localization/Resources/en.json | 247 ++++++++++++++++- .../Localization/Resources/zh-Hans.json | 256 +++++++++++++++++- 4 files changed, 502 insertions(+), 7 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index 71dc425dc6..f28ff1c4a1 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -30,6 +30,7 @@ "Permission:License": "License", "Permission:UserInfo": "Usere info", "SeeDocuments": "See Documents", - "Samples": "Samples" + "Samples": "Samples", + "Framework": "Framework" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json index f061408c98..5b9952993f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json @@ -30,6 +30,7 @@ "Permission:License": "许可", "Permission:UserInfo": "用户信息", "SeeDocuments": "查看文档", - "Samples": "示例" + "Samples": "示例", + "Framework": "框架" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 4de287778f..050d4df164 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -41,6 +41,249 @@ "Unsubscribe": "Unsubscribe", "NotOrganizationMember": "You are not member of any organization.", "UnsubscribeLicenseExpirationEmailSuccessTitle": "Successfully unsubscribed", - "UnsubscribeLicenseExpirationEmailSuccessMessage": "You will not receive license expiration date reminder emails anymore." - } + "UnsubscribeLicenseExpirationEmailSuccessMessage": "You will not receive license expiration date reminder emails anymore.", + "IndexPageHeroSection": "A complete web development platformbuilt-on framework", + "AbpCommercialShortDescription": "ABP Commercial provides pre-built application modules, rapid application development tooling, professional UI themes, premium support and more.", + "LiveDemo": "Live Demo", + "GetLicence" :"Get a Licence", + "Application": "Application", + "StartupTemplates": "Startup Templates", + "Startup": "Startup", + "Templates": "Templates", + "Developer": "Developer", + "Tools": "Tools", + "Premium": "Premium", + "Support": "Support", + "UI": "UI", + "Themes": "Themes", + "JoinOurNewsletter": "Join Our Newsletter", + "Send": "Send", + "Learn": "Learn", + "AdditionalServices": "Additional Services", + "WhatIsABPFramework": "WHAT IS THE ABP FRAMEWORK?", + "OpenSourceBaseFramework": "Open Source Base Framework", + "ABPFrameworkExplanation": "

ABP Commercial is based on the ABP Framework, an open source and community driven web application framework for ASP.NET Core.

ABP Framework provides an excellent infrastructure to write maintainable, extensible and testable code with best practices.

Built on and integrated to popular tools you already know. Low learning curve, easy adaptation, comfortable development.

", + "Modular": "Modular", + "MicroserviceCompatible": "Microservice compatible", + "DomainDrivenDesignInfrastructure": "Domain Driven Design Infrastructure", + "MultiTenancy": "Multi-Tenancy", + "DistributedMessaging": "Distributed Messaging", + "DynamicProxying": "Dynamic Proxying", + "BackgroundJobs": "Background Jobs", + "AuditLogging": "Audit Logging", + "BLOBStoring": "BLOB Storing", + "BundlingMinification": "Bundling & Minification", + "AdvancedLocalization": "Advanced Localization", + "ManyMore": "Many more", + "ExploreTheABPFramework": "Explore the ABP Framework", + "WhyUseTheABPCommercial": "Why Use The ABP Commercial?", + "WhyUseTheABPCommercialExplanation": "

Building enterprise-grade web applications can be complex and time-consuming.

ABP Commercial offers the perfect base infrastructure necessary for all modern enterprise-grade ASP.NET Core based solutions. Right from the design to deployment, the entire development cycle is empowered by ABP's built-in features & modules.

", + "StartupTemplatesShortDescription": "Startup templates make you jump-start to your project in a few seconds.", + "UIFrameworksOptions": "UI frameworks options;", + "DatabaseProviderOptions": "Database provider options;", + "PreBuiltApplicationModules": "Pre-Built Application Modules", + "PreBuiltApplicationModulesShortDescription": "Most common application requirements are already developed for you as reusable modules.", + "Account": "Account", + "Blogging": "Blogging", + "Identity": "Identity", + "IdentityServer": "Identity Server", + "Saas": "Saas", + "LanguageManagement": "Language Management", + "TextTemplateManagement": "Text Template Management", + "See All Modules": "SeeAllModules", + "ABPSuite": "ABP Suite", + "AbpSuiteShortDescription": "ABP Suite is a complementary tool to the ABP Commercial.", + "AbpSuiteExplanation": "It allows you to build web pages in a matter of minutes. It's a .NET Core Global tool which can be installed from the command line. It can create a new ABP solution, generate CRUD pages from the database to the front-end.", + "Details": "Details", + "LeptonTheme": "Lepton Theme", + "ProfessionalModernUIThemes": "Professional, modern UI themes", + "LeptonThemeExplanation": "Lepton provides a gamut of Bootstrap admin themes that serve as a solid foundation for any project requiring admin dashboard.", + "DefaultTheme": "Default Theme", + "MaterialTheme": "Material Theme", + "Default2Theme": "Default 2 Theme", + "DarkTheme": "Dark Theme", + "DarkBlueTheme": "Dark Blue Theme", + "LightTheme": "Light Theme", + "ProudToWorkWith": "Proud to Work With", + "OurConsumers": "Hundreds of enterprises and developers over 50 countries worldwide rely on ABP Commercial.", + "JoinOurConsumers": "Join them and build amazing products fast.", + "AdditionalServicesExplanation": "Do you need additional or custom services? We and our partners can provide;", + "CustomProjectDevelopment": "Custom Project Development", + "CustomProjectDevelopmentExplanation": "Dedicated developers for your custom projects.", + "PortingExistingProjects": "Porting Existing Projects", + "PortingExistingProjectsExplanation": "Migrating your legacy projects to the ABP platform.", + "LiveSupport": "Live Support", + "LiveSupportExplanation": "Live remote support option when you need it.", + "Training": "Training", + "TrainingExplanation": "Dedicated training for your developers.", + "OnBoarding": "Onboarding", + "OnBoardingExplanation": "Help to setup your development, CI & CD environments.", + "PrioritizedTechnicalSupport": "Prioritized Technical Support", + "PremiumSupportExplanation": "Beside the great community support of the ABP framework, our support team answers technical questions and problems of the commercial users with high priority.", + "SeeTheSupportOptions": "See the Support Options", + "Contact": "Contact", + "TellUsWhatYouNeed": "Tell us what you need.", + "YourMessage": "Your Message", + "YourFullName": "Your full name", + "EmailField": "E-mail Address", + "YourEmailAddress": "Your e-mail address", + "HowMayWeHelpYou": "How may we help you", + "SendMessage": "Send Message", + "Success": "Success", + "WeWillReplyYou.": "Your message is sent! We will reply you in a short time.", + "GoHome": "Go Home", + "CreateLiveDemo": "Create Live Demo", + "RegisterToTheNewsletter": "Register to the newsletter to get information on happenings about ABP.IO, like new releases.", + "EnterYourEmailOrLogin": "Enter your e-mail address to create your demo or Login using your existing account.", + "ApplicationTemplate": "Application Template", + "ApplicationTemplateExplanation": "Application startup template is used to create a new web application.", + "EfCoreProvider": "Entity Framework (Supports SQL Server, MySQL, PostgreSQL, Oracle and others)", + "AlreadyIncludedInTemplateModules": "Following modules are already included and configured in this template:", + "ApplicationTemplateArchitecture": "This application template also supports tiered architecture where UI layer, API layer and the authentication service are physically separated.", + "SeeTheGuideOrGoToTheLiveDemo": "See the developer guide for technical information about this template or go to the live demo.", + "DeveloperGuide": "Developer Guide", + "ModuleTemplate": "Module Template", + "ModuleTemplateExplanation1": "You want to create a module and reuse across different applications? This startup template prepares everything to start to create a reusable application module or a microservice.", + "ModuleTemplateExplanation2": "

You can support single or multiple UI frameworks, single or multiple database providers for a single module. The startup template is configured to run and test your module in a minimal application in addition to the unit and integration test infrastructure.

See the developer guide for technical information about this template.

", + "WithAllStyleOptions": "with all style options", + "Demo": "Demo", + "SeeAllModules": "See All Modules", + "ABPCLIExplanation": "ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions.", + "ABPSuiteEasilyCURD": "ABP Suite is a tool which allows you to easily create CRUD pages", + "WeAreHereToHelp": "We are Here to Help", + "BrowseOrAskQuestion": "You can browse our help topics or search in frequently asked questions, or you can ask us a question by using the contact form.", + "SearchQuestionPlaceholder": "Search in frequently asked questions", + "WhatIsTheABPCommercial": "What is the ABP Commercial?", + "WhatAreDifferencesThanAbpFramework": "What are the differences between the open source ABP Framework and the ABP Commercial?", + "ABPCommercialExplanation": "ABP Commercial is a set of premium modules, tools, themes and services built on top of the open source ABP framework. ABP Commercial is being developed and supported by the same team behind the ABP framework.", + "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP framework is a modular, themeable, micro-service compatible application development framework for ASP.NET Core. It provides a complete architecture and a strong infrastructure to make you focusing on your own business code rather than repeating yourself for every new project. It is based on software development best practices and popular tools you already know.

ABP framework is completely free, open source and community-driven. It also provides a free theme and some pre-built modules (e.g. identity management and tenant management).

", + "VisitTheFrameworkVSCommercialDocument": "Visit the following link, for more information {1} ", + "ABPCommercialFollowingBenefits": "ABP Commercial adds the following benefits on top of the ABP framework;", + "Professional": "Professional", + "UIThemes": "UI themes", + "EnterpriseModules": "Enterprise ready, feature rich, pre-built application modules (e.g. Identity Server management, SaaS management, language management)", + "ToolingToSupport": "Tooling to support your development productivity (e.g. ABP Suite)", + "PremiumSupportLink": "Premium support", + "WhatDoIDownloadABPCommercial": "What do I download when I purchase the ABP Commercial?", + "CreateUnlimitedSolutions": "Once you purchase an ABP Commercial license, you will be able to create unlimited solutions like described in the Getting Started document.", + "ABPCommercialSolutionExplanation": "When you create a new application, you get a Visual Studio solution (a startup template) based on your preferences. The downloaded solution has commercial modules and themes already installed and configured for you. You can remove a pre-installed module or add another module if you like. All modules and themes are used a NuGet/NPM packages by default.", + "StartDevelopWithTutorials": "The downloaded solution is well architected and documented. You can start to develop your own business code based on it following the tutorials", + "TryTheCommercialDemo": "You can try the demo to see a sample application created using the ABP Commercial startup template.", + "HowManyProducts": "How many different products/solutions can I build using the ABP Commercial?", + "HowManyProductsExplanation": "There is no limit to create an ABP project. You can create as many project as you want, develop and upload them to different servers.", + "HowManyDevelopers": "How many developers can work on the ABP Commercial?", + "HowManyDevelopersExplanation": "ABP Commercial licenses are per developer. Different license types have different developer limits. However, you can add more developers to any license type whenever you need. See the prices page for license types, developer limits and additional developer costs.", + "ChangingLicenseType": "Can I change my license type in the future?", + "ChangingLicenseTypeExplanation": "You can always add new developers in your same license type. See also \"How many developers can work on the ABP Commercial?\". You can also upgrade to a higher license by paying the calculated price difference. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date.", + "LicenseExtendUpgradeDiff": "What is the difference between license extend and upgrade?", + "LicenseExtendUpgradeDiffExplanation": "Extending: By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.
Upgrading: By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the license comparison table to check the differences between the license plans.On the other hand, when you upgrade, your license expiry date will not change!To extend your license end date, you need to extend your license.", + "LicenseRenewalCost": "What is the license renewal cost after 1 year?", + "LicenseRenewalCostExplanation": "You can renew (extend) your license by paying %80 of the current license price. For example; Standard ABP Team License is ${0} and renewal price of the Team License is ${1}.", + "IsSourceCodeIncluded": "Does my license include the source code of the commercial modules and themes?", + "IsSourceCodeIncludedExplanation1": "Depends on the license type you've purchased:", + "IsSourceCodeIncludedExplanation2": "Team: Your solution uses the modules and the themes as NuGet and NPM packages. It doesn't include their source code. In this way, you can easily upgrade these modules and themes whenever a new version is available. However, you can not get the source code of the modules and the themes.", + "IsSourceCodeIncludedExplanation3": "Business/Enterprise: In addition to the Team license, you are able to download the source code of any module or theme you need. You can even remove the NuGet/NPM package references for a particular module and add its source code directly to your solution to fully change it.", + "IsSourceCodeIncludedExplanation4": "

Including the source code of a module to your solution gives you the maximum freedom to customize that module. However, then it will not be possible to automatically upgrade the module when a new version is released.

None of the licenses include the ABP Suite source code, which is an external tool that generates code for you and assist to your development.

See the pricing page for other differences between the license types.

", + "ChangingDevelopers": "Can I change the registered developers of my organization in the future?", + "ChangingDevelopersExplanation": "In addition to add new developers to your license, you can also change the existing developers (you can remove a developer and add a new one to the same seat) without any additional cost.", + "WhatHappensWhenLicenseEnds": "What happens when my license period ends?", + "WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial has perpetual license type.After your license expires, you can continue developing your project. And you are not obliged to renew your license. After your license expires;", + "WhatHappensWhenLicenseEndsExplanation2": "You can not create new solutions using the ABP Commercial, but you can continue to develop your existing applications forever.", + "WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version. For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x)", + "WhatHappensWhenLicenseEndsExplanation4": "You can not install new modules and themes added to the ABP Commercial platform after your license ends.", + "WhatHappensWhenLicenseEndsExplanation5": "You can not use the ABP Suite.", + "WhatHappensWhenLicenseEndsExplanation6": "You can not get the premium support anymore.", + "WhatHappensWhenLicenseEndsExplanation7": "You can renew your subscription if you want to continue to get these benefits. There is a 20% discount when you renew your subscription.", + "WhenShouldIRenewMyLicense": "When should I renew my license?", + "WhenShouldIRenewMyLicenseExplanation1": "If you renew your license within 1 month after your license expires, %20 discount will be applied to total license price.", + "WhenShouldIRenewMyLicenseExplanation2": "If you renew your license after 1 month from your license expire date, the renew price will be same as license purchase price and there will be no discount for your renewal.", + "TrialPlan": "Do you have a trial plan?", + "TrialPlanExplanation": "For now, ABP Commercial doesn't have a trial plan. For the Team licenses we provide 30 days money back guarantee. You can just request a refund in the first 30 days. For the Business and Enterprise licenses, we provide 60% refund in 30 days. This is because Business and Enterprise licenses include the full source code of all the modules and the themes.", + "DoYouAcceptBankWireTransfer": "Do you accept bank wire transfer?", + "DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfer.
After sending the license amount via bank wire transfer, send us your receipt and the requested license type via e-mail.
Our international bank account information:", + "HowToUpgrade": "How to upgrade existing applications when a new version is available?", + "HowToUpgradeExplanation1": "When you create a new application using ABP Commercial, all the modules and the theme are used as NuGet and NPM packages. So, you can easily upgrade the packages when a new version is available.", + "HowToUpgradeExplanation2": "In addition to the standard NuGet/NPM upgrades, ABP CLI provides an update command that automatically finds and upgrades all ABP related packages in your solution.", + "DatabaseSupport": "Which database systems are supported?", + "DatabaseSupportExplanation": "ABP Framework itself is database agnostic and can work with any database provider by its nature. See the data access document for a list of currently implemented providers.", + "UISupport": "Which UI frameworks are supported?", + "Supported": "Supported", + "UISupportExplanation": "ABP Framework itself is UI framework agnostic and can work with any UI framework. However, startup templates, module UIs and themes were not implemented for all UI frameworks. See the getting started document for the up-to-date list of UI options.", + "MicroserviceSupport": "Does it support the micro-service architecture?", + "MicroserviceSupportExplanation1": "One of the major goals of the ABP framework is to provide a convenient infrastructure to create micro-service solutions. See the micro-service architecture document to understand how it helps to create micro-service systems.", + "MicroserviceSupportExplanation2": "All the ABP Commercial modules are designed to support micro-service deployment scenarios (with its own API and database) by following the module development best practices document.", + "MicroserviceSupportExplanation3": "We provide a sample micro-service demo solutionthat demonstrates a micro-service architecture implementation to help you to create your own solution.", + "MicroserviceSupportExplanation4": "So, the short answer is \"yes, it supports micro-service architecture\".", + "MicroserviceSupportExplanation5": "However, a micro-service system is a solution and every solution will have different requirements, network topology, communication scenarios, authentication possibilities, database separation/sharing decisions, runtime configurations, 3rd party system integrations and many more.", + "MicroserviceSupportExplanation6": "The ABP Framework and the ABP Commercial provides infrastructure for micro-service scenarios, micro-service compatible modules, samples and documentation to help you to build your own solution. But don't expect to directly download your dream solution pre-built for you. You will need to understand it and bring some parts together based on your requirements.", + "WhereCanIDownloadSourceCode": "Where can I download source-code?", + "WhereCanIDownloadSourceCodeExplanation": "You can download the source code of all ABP modules, Angular packages and themes via ABP Suite or ABP CLI. See How to download source-code?", + "ComputerLimitation": "How many computers can a developer login when developing ABP?", + "ComputerLimitationExplanation": "We specifically permit {0} computers per individual/licensed developer. Whenever there is a need for a developer to develop ABP Commercial products on a third machine, an e-mail should be sent to license@abp.io explaining the situation and we will then make the appropriate allocation in our system.", + "RefundPolicy": "Do you have a refund policy?", + "RefundPolicyExplanation": "You can request a refund within 30 days of your license purchase. The Business and Enterprise license types have source-code download option, therefore refunds are not available for the Business and Enterprise (and any licenses that include a right to receive source-code). In addition, no refunds are made for renewals and second license purchases.", + "HowCanIRefundVat": "How can I refund VAT?", + "HowCanIRefundVatExplanation1": "If you made the payment using 2Checkout, you can refund VAT via your 2Checkout account:", + "HowCanIRefundVatExplanation2": "Log in into your 2Checkout account", + "HowCanIRefundVatExplanation3": "Find the appropriate order and press \"Refund Belated VAT\" (enter your VAT ID)", + "HowCanIGetMyInvoice": "How can I get my invoice?", + "HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: PayU and 2Checkout. If you purchase your license through 2Checkout gateway, it sends the PDF invoice to your email address, see 2Checkout invoicing. If you purchase through the PayU gateway or via bank wire transfer, we will prepare and send your invoice. You can request your invoice from the organization management page.", + "Forum": "Forum", + "SupportExplanation": "ABP Commercial licenses provides a premium forum support by a team consists of the ABP Framework experts.", + "PrivateTicket": "Private Ticket", + "PrivateTicketExplanation": "Enterprise License also includes a private support with e-mail and ticket system.", + "AbpSuiteExplanation1": "ABP Suite allows you to build web pages in a matter of minutes. It's a .NET Core Global tool that can be installed from the command line.", + "AbpSuiteExplanation2": "It can create a new ABP solution, generate CRUD pages from the database to the front-end. For technical overview see the document", + "FastEasy": "Fast & Easy", + "AbpSuiteExplanation3": "ABP Suite allows you to easily create CRUD pages. You just need to define your entity and its properties, let the rest to ABP Suite for you! ABP Suite generates all the necessary code for your CRUD page in a few seconds. It supports Angular, MVC and Blazor user interfaces.", + "RichOptions": "Rich Options", + "AbpSuiteExplanation4": "ABP Suite supports multiple UI options like Razor Pages and Angular.It also supports multiple databases like MongoDB and all databases supported by EntityFramework Core (MS SQL Server, Oracle, MySql, PostgreSQL and more).", + "AbpSuiteExplanation5": "Good thing is that, you don't have to worry about those options. ABP Suite understands your project type and generates the code for your project and places the generated code in correct place in your project.", + "SourceCode": "Source Code", + "AbpSuiteExplanation6": "ABP Suite generates the source code for you! It doesn't generate magic files to generate the web page. ABP Suite generates the source code for Entity, Repository, Application Service, Code First Migration, JavaScript/TypeScript and CSHTML/HTML and necessary Interfaces as well. ABP Suite also generates the code according to Best Practices of software development, so you don't have to worry about generated code's quality.", + "AbpSuiteExplanation7": "Since you have the source code of building blocks of the generated CRUD page in correct application layers, you can easily modify the source code and inject your custom/bussiness logic to the generated code.", + "CrossPlatform": "Cross Platform", + "AbpSuiteExplanation8": "ABP Suite is built with .NET Core and it is cross platform. It runs as a web application on your local computer. You can run it on Windows, Mac and Linux", + "OtherFeatures": "Other Features", + "OtherFeatures1": "Updates NuGet and NPM packages on your solution easily.", + "OtherFeatures2": "Regenerates already generated pages from scratch.", + "OtherFeatures3": "Creates new solutions", + "ThanksForCreatingProject": "Thanks for Creating Your Project!", + "HotToRunSolution": "How to run your solution?", + "HotToRunSolutionExplanation": "See getting started document to learn how to configure and run your solution.", + "GettingStarted": "Getting Started", + "WebAppDevTutorial": "Web App Dev Tutorial", + "WebAppDevTutorialExplanation": "See web application development tutorial document for a step by step development sample.", + "Document": "Document", + "UsingABPSuiteToCURD": "Using ABP Suite for CRUD Page Generation & Tooling", + "SeeABPSuiteDocument": "See ABP Suite document to learn the usage of ABP Suite.", + "AskQuestionsOnSupport": "You can ask questions on ABP Commercial Support.", + "Documentation": "Documentation", + "SeeModulesDocument": "See modules document for a list of all commercial (pro) modules and their documents.", + "Pricing": "Pricing", + "PricingExplanation": "Choose the features and functionality your business needs today. Easily upgrade as your business grows.", + "Team": "Team", + "Business": "Business", + "Enterprise": "Enterprise", + "Custom": "Custom", + "IncludedDeveloperLicenses": "Included developer licenses", + "CustomLicenceOrAdditionalServices": "Need custom licence or additional services?", + "CustomOrVolumeLicense": "Custom or volume license", + "LiveTrainingSupport": "Live training & support", + "AndMore": "and more", + "AdditionalDeveloperLicense": "Additional developer license", + "ProjectCount": "Project count", + "AllProModules": "All pro modules", + "AllProThemes": "All pro themes", + "AllProStartupTemplates": "All pro startup templates", + "SourceCodeOfAllModules": "Source code of all modules", + "SourceCodeOfAllThemes": "Source code of all themes", + "PerpetualLicense": "Perpetual license", + "UnlimitedServerDeployment": "Unlimited server deployment", + "YearUpgrade": "1 year upgrade", + "YearPremiumForumSupport": "1 year premium forum support", + "ForumSupportIncidentCountYear": "Forum support incident count/year", + "PrivateTicketEmailSupport": "Private ticket & email support", + "BuyNow": "Buy Now" + } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index 82c23450a0..bc634de3c2 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -16,7 +16,7 @@ "Name": "名称", "EmailAddress": "电子邮件地址", "Developers": "开发者", - "LicenseType": "许可证类型", + "LicenseType": "许可类型", "Manage": "管理", "StartDate": "开始日期", "EndDate": "结束日期", @@ -33,7 +33,257 @@ "EmailNotValid": "请输入有效的电子邮件地址", "JoinOurMarketingNewsletter": "加入我们的营销简讯", "WouldLikeToReceiveMarketingMaterials": "我想收到市场营销资料,例如产品交易和特别优惠.", - "StartUsingYourLicenseNow": "立即开始使用你的许可证", - "WelcomePage": "欢迎页面" + "StartUsingYourLicenseNow": "立即开始使用你的许可", + "WelcomePage": "欢迎页面", + "UnsubscriptionExpireEmail": "退订许可到期提醒邮件", + "UnsubscribeLicenseExpireEmailReminderMessage": "此电子邮件订阅仅提醒你许可的到期日期.", + "UnsubscribeFromLicenseExpireEmails": "如果你不想收到关于许可到期邮件,你可以在任何时间取消订阅.", + "Unsubscribe": "取消订阅", + "NotOrganizationMember": "你不是任何组织的成员.", + "UnsubscribeLicenseExpirationEmailSuccessTitle": "退订成功", + "UnsubscribeLicenseExpirationEmailSuccessMessage": "你不会再收到任何许可到期提醒邮件.", + "IndexPageHeroSection": "一个完整的web开发平台基于 框架", + "AbpCommercialShortDescription": "ABP商业版提供了预构建的应用程序模块, 快速的应用程序开发工具, 专业的UI主题, 高级支持等.", + "LiveDemo": "在线演示", + "GetLicence" :"获得许可", + "Application": "应用程序", + "StartupTemplates": "启动模板", + "Startup": "启动", + "Templates": "模板", + "Developer": "开发人员", + "Tools": "工具", + "Premium": "高级", + "Support": "支持", + "UI": "UI", + "Themes": "主题", + "JoinOurNewsletter": "加入我们的时事通讯", + "Send": "发送", + "Learn": "学习", + "AdditionalServices": "额外的服务", + "WhatIsABPFramework": "什么是ABP框架?", + "OpenSourceBaseFramework": "开源的框架", + "ABPFrameworkExplanation": "

ABP商业版基于ABP框架, 这是一个开源和社区驱动的ASP.NET Core web应用程序开发框架.

ABP框架提供了出色的基础设施, 使用最佳实践编写可维护,可扩展,可测试的代码.

基于你已经知道的流行工具. 低学习曲线,容易适应,舒适的开发体检.

", + "Modular": "模块化", + "MicroserviceCompatible": "微服务兼容", + "DomainDrivenDesignInfrastructure": "领域驱动设计基础设施", + "MultiTenancy": "多租户", + "DistributedMessaging": "分布式消息", + "DynamicProxying": "动态代理", + "BackgroundJobs": "后台作业", + "AuditLogging": "审计日志", + "BLOBStoring": "BLOB存储", + "BundlingMinification": "捆绑 & 压缩", + "AdvancedLocalization": "高级本地化", + "ManyMore": "以及更多", + "ExploreTheABPFramework": "探索ABP框架", + "WhyUseTheABPCommercial": "为什么使用ABP商业版?", + "WhyUseTheABPCommercialExplanation": "

构建企业级的web应用程序可能复杂和耗时.

ABP商业版提供所有现代企业级基于ASP.NET Core的解决方案所需要的基础设施. 从设计到部署,整个开发生命周期都由ABP的内置功能和模块提供支持.

", + "StartupTemplatesShortDescription": "启动模板使你在几秒内快速启动项目.", + "UIFrameworksOptions": "UI框架选项;", + "DatabaseProviderOptions": "数据库提供程序选项;", + "PreBuiltApplicationModules": "预构建的应用程序模块", + "PreBuiltApplicationModulesShortDescription": "大多数常见的应用程序需求已经做为可重用的模块为你开发了.", + "Account": "账户", + "Blogging": "博客", + "Identity": "Identity", + "IdentityServer": "Identity Server", + "Saas": "Saas", + "LanguageManagement": "语言管理", + "TextTemplateManagement": "文本模板管理", + "See All Modules": "查看所有的模块", + "ABPSuite": "ABP Suite", + "AbpSuiteShortDescription": "ABP Suite是ABP商业版的辅助工具.", + "AbpSuiteExplanation": "它让你在几分钟内构建web页面. 它是一个.Net Core全局工具,可以使用命令行安装. 它可以创建一个新的ABP解决方案,从数据库生成前端CURD页面.", + "Details": "详情", + "LeptonTheme": "Lepton主题", + "ProfessionalModernUIThemes": "专业, 现代化的UI主题", + "LeptonThemeExplanation": "Lepton提供了一系列的Bootstrap管理主题,为任何需要管理仪表盘的项目提供了坚实的基础.", + "DefaultTheme": "默认主题", + "MaterialTheme": "Material主题", + "Default2Theme": "默认主题2", + "DarkTheme": "深色主题", + "DarkBlueTheme": "深蓝主题", + "LightTheme": "浅色主题", + "ProudToWorkWith": "荣幸与你合作", + "OurConsumers": "全球50多个国家的数百家企业和开发商使用ABP商业版.", + "JoinOurConsumers": "加它他们并快速构建令人惊叹的产品.", + "AdditionalServicesExplanation": "你是否需要额外或自定义的服务? 我们和我们的合作伙伴可以提供;", + "CustomProjectDevelopment": "自定义项目开发", + "CustomProjectDevelopmentExplanation": "专为你的自定义的开发人员.", + "PortingExistingProjects": "移植现有项目", + "PortingExistingProjectsExplanation": "将你的迁移传统项目迁移到ABP平台.", + "LiveSupport": "实时支持", + "LiveSupportExplanation": "在你需要时,可以实时提供远程支持选项.", + "Training": "培训", + "TrainingExplanation": "为你的开发人员提供专门培训.", + "OnBoarding": "管理", + "OnBoardingExplanation": "帮助设置你的开发,CI和CD环境.", + "PrioritizedTechnicalSupport": "优先的技术支持", + "PremiumSupportExplanation": "除了社区对ABP框架出色支持外,我们的支持团队会优先回答商业用户的技术问题.", + "SeeTheSupportOptions": "查看支持选项", + "Contact": "联系", + "TellUsWhatYouNeed": "告诉我们你需要什么.", + "YourMessage": "你的消息", + "YourFullName": "你的全名", + "EmailField": "E-mail地址", + "YourEmailAddress": "你的e-mail地址", + "HowMayWeHelpYou": "我们如何帮助你", + "SendMessage": "发送消息", + "Success": "成功", + "WeWillReplyYou.": "你的消息已经发送! 我们会在短时间内给你答复.", + "GoHome": "回到主页面", + "CreateLiveDemo": "创建在线演示", + "RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.", + "EnterYourEmailOrLogin": "输入你的e-mail地址来创建你的演示或者使用你的已有账号登录.", + "ApplicationTemplate": "应用程序模板", + "ApplicationTemplateExplanation": "应用程序启动模板用于创建新的web应用程序.", + "EfCoreProvider": "Entity Framework (支持 SQL Server, MySQL, PostgreSQL, Oracle 和其它)", + "AlreadyIncludedInTemplateModules": "以下模块已经包含并配置在此模板中:", + "ApplicationTemplateArchitecture": "应用程序模板还支持UI,API,身份验证服务器物理分离的分层架构.", + "SeeTheGuideOrGoToTheLiveDemo": "查看开发人员指南或者查看在线演示了解更多关于模板的信息.", + "DeveloperGuide": "开发人员指南", + "ModuleTemplate": "模块模块", + "ModuleTemplateExplanation1": "你是否想要创建可在不同应用程序之间重用的模块? 这个启动模板准备好了一切来创建可重用的应用程序模块或微服务.", + "ModuleTemplateExplanation2": "

你可以为一个模块支持单个或多个UI框架, 单个或多个数据库提供程序. 除了单元测试和集成测试基础架构外,启动模板被配置为在一个最小的应用程序中运行和测试你的模块.

查看开发人员指南了解有关此模板的技术信息.

", + "WithAllStyleOptions": "使用所有的样式选项", + "Demo": "演示", + "SeeAllModules": "查看所有的模块", + "ABPCLIExplanation": "ABP CLI(命令行页面)是一个执行基于ABP解决方案的一些常见操作的命令行工具.", + "ABPSuiteEasilyCURD": "ABP Suite是一个使你轻松创建CURD页面的工具", + "WeAreHereToHelp": "我们在这里为你提供帮助", + "BrowseOrAskQuestion": "你可以浏览我们的帮助主题或搜索常见的问题, 或者你可以使用联系表单向我们提问.", + "SearchQuestionPlaceholder": "搜索常见的问题", + "WhatIsTheABPCommercial": "什么是ABP商业版?", + "WhatAreDifferencesThanAbpFramework": "ABP框架与ABP商业版有什么不同?", + "ABPCommercialExplanation": "ABP商业版是一套基于开源ABP框架之上的高级模块,工具,主题和服务. ABP商业版由ABP框架背后的同一团队开发和支持.", + "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP框架是模块化,主题化,微服务兼容的ASP.NET Core应用程序开发框架. 它提供了一个完整的架构和强大的基础设施,让你专注于自己的业务代码而不是重复自己的每一个项目. 它基于软件开发的最佳实践和你已经知道的流行工具

ABP框架是完全免费,开源和由社区驱动的. 它还提供了一个免费的主题和一些预构建的模块 (如 identity管理和租户管理).

", + "VisitTheFrameworkVSCommercialDocument": "访问以下链接,了解更多信息 {1} ", + "ABPCommercialFollowingBenefits": "ABP商业版在ABP框架之上添加了以下好处;", + "Professional": "专业的", + "UIThemes": "UI主题", + "EnterpriseModules": "企业就绪,功能丰富,预构建的应用程序模块 (如 Identity Server管理, SaaS管理, 语言管理)", + "ToolingToSupport": "支持你的生产力的工具(如. ABP Suite)", + "PremiumSupportLink": "高级支持", + "WhatDoIDownloadABPCommercial": "购买ABP商业版后我可以下载什么?", + "CreateUnlimitedSolutions": "一旦你购买了ABP商业许可, 你可以创建入门文档中描述的无限的解决方案.", + "ABPCommercialSolutionExplanation": "创建新应用程序时,将根据你的首选项获得Visual Studio解决方案(启动模板). 下载的解决方案已为你安装并配置了商业模块和主题. 你可以删除预装的模块,也可以根据需要添加其他模块. 默认情况下所有模块和主题都使用NuGet/NPM软件包.", + "StartDevelopWithTutorials": "下载的解决方案经过精心设计和记录, 你可以根据教程来开发自己的业务代码.", + "TryTheCommercialDemo": "你可以尝试示例来查看使用ABP商业模板创建的示例应用程序.", + "HowManyProducts": "使用ABP商业版,我可以构建多少不同的产品/解决方案?", + "HowManyProductsExplanation": "创建ABP项目没有限制. 你可以根据需要创建任意数量的项目,进行开发并将其部署到其他服务器.", + "HowManyDevelopers": "有多少开发者可以参与ABP商业版工作?", + "HowManyDevelopersExplanation": "ABP商业许可是针对每个开发人员的. 不同的许可类型具有不同的开发人员限制. 但是你可以在需要时将更多开发人员添加到任何许可类型. 查看许可类型,开发人员限制和额外的开发人员成本的价格页面.", + "ChangingLicenseType": "将来更改我的许可类型吗?", + "ChangingLicenseTypeExplanation": "你始终可以在同一许可中添加新的开发人员. 参阅 \"有多少开发者可以参与ABP商业版工作?\". 你还可以通过支付计算出的价格差来升级到更高的许可. 当你升级到更高的许可计划时,可以享受新计划的好处,但是许可升级不会更改许可的到期日期.", + "LicenseExtendUpgradeDiff": "许可扩展和升级有什么区别?", + "LicenseExtendUpgradeDiffExplanation": "扩展: 通过扩展/更新许可,你将继续获得高级支持,并获得有关模块和主题的重大更新. 此外你将能够继续创建新项目. 而且你仍然可以使用ABP Suite来加快开发速度.
升级: 通过升级许可,你将升级到更高的许可计划,这将使你获得更多好处. 查看 许可比较表来检查许可计划之间的差异. 另一方面,当你升级时你的许可到期日期不会改变!要延长你的许可终止日期,你需要延长你的许可.", + "LicenseRenewalCost": "一年后的许可续期费用是多少?", + "LicenseRenewalCostExplanation": "你可以通过支付当前许可价格的%80来续订(扩展)你的许可. 例如; 标准ABP团队许可为 ${0} 续订价格是 ${1}.", + "IsSourceCodeIncluded": "我的许可是否包括商业模块和主题的源代码?", + "IsSourceCodeIncludedExplanation1": "取决于你购买的许可类型:", + "IsSourceCodeIncludedExplanation2": "团队: 你的解决方案将这些模块和主题作为NuGet和NPM包使用. 它不包括其源代码. 这样,只要有新版本可用,你就可以轻松升级这些模块和主题. 但是,你无法获取模块和主题的源代码.", + "IsSourceCodeIncludedExplanation3": "商业/企业: 除了团队许可外,你还可以下载所需的任何模块或主题的源代码. 你甚至可以删除特定模块的NuGet/NPM软件包引用,并将其源代码直接添加到你的解决方案中以完全更改它.", + "IsSourceCodeIncludedExplanation4": "

将模块的源代码包含到解决方案中,可以最大程度地自定义该模块. 但是当新版本发布时,将无法自动升级模块.

这些许可均不包含ABP Suite源代码,该源代码是一个外部工具,可以为你生成代码并帮助你进行开发

有关许可类型之间的其它差异查看定价页面.

", + "ChangingDevelopers": "我将来可以更改我组织的注册开发人员吗?", + "ChangingDevelopersExplanation": "除了将新的开发人员添加到你的许可中之外,你还可以更改现有的开发人员(可以删除一个开发人员并将新的开发人员添加到同一位置),而无需任何额外费用.", + "WhatHappensWhenLicenseEnds": "我的许可期限结束后会怎样?", + "WhatHappensWhenLicenseEndsExplanation1": "ABP商业版具有永久许可类型.许可到期后, 你可以继续开发你的项目.并且你没有义务续订许可.许可到期后;", + "WhatHappensWhenLicenseEndsExplanation2": "你不能使用ABP商业版创建新的解决方案,但可以永远继续开发现有的应用程序.", + "WhatHappensWhenLicenseEndsExplanation3": "你能够在你的主版本中获得模块和主题的更新.例如;如果你使用的是模块的v3.2.0版本,你仍然可以获得v3.x.x版本的更新.(v3.3.0 v3.5.2…等等)的.但是你无法获得下一个主要版本(如v4.x,v5.x)的更新", + "WhatHappensWhenLicenseEndsExplanation4": "许可到期后,你无法安装添加到ABP商业平台的新模块和主题.", + "WhatHappensWhenLicenseEndsExplanation5": "你不能使用ABP Suite.", + "WhatHappensWhenLicenseEndsExplanation6": "你不再获得高级支持.", + "WhatHappensWhenLicenseEndsExplanation7": "如果你想继续获得这些好处,可以继续续订. 续订时有20%的折扣.", + "WhenShouldIRenewMyLicense": "我什么时候应该续订我的许可?", + "WhenShouldIRenewMyLicenseExplanation1": "如果你在许可到期后的 1个月内续订许可,则许可总价将享受%20的折扣.", + "WhenShouldIRenewMyLicenseExplanation2": "如果你在你的许可过期日期1个月后更新你的许可,更新价格将与许可购买价格相同,你的更新将没有折扣.", + "TrialPlan": "你们有试用计划吗?", + "TrialPlanExplanation": "目前,ABP商业版还没有试用计划.对于团队许可,我们提供30天的退款保证.你可以在30天内要求退款.对于企业营业执照,我们提供30天内60%的退款.这是因为商业和企业许可包含所有模块和主题的完整源代码.", + "DoYouAcceptBankWireTransfer": "你们接受银行电汇吗?", + "DoYouAcceptBankWireTransferExplanation": "是的,我们接受银行电汇.
通过银行电汇转账,通过电子邮件将收据和所要求的许可类型发送给我们.
我们的国际银行帐户信息:", + "HowToUpgrade": "可用新版本时如何升级现有应用程序?", + "HowToUpgradeExplanation1": "使用ABP商业版创建新应用程序时,所有模块和主题均用作NuGet和NPM软件包. 因此,当有新版本可用时,你可以轻松升级软件包.", + "HowToUpgradeExplanation2": "除了标准的NuGet/NPM升级之外, ABP CLI 还提供了一条更新命令,该命令可自动查找和升级解决方案中的所有与ABP相关的软件包.", + "DatabaseSupport": "支持哪些数据库系统?", + "DatabaseSupportExplanation": "ABP框架本身与数据库无关,并且就其性质而言,可以与任何数据库提供程序一起使用. 请参阅数据访问文档以获取当前实现的提供程序的列表.", + "UISupport": "支持哪些UI框架?", + "Supported": "支持的", + "UISupportExplanation": "ABP框架本身与UI框架无关,并且可以与任何UI框架一起使用. 但是,并非针对所有UI框架都实现了启动模板,模块UI和主题. 有关UI选项的最新列表,请参见入门文档.", + "MicroserviceSupport": "它是否支持微服务架构?", + "MicroserviceSupportExplanation1": "ABP框架的主要目标之一是为创建微服务解决方案提供便利的基础架构. 请参阅微服务体系结构文档,以了解它如何帮助创建微服务系统.", + "MicroserviceSupportExplanation2": "所有的ABP商业模块通过模块开发最佳实践文档被设计为支持微服务部署场景(使用自己的API和数据库).", + "MicroserviceSupportExplanation3": "我们提供了一个示例微服务演示解决方案,该示例演示了一种微服务架构实现,可帮助你创建自己的解决方案.", + "MicroserviceSupportExplanation4": "所以简短的答案是 \"是的, 它支持微服务体系结构\".", + "MicroserviceSupportExplanation5": "但是,微服务系统是一个解决方案,每个解决方案都有不同的要求,网络拓扑,通信场景,身份验证可能性,数据库分离/共享决策,运行时配置,第三方系统集成等等.", + "MicroserviceSupportExplanation6": "ABP框架和ABP商业版提供了微服务方案,微服务兼容模块,示例和文档的基础结构,以帮助你构建自己的解决方案. 但是不要期望直接下载为你预先构建的梦想解决方案. 你将需要了解它,并根据需要将某些部分组合在一起.", + "WhereCanIDownloadSourceCode": "在哪里可以下载源代码?", + "WhereCanIDownloadSourceCodeExplanation": "你可以通过ABP Suite或ABP CLI下载所有ABP模块,Angular软件包和主题的源代码. 请参见如何下载源代码?", + "ComputerLimitation": "开发人员在开发ABP时可以登录到多少台计算机?", + "ComputerLimitationExplanation": "我们特别允许每个个人/许可的开发人员使用 {0}台计算机. 每当需要开发人员在第三台计算机上开发ABP商业产品时,都应将电子邮件发送到license@abp.io,以说明情况,然后我们将在系统中进行适当分配.", + "RefundPolicy": "你们有退款政策吗?", + "RefundPolicyExplanation": "你可以在购买许可的30天内请求退款.商业和企业许可类型都有源代码下载选项,因此商业和企业(以及任何包含获得源代码的权利的许可)都不能退款.此外,续展和购买第二次许可也不退款.", + "HowCanIRefundVat": "我该如何退还增值税?", + "HowCanIRefundVatExplanation1": "如果你使用2Checkout付款,则可以通过2Checkout帐户退还增值税:", + "HowCanIRefundVatExplanation2": "登录到你的2Checkout账户", + "HowCanIRefundVatExplanation3": "找到适当的订单,然后按\"退还已延期的增值税\"(输入你的增值税ID", + "HowCanIGetMyInvoice": "我如何获得发票?", + "HowCanIGetMyInvoiceExplanation": "有两个用于购买许可的支付网关:PayU和2Checkout. 如果你通过2Checkout网关购买许可,则它将PDF发票发送到你的电子邮件地址,请参阅2Checkout发票.如果你是通过PayU网关或通过银行电汇购买的,我们将准备并发送你的发票. 你可以从组织管理页面索取发票.", + "Forum": "论坛", + "SupportExplanation": "ABP商业版许可包含由ABP框架专家组成的团队提供的高级论坛支持.", + "PrivateTicket": "私有票", + "PrivateTicketExplanation": "企业许可还包含带有电子邮件和票系统的私人支持.", + "AbpSuiteExplanation1": "ABP Suite使你在几分钟内构建web页面. 它是一个.NET Core Global工具,可以使用命令行安装.", + "AbpSuiteExplanation2": "它可以创建一个新的ABP解决方案, 从数据库生成前端CURD页面. 有关技术概述查看文档", + "FastEasy": "快速并且简单", + "AbpSuiteExplanation3": "ABP Suite允许你轻松的创建CURD页面. 你只需要定义你的实体和它的属性, 其它的让ABP Suite帮你完成! ABP Suite会在几秒内为你生成CURD页面和必要的代码. 它支持Angular, MVC和 Blazor用户界面.", + "RichOptions": "丰富的选项", + "AbpSuiteExplanation4": "ABP Suite支持多个UI选项,例如 Razor Pages和Angular.它还支持多个数据库, 如 MongoDB 和EntityFramework Core支持的所有数据库(MS SQL Server, Oracle, MySql, PostgreSQL 和 更多).", + "AbpSuiteExplanation5": "好消息是, 你不必担心这些选项. ABP Suite了解你的项目类型并且将生成的代码放到项目中正确的位置.", + "SourceCode": "源码", + "AbpSuiteExplanation6": "ABP Suite为你生成源代码! 它不会生成魔法文件来生成web页面. ABP Suite为实体, 仓储, 应用程序, Code First迁移, JavaScript/TypeScript 和 CSHTML/HTML以及必要的页面生成源代码. ABP Suite根据软件开发的最佳实践来生成代码, 所以你不必担心生成的代码的质量.", + "AbpSuiteExplanation7": "由于你有应用程序层中生成的CURD页面的构建块的源代码, 因此你可以轻松修改源码并将自定义/业务逻辑注入到所生成的代码中.", + "CrossPlatform": "跨平台", + "AbpSuiteExplanation8": "ABP Suite使用.NET Core构建并且它是跨平台的. 它在你的本地电脑中运行为web应用程序. 你可以在Windows, Mac和Linux上运行它", + "OtherFeatures": "其他功能", + "OtherFeatures1": "轻松更新你的解决方案的NuGet和NPM包.", + "OtherFeatures2": "重新生成已经生成的页面.", + "OtherFeatures3": "创建新的解决方案", + "ThanksForCreatingProject": "感谢你创建你的项目!", + "HotToRunSolution": "如何运行你的解决方案?", + "HotToRunSolutionExplanation": "查看入门文档来学习如何配置和运行你的解决方案.", + "GettingStarted": "入门", + "WebAppDevTutorial": "Web应用开发教程", + "WebAppDevTutorialExplanation": "查看web应用程序开发教程文档来一步一步的了解开发示例.", + "Document": "文档", + "UsingABPSuiteToCURD": "使用ABP Suite来生成CURD页面", + "SeeABPSuiteDocument": "查看ABP Suite文档学习如何使用ABP Suite.", + "AskQuestionsOnSupport": "你可以在ABP商业支持提出问题.", + "Documentation": "文档", + "SeeModulesDocument": "查看模块文档获取所有商业(专业)模块列表和它们的文档.", + "Pricing": "价格", + "PricingExplanation": "选择当前业务需要的特性和功能. 随着业务增长轻松升级.", + "Team": "团队", + "Business": "商业", + "Enterprise": "企业", + "Custom": "自定义", + "IncludedDeveloperLicenses": "包括开发人员许可", + "CustomLicenceOrAdditionalServices": "需要自定义许可与额外服务?", + "CustomOrVolumeLicense": "自定义或批量许可", + "LiveTrainingSupport": "现场培训和支持", + "AndMore": "和更多", + "AdditionalDeveloperLicense": "额外的开发人员许可", + "ProjectCount": "项目数量", + "AllProModules": "所有模块", + "AllProThemes": "所有主题", + "AllProStartupTemplates": "所有专业启动模板", + "SourceCodeOfAllModules": "所有模块的源码", + "SourceCodeOfAllThemes": "所有主题的源码", + "PerpetualLicense": "永久的许可", + "UnlimitedServerDeployment": "无限制的服务器部署", + "YearUpgrade": "1年升级", + "YearPremiumForumSupport": "1年高级论坛支持", + "ForumSupportIncidentCountYear": "论坛支持事件数量/年", + "PrivateTicketEmailSupport": "私有票和email支持", + "BuyNow": "现在购买" } } \ No newline at end of file From 52c40009d4927471efb46369c8f0d5fc9819571c Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 1 Mar 2021 21:15:53 +0800 Subject: [PATCH 026/101] Improve --- .../AbpIoLocalization/Base/Localization/Resources/en.json | 3 ++- .../AbpIoLocalization/Base/Localization/Resources/zh-Hans.json | 3 ++- .../Commercial/Localization/Resources/en.json | 3 ++- .../Commercial/Localization/Resources/zh-Hans.json | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index f28ff1c4a1..eedfd4bccd 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -31,6 +31,7 @@ "Permission:UserInfo": "Usere info", "SeeDocuments": "See Documents", "Samples": "Samples", - "Framework": "Framework" + "Framework": "Framework", + "Support": "Support" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json index 5b9952993f..01550612d4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json @@ -31,6 +31,7 @@ "Permission:UserInfo": "用户信息", "SeeDocuments": "查看文档", "Samples": "示例", - "Framework": "框架" + "Framework": "框架", + "Support": "支持" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 050d4df164..b03d57cee0 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -53,7 +53,8 @@ "Developer": "Developer", "Tools": "Tools", "Premium": "Premium", - "Support": "Support", + "PremiumSupport": "Premium Support", + "PremiumForumSupport": "Premium Forum Support", "UI": "UI", "Themes": "Themes", "JoinOurNewsletter": "Join Our Newsletter", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index bc634de3c2..0e1e61dba8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -53,7 +53,8 @@ "Developer": "开发人员", "Tools": "工具", "Premium": "高级", - "Support": "支持", + "PremiumSupport": "高级支持", + "PremiumForumSupport": "高级论坛支持", "UI": "UI", "Themes": "主题", "JoinOurNewsletter": "加入我们的时事通讯", From 1debba1829e270c6b426da27c15ad56c0a880e53 Mon Sep 17 00:00:00 2001 From: GameBelial <243387971@qq.com> Date: Mon, 1 Mar 2021 22:32:37 +0800 Subject: [PATCH 027/101] Add support for RabbitMQ cluster. --- .../Volo/Abp/RabbitMQ/ConnectionPool.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs index 5856f7bb16..7ca8346d11 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ConnectionPool.cs @@ -26,10 +26,13 @@ namespace Volo.Abp.RabbitMQ return Connections.GetOrAdd( connectionName, - () => Options - .Connections - .GetOrDefault(connectionName) - .CreateConnection() + () => + { + var connection = Options.Connections.GetOrDefault(connectionName); + var hostnames = connection.HostName.TrimEnd(';').Split(';'); + // Handle Rabbit MQ Cluster. + return hostnames.Length == 1 ? connection.CreateConnection() : connection.CreateConnection(hostnames); + } ); } From fc9ade905d395578aa9073b7697dabb3c34bd024 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 1 Mar 2021 18:05:37 +0300 Subject: [PATCH 028/101] Added EntityType to mediadescriptopr entity --- .../Admin/MediaDescriptors/CreateMediaInputStream.cs | 4 ++++ .../MediaDescriptors/MediaDescriptorAdminAppService.cs | 2 +- .../MediaDescriptors/MediaDescriptorAdminController.cs | 4 +++- .../Volo/CmsKit/MediaDescriptors/MediaDescriptorConsts.cs | 6 +++++- .../Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs | 8 +++++--- .../{MediaDescriptorCheck.cs => MediaDescriptorChecks.cs} | 4 ++-- .../CmsKitDbContextModelCreatingExtensions.cs | 1 + .../Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs | 2 +- .../cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs | 3 +++ 9 files changed, 25 insertions(+), 9 deletions(-) rename modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/{MediaDescriptorCheck.cs => MediaDescriptorChecks.cs} (77%) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/CreateMediaInputStream.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/CreateMediaInputStream.cs index b61d50e124..0f66ab5fef 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/CreateMediaInputStream.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/CreateMediaInputStream.cs @@ -8,6 +8,10 @@ namespace Volo.CmsKit.Admin.MediaDescriptors { public class CreateMediaInputStream : RemoteStreamContent { + [Required] + [DynamicStringLength(typeof(MediaDescriptorConsts), nameof(MediaDescriptorConsts.MaxEntityTypeLength))] + public string EntityType { get; set; } + [Required] [DynamicStringLength(typeof(MediaDescriptorConsts), nameof(MediaDescriptorConsts.MaxNameLength))] public string Name { get; set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index 17af6a9993..ee2b5af152 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -27,7 +27,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors { var newId = GuidGenerator.Create(); var stream = inputStream.GetStream(); - var newEntity = new MediaDescriptor(newId, inputStream.Name, inputStream.ContentType, stream.Length, CurrentTenant.Id); + var newEntity = new MediaDescriptor(newId, inputStream.EntityType, inputStream.Name, inputStream.ContentType, stream.Length, CurrentTenant.Id); await MediaContainer.SaveAsync(newId.ToString(), stream); await MediaDescriptorRepository.InsertAsync(newEntity); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs index 4267f635b0..124cfcba1c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs @@ -42,8 +42,9 @@ namespace Volo.CmsKit.Admin.MediaDescriptors } [HttpPost] + [Route("{entityType}")] [Authorize(CmsKitAdminPermissions.MediaDescriptors.Create)] - public virtual async Task UploadAsync(IFormFile file) + public virtual async Task UploadAsync(string entityType, IFormFile file) { if (file == null) { @@ -52,6 +53,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors var inputStream = new CreateMediaInputStream(file.OpenReadStream()) { + EntityType = entityType, ContentType = file.ContentType, Name = file.FileName }; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/MediaDescriptors/MediaDescriptorConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/MediaDescriptors/MediaDescriptorConsts.cs index 5f4741828e..31737fa9fe 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/MediaDescriptors/MediaDescriptorConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/MediaDescriptors/MediaDescriptorConsts.cs @@ -1,7 +1,11 @@ -namespace Volo.CmsKit.MediaDescriptors +using Volo.CmsKit.Entities; + +namespace Volo.CmsKit.MediaDescriptors { public class MediaDescriptorConsts { + public static int MaxEntityTypeLength { get; set; } = CmsEntityConsts.MaxEntityTypeLength; + public static int MaxNameLength { get; set; } = 255; public static int MaxMimeTypeLength { get; set; } = 128; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs index 3829a3afef..c97eb26b9a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs @@ -2,13 +2,14 @@ using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; -using Volo.CmsKit.MediaDescriptors.Extensions; namespace Volo.CmsKit.MediaDescriptors { public class MediaDescriptor : FullAuditedAggregateRoot, IMultiTenant { public Guid? TenantId { get; protected set; } + + public string EntityType { get; set; } public string Name { get; protected set; } @@ -21,10 +22,11 @@ namespace Volo.CmsKit.MediaDescriptors } - public MediaDescriptor(Guid id, string name, string mimeType, long size, Guid? tenantId = null) : base(id) + public MediaDescriptor(Guid id, string entityType, string name, string mimeType, long size, Guid? tenantId = null) : base(id) { TenantId = tenantId; + EntityType = Check.NotNullOrEmpty(entityType, nameof(entityType), MediaDescriptorConsts.MaxEntityTypeLength); MimeType = Check.NotNullOrWhiteSpace(mimeType, nameof(name), MediaDescriptorConsts.MaxMimeTypeLength); Size = size; @@ -33,7 +35,7 @@ namespace Volo.CmsKit.MediaDescriptors public void SetName(string name) { - if (!MediaDescriptorCheck.IsValidMediaFileName(name)) + if (!MediaDescriptorChecks.IsValidMediaFileName(name)) { throw new InvalidMediaDescriptorNameException(name); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorCheck.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorChecks.cs similarity index 77% rename from modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorCheck.cs rename to modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorChecks.cs index 5ef0c4497a..1881de83e3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorCheck.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorChecks.cs @@ -1,9 +1,9 @@ using System.IO; using System.Linq; -namespace Volo.CmsKit.MediaDescriptors.Extensions +namespace Volo.CmsKit.MediaDescriptors { - public static class MediaDescriptorCheck + public static class MediaDescriptorChecks { public static bool IsValidMediaFileName(string name) { diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 2f7308be95..476e2a3111 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -242,6 +242,7 @@ namespace Volo.CmsKit.EntityFrameworkCore b.ConfigureByConvention(); + b.Property(x => x.EntityType).IsRequired().HasMaxLength(MediaDescriptorConsts.MaxEntityTypeLength); b.Property(x => x.Name).IsRequired().HasMaxLength(MediaDescriptorConsts.MaxNameLength); b.Property(x => x.MimeType).IsRequired().HasMaxLength(MediaDescriptorConsts.MaxMimeTypeLength); b.Property(x => x.Size).HasMaxLength(MediaDescriptorConsts.MaxSizeLength); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index be28728596..9bdd1cfb96 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -402,7 +402,7 @@ namespace Volo.CmsKit { using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(_cmsKitTestData.Media_1_Content))) { - var media = new MediaDescriptor(_cmsKitTestData.Media_1_Id, _cmsKitTestData.Media_1_Name, _cmsKitTestData.Media_1_ContentType, stream.Length); + var media = new MediaDescriptor(_cmsKitTestData.Media_1_Id, _cmsKitTestData.Media_1_EntityType, _cmsKitTestData.Media_1_Name, _cmsKitTestData.Media_1_ContentType, stream.Length); await _mediaDescriptorRepository.InsertAsync(media); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 3762b8b073..32e4cd9f84 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -1,6 +1,7 @@ using System; using JetBrains.Annotations; using Volo.Abp.DependencyInjection; +using Volo.CmsKit.Blogs; namespace Volo.CmsKit { @@ -101,6 +102,8 @@ namespace Volo.CmsKit public Guid Media_1_Id { get; } = Guid.NewGuid(); + public string Media_1_EntityType = nameof(Blog); + public string Media_1_Content = "Hi, this is text file"; public string Media_1_Name = "hello.txt"; From c7f12500f4e73f70b32c76b2260ff6d77ceb7285 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Tue, 2 Mar 2021 10:38:08 +0800 Subject: [PATCH 029/101] Remote async keyword --- .../Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs | 4 +++- .../Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs | 4 +++- .../Navigation/AbpIdentityWebMainMenuContributor.cs | 6 ++++-- .../Navigation/AbpTenantManagementWebMainMenuContributor.cs | 6 ++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs index e2011acf43..43e4bfca5b 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/BloggingAdminMenuContributor.cs @@ -14,7 +14,7 @@ namespace Volo.Blogging.Admin } } - private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + private Task ConfigureMainMenuAsync(MenuConfigurationContext context) { var l = context.GetLocalizer(); @@ -23,6 +23,8 @@ namespace Volo.Blogging.Admin managementRootMenuItem.AddItem(new ApplicationMenuItem("BlogManagement.Blogs", l["Menu:Blogs"], "~/Blogging/Admin/Blogs", requiredPermissionName: BloggingPermissions.Blogs.Management)); context.Menu.GetAdministration().AddItem(managementRootMenuItem); + + return Task.CompletedTask; } } } diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs index 8b53069132..644dd037c4 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Navigation/DocsMenuContributor.cs @@ -17,7 +17,7 @@ namespace Volo.Docs.Admin.Navigation } } - private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + private Task ConfigureMainMenuAsync(MenuConfigurationContext context) { var administrationMenu = context.Menu.GetAdministration(); @@ -29,6 +29,8 @@ namespace Volo.Docs.Admin.Navigation rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Projects, l["Menu:ProjectManagement"], "~/Docs/Admin/Projects", requiredPermissionName: DocsAdminPermissions.Projects.Default)); rootMenuItem.AddItem(new ApplicationMenuItem(DocsMenuNames.Documents, l["Menu:DocumentManagement"], "~/Docs/Admin/Documents", requiredPermissionName: DocsAdminPermissions.Documents.Default)); + + return Task.CompletedTask; } } } diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs index e5d1f31f13..2f48318511 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Navigation/AbpIdentityWebMainMenuContributor.cs @@ -9,11 +9,11 @@ namespace Volo.Abp.Identity.Web.Navigation { public class AbpIdentityWebMainMenuContributor : IMenuContributor { - public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context) + public virtual Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name != StandardMenus.Main) { - return; + return Task.CompletedTask; } var l = context.GetLocalizer(); @@ -23,6 +23,8 @@ namespace Volo.Abp.Identity.Web.Navigation identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "~/Identity/Users", requiredPermissionName: IdentityPermissions.Users.Default)); context.Menu.GetAdministration().AddItem(identityMenuItem); + + return Task.CompletedTask; } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs index 45f9b75487..c3ebaa39b5 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs @@ -9,11 +9,11 @@ namespace Volo.Abp.TenantManagement.Web.Navigation { public class AbpTenantManagementWebMainMenuContributor : IMenuContributor { - public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context) + public virtual Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name != StandardMenus.Main) { - return; + return Task.CompletedTask; } var administrationMenu = context.Menu.GetAdministration(); @@ -24,6 +24,8 @@ namespace Volo.Abp.TenantManagement.Web.Navigation administrationMenu.AddItem(tenantManagementMenuItem); tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "~/TenantManagement/Tenants", requiredPermissionName: TenantManagementPermissions.Tenants.Default)); + + return Task.CompletedTask; } } } From f1ed14797a0e68dc4f65a61ba10e0b1c7a70cb7e Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 09:43:00 +0300 Subject: [PATCH 030/101] added new migration --- ...4229_Added_EntityType_to_Media.Designer.cs | 2012 +++++++++++++++++ ...0210302064229_Added_EntityType_to_Media.cs | 25 + .../UnifiedDbContextModelSnapshot.cs | 5 + 3 files changed, 2042 insertions(+) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.Designer.cs create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.Designer.cs new file mode 100644 index 0000000000..d291705365 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.Designer.cs @@ -0,0 +1,2012 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20210302064229_Added_EntityType_to_Media")] + partial class Added_EntityType_to_Media + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.3") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)") + .HasColumnName("Exceptions"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpFeatureValues"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogs"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogFeature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeatureName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogFeatures"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ShortDescription") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("Slug", "BlogId"); + + b.ToTable("CmsBlogPosts"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.MediaDescriptors.MediaDescriptor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Size") + .HasMaxLength(2147483647) + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsMediaDescriptors"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Slug"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.HasOne("Volo.CmsKit.Users.CmsUser", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.cs new file mode 100644 index 0000000000..10a6abd994 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302064229_Added_EntityType_to_Media.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class Added_EntityType_to_Media : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "EntityType", + table: "CmsMediaDescriptors", + type: "nvarchar(64)", + maxLength: 64, + nullable: false, + defaultValue: ""); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "EntityType", + table: "CmsMediaDescriptors"); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 63c57a4390..cd61c93ff2 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1475,6 +1475,11 @@ namespace Volo.CmsKit.Migrations .HasColumnType("datetime2") .HasColumnName("DeletionTime"); + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); From 1ac196427c4cbf8a5d36bba0861ab1ab053ffa38 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Tue, 2 Mar 2021 14:46:30 +0800 Subject: [PATCH 031/101] Use RequiredPermissionName for all ApplicationMenuItem of Blazor --- .../AbpIdentityWebMainMenuContributor.cs | 38 +++++++++---------- .../TenantManagementBlazorMenuContributor.cs | 18 +++++---- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs index 5e5714a851..609da7e6a7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityWebMainMenuContributor.cs @@ -6,35 +6,35 @@ namespace Volo.Abp.Identity.Blazor { public class AbpIdentityWebMainMenuContributor : IMenuContributor { - public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context) + public virtual Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name != StandardMenus.Main) { - return; + return Task.CompletedTask; } - var hasRolePermission = await context.IsGrantedAsync(IdentityPermissions.Roles.Default); - var hasUserPermission = await context.IsGrantedAsync(IdentityPermissions.Users.Default); + var administrationMenu = context.Menu.GetAdministration(); - if (hasRolePermission || hasUserPermission) - { - var administrationMenu = context.Menu.GetAdministration(); + var l = context.GetLocalizer(); - var l = context.GetLocalizer(); + var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], + icon: "far fa-id-card"); + administrationMenu.AddItem(identityMenuItem); - var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "far fa-id-card"); - administrationMenu.AddItem(identityMenuItem); + identityMenuItem.AddItem(new ApplicationMenuItem( + IdentityMenuNames.Roles, + l["Roles"], + url: "identity/roles", + requiredPermissionName: IdentityPermissions.Roles.Default)); - if (hasRolePermission) - { - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Roles, l["Roles"], url: "identity/roles")); - } - if (hasUserPermission) - { - identityMenuItem.AddItem(new ApplicationMenuItem(IdentityMenuNames.Users, l["Users"], url: "identity/users")); - } - } + identityMenuItem.AddItem(new ApplicationMenuItem( + IdentityMenuNames.Users, + l["Users"], + url: "identity/users", + requiredPermissionName: IdentityPermissions.Users.Default)); + + return Task.CompletedTask; } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs index 03bfd6b2d2..32cac00b2c 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Navigation/TenantManagementBlazorMenuContributor.cs @@ -6,24 +6,28 @@ namespace Volo.Abp.TenantManagement.Blazor.Navigation { public class TenantManagementBlazorMenuContributor : IMenuContributor { - public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context) + public virtual Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name != StandardMenus.Main) { - return; + return Task.CompletedTask; } var administrationMenu = context.Menu.GetAdministration(); var l = context.GetLocalizer(); - var tenantManagementMenuItem = new ApplicationMenuItem(TenantManagementMenuNames.GroupName, l["Menu:TenantManagement"], icon: "fa fa-users"); + var tenantManagementMenuItem = new ApplicationMenuItem(TenantManagementMenuNames.GroupName, + l["Menu:TenantManagement"], icon: "fa fa-users"); administrationMenu.AddItem(tenantManagementMenuItem); - if (await context.IsGrantedAsync(TenantManagementPermissions.Tenants.Default)) - { - tenantManagementMenuItem.AddItem(new ApplicationMenuItem(TenantManagementMenuNames.Tenants, l["Tenants"], url: "tenant-management/tenants")); - } + tenantManagementMenuItem.AddItem(new ApplicationMenuItem( + TenantManagementMenuNames.Tenants, + l["Tenants"], + url: "tenant-management/tenants", + requiredPermissionName: TenantManagementPermissions.Tenants.Default)); + + return Task.CompletedTask; } } } From f2d3f62a17ddbd72233bf20547a13d76020be2a4 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 11:06:57 +0300 Subject: [PATCH 032/101] CmsKit - Add definitions to MediaDescriptor --- .../Admin/CmsKitAdminApplicationModule.cs | 26 +++++++++++ .../MediaDescriptorAdminAppService.cs | 38 ++++++++++++---- .../CmsKit/CmsKitCommonApplicationModule.cs | 5 +++ .../Volo/CmsKit/CmsKitErrorCodes.cs | 1 + .../CmsKit/Localization/Resources/en.json | 1 + .../CmsKit/Localization/Resources/tr.json | 1 + .../Volo/CmsKit/Pages/PageConsts.cs | 2 + .../MediaDescriptors/CmsKitMediaOptions.cs | 15 +++++++ .../DefaultMediaDescriptorDefinitionStore.cs | 43 +++++++++++++++++++ .../EntityCantHaveMediaException.cs | 21 +++++++++ .../IMediaDescriptorDefinitionStore.cs | 12 ++++++ .../MediaDescriptors/MediaDescriptor.cs | 4 +- .../MediaDescriptorDefinition.cs | 18 ++++++++ .../MediaDescriptorManager.cs | 36 ++++++++++++++++ .../Volo/CmsKit/PolicySpecifiedDefinition.cs | 14 +++++- .../CmsKit/Tags/TagEntityTypeDefiniton.cs | 4 +- 16 files changed, 226 insertions(+), 15 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/CmsKitMediaOptions.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/IMediaDescriptorDefinitionStore.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index 2ad96af963..6da0e9233a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -7,6 +7,8 @@ using Volo.Abp.Modularity; using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Localization; +using Volo.CmsKit.MediaDescriptors; +using Volo.CmsKit.Pages; using Volo.CmsKit.Permissions; using Volo.CmsKit.Tags; @@ -49,6 +51,30 @@ namespace Volo.CmsKit.Admin CmsKitAdminPermissions.BlogPosts.Update)); } }); + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + Configure(options => + { + if (GlobalFeatureManager.Instance.IsEnabled()) + { + options.EntityTypes.AddIfNotContains( + new MediaDescriptorDefinition( + BlogPostConsts.EntityType, + createPolicy: CmsKitAdminPermissions.BlogPosts.Update, + deletePolicy: CmsKitAdminPermissions.BlogPosts.Delete)); + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + options.EntityTypes.AddIfNotContains( + new MediaDescriptorDefinition( + PageConsts.EntityType, + createPolicy: CmsKitAdminPermissions.Pages.Update, + deletePolicy: CmsKitAdminPermissions.Pages.Delete)); + } + }); + } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index ee2b5af152..dfa752aeb5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -13,31 +13,51 @@ namespace Volo.CmsKit.Admin.MediaDescriptors [Authorize(CmsKitAdminPermissions.MediaDescriptors.Default)] public class MediaDescriptorAdminAppService : CmsKitAdminAppServiceBase, IMediaDescriptorAdminAppService { - protected readonly IBlobContainer MediaContainer; - protected readonly IMediaDescriptorRepository MediaDescriptorRepository; - - public MediaDescriptorAdminAppService(IBlobContainer mediaContainer, IMediaDescriptorRepository mediaDescriptorRepository) + protected IBlobContainer MediaContainer { get; } + protected IMediaDescriptorRepository MediaDescriptorRepository { get; } + protected MediaDescriptorManager MediaDescriptorManager { get; } + protected IMediaDescriptorDefinitionStore MediaDescriptorDefinitionStore { get; } + + public MediaDescriptorAdminAppService( + IBlobContainer mediaContainer, + IMediaDescriptorRepository mediaDescriptorRepository, + MediaDescriptorManager mediaDescriptorManager, + IMediaDescriptorDefinitionStore mediaDescriptorDefinitionStore) { MediaContainer = mediaContainer; MediaDescriptorRepository = mediaDescriptorRepository; + MediaDescriptorManager = mediaDescriptorManager; + MediaDescriptorDefinitionStore = mediaDescriptorDefinitionStore; } [Authorize(CmsKitAdminPermissions.MediaDescriptors.Create)] public virtual async Task CreateAsync(CreateMediaInputStream inputStream) { + var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(inputStream.EntityType); + + await CheckPolicyAsync(definition.CreatePolicy); + var newId = GuidGenerator.Create(); - var stream = inputStream.GetStream(); - var newEntity = new MediaDescriptor(newId, inputStream.EntityType, inputStream.Name, inputStream.ContentType, stream.Length, CurrentTenant.Id); + using (var stream = inputStream.GetStream()) + { + var newEntity = await MediaDescriptorManager.Create(inputStream.ContentType, inputStream.Name, inputStream.ContentType, inputStream.ContentLength ?? 0); - await MediaContainer.SaveAsync(newId.ToString(), stream); - await MediaDescriptorRepository.InsertAsync(newEntity); + await MediaContainer.SaveAsync(newId.ToString(), stream); + await MediaDescriptorRepository.InsertAsync(newEntity); - return ObjectMapper.Map(newEntity); + return ObjectMapper.Map(newEntity); + } } [Authorize(CmsKitAdminPermissions.MediaDescriptors.Delete)] public virtual async Task DeleteAsync(Guid id) { + var mediaDescriptor = await MediaDescriptorRepository.GetAsync(id); + + var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(mediaDescriptor.EntityType); + + await CheckPolicyAsync(definition.DeletePolicy); + await MediaContainer.DeleteAsync(id.ToString()); await MediaDescriptorRepository.DeleteAsync(id); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationModule.cs index 8fa08fa950..1778e7e234 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationModule.cs @@ -1,6 +1,11 @@ using Volo.Abp.Application; using Volo.Abp.AutoMapper; +using Volo.Abp.GlobalFeatures; using Volo.Abp.Modularity; +using Volo.CmsKit.Blogs; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.MediaDescriptors; +using Volo.CmsKit.Permissions; namespace Volo.CmsKit { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs index 64956b8683..b358672a1a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs @@ -28,6 +28,7 @@ public static class MediaDescriptors { public const string InvalidName = "CmsKit:Media:0001"; + public const string EntityTypeDoesntExist = "CmsKit:Media:0002"; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 8102350c6a..1107d5e5db 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -20,6 +20,7 @@ "CmsKit:Media:0001": "'{Name}' is not a valid media name.", "CmsKit:Page:0001": "The given url ({0}) already exists.", "CmsKit:Tag:0002": "The entity is not taggable!", + "CmsKit:Media:0002": "The entity can't have media.", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", "CommentDeletionConfirmationMessage": "This comment and all replies will be deleted!", "Comments": "Comments", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index 5701c631f2..f41639325a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -16,6 +16,7 @@ "CmsKit:0002": "İçerik zaten mevcut!", "CmsKit:0003": "{0} ögesi etiketlenebilir değil.", "CmsKit:BlogPost:0001": "Aynı url etiketi zaten mevcut.", + "CmsKit:Media:0002": "Bu öge için medya eklenemez.", "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır.", "CmsKit:Tag:0002": "Bu öge etiketlenebilir değil.", "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs index 47d82b5d07..fc4c5c75ad 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs @@ -2,6 +2,8 @@ { public class PageConsts { + public const string EntityType = "Page"; + public static int MaxTitleLength { get; set; } = 256; public static int MaxSlugLength { get; set; } = 256; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/CmsKitMediaOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/CmsKitMediaOptions.cs new file mode 100644 index 0000000000..89f5d0dca3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/CmsKitMediaOptions.cs @@ -0,0 +1,15 @@ +using JetBrains.Annotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Volo.CmsKit.MediaDescriptors +{ + public class CmsKitMediaOptions + { + [NotNull] + public List EntityTypes { get; } = new(); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs new file mode 100644 index 0000000000..4cf5889dcc --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs @@ -0,0 +1,43 @@ +using JetBrains.Annotations; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.DependencyInjection; + +namespace Volo.CmsKit.MediaDescriptors +{ + public class DefaultMediaDescriptorDefinitionStore : IMediaDescriptorDefinitionStore, ITransientDependency + { + protected CmsKitMediaOptions Options { get; } + + public DefaultMediaDescriptorDefinitionStore(IOptions options) + { + Options = options.Value; + } + + /// + /// Gets single by entityType. + /// + /// EntityType to get definition. + /// Thrown when EntityType is not configured as taggable. + /// More than one element satisfies the condition in predicate. + public Task GetDefinitionAsync([NotNull] string entityType) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + + var result = Options.EntityTypes.SingleOrDefault(x => x.EntityType == entityType) ?? + throw new EntityCantHaveMediaException(entityType); + + return Task.FromResult(result); + } + + public Task IsDefinedAsync([NotNull] string entityType) + { + return Task.Run(() => Options.EntityTypes.Any(a => a.EntityType == entityType)); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs new file mode 100644 index 0000000000..29d60126a1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs @@ -0,0 +1,21 @@ +using System.Runtime.Serialization; +using Volo.Abp; + +namespace Volo.CmsKit.MediaDescriptors +{ + public class EntityCantHaveMediaException : BusinessException + { + public EntityCantHaveMediaException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) + { + } + + public EntityCantHaveMediaException(string entityType) + { + EntityType = entityType; + Code = CmsKitErrorCodes.MediaDescriptors.EntityTypeDoesntExist; + WithData(nameof(entityType), EntityType); + } + + public string EntityType { get; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/IMediaDescriptorDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/IMediaDescriptorDefinitionStore.cs new file mode 100644 index 0000000000..9cd5c5c40d --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/IMediaDescriptorDefinitionStore.cs @@ -0,0 +1,12 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; + +namespace Volo.CmsKit.MediaDescriptors +{ + public interface IMediaDescriptorDefinitionStore + { + Task IsDefinedAsync([NotNull] string entityType); + + Task GetDefinitionAsync([NotNull] string entityType); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs index c97eb26b9a..ee0df74b59 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptor.cs @@ -9,7 +9,7 @@ namespace Volo.CmsKit.MediaDescriptors { public Guid? TenantId { get; protected set; } - public string EntityType { get; set; } + public string EntityType { get; protected set; } public string Name { get; protected set; } @@ -22,7 +22,7 @@ namespace Volo.CmsKit.MediaDescriptors } - public MediaDescriptor(Guid id, string entityType, string name, string mimeType, long size, Guid? tenantId = null) : base(id) + internal MediaDescriptor(Guid id, string entityType, string name, string mimeType, long size, Guid? tenantId = null) : base(id) { TenantId = tenantId; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs new file mode 100644 index 0000000000..b2ccb01460 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs @@ -0,0 +1,18 @@ +using JetBrains.Annotations; + +namespace Volo.CmsKit.MediaDescriptors +{ + public class MediaDescriptorDefinition : PolicySpecifiedDefinition + { + public MediaDescriptorDefinition( + [NotNull] string entityType, + [CanBeNull] string createPolicy = null, + [CanBeNull] string updatePolicy = null, + [CanBeNull] string deletePolicy = null) : base(entityType, + createPolicy, + updatePolicy, + deletePolicy) + { + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs new file mode 100644 index 0000000000..f0773ad7ff --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; +using Volo.CmsKit.MediaDescriptors; + +namespace Volo.CmsKit.MediaDescriptors +{ + public class MediaDescriptorManager : DomainService + { + protected IMediaDescriptorDefinitionStore MediaDescriptorDefinitionStore { get; } + + public MediaDescriptorManager(IMediaDescriptorDefinitionStore mediaDescriptorDefinitionStore) + { + MediaDescriptorDefinitionStore = mediaDescriptorDefinitionStore; + } + + public virtual async Task Create(string entityType, string name, string mimeType, long size) + { + if(!await MediaDescriptorDefinitionStore.IsDefinedAsync(entityType)) + { + throw new EntityCantHaveMediaException(entityType); + } + + return new MediaDescriptor( + GuidGenerator.Create(), + entityType, + name, + mimeType, + size, + CurrentTenant.Id); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs index 54527621ec..2a5f69b69e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs @@ -1,23 +1,30 @@ using JetBrains.Annotations; +using System; +using Volo.Abp; namespace Volo.CmsKit { - public abstract class PolicySpecifiedDefinition + public abstract class PolicySpecifiedDefinition : IEquatable { protected PolicySpecifiedDefinition() { } public PolicySpecifiedDefinition( + [NotNull] string entityType, [CanBeNull] string createPolicy = null, [CanBeNull] string updatePolicy = null, [CanBeNull] string deletePolicy = null) { + EntityType = Check.NotNullOrEmpty(entityType, nameof(entityType)); CreatePolicy = createPolicy; DeletePolicy = deletePolicy; UpdatePolicy = updatePolicy; } + [NotNull] + public string EntityType { get; set; } + [CanBeNull] public virtual string CreatePolicy { get; set; } @@ -26,5 +33,10 @@ namespace Volo.CmsKit [CanBeNull] public virtual string DeletePolicy { get; set; } + + public bool Equals(PolicySpecifiedDefinition other) + { + return other?.EntityType == EntityType; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs index e714d91c0b..a6fb4cde7a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs @@ -7,8 +7,6 @@ namespace Volo.CmsKit.Tags { public class TagEntityTypeDefiniton : PolicySpecifiedDefinition, IEquatable { - public string EntityType { get; } - [CanBeNull] public virtual ILocalizableString DisplayName { get; } @@ -21,7 +19,7 @@ namespace Volo.CmsKit.Tags [CanBeNull] ILocalizableString displayName = null, [CanBeNull] string createPolicy = null, [CanBeNull] string updatePolicy = null, - [CanBeNull] string deletePolicy = null) : base(createPolicy, updatePolicy, deletePolicy) + [CanBeNull] string deletePolicy = null) : base(entityType, createPolicy, updatePolicy, deletePolicy) { EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); DisplayName = displayName; From 58298bffe66da62659b535097270b7f7dd9c804e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 2 Mar 2021 11:09:36 +0300 Subject: [PATCH 033/101] Cli: fix solution renaming for microservice service template --- .../ProjectBuilding/Building/Steps/SolutionRenameStep.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs index 27199f6ce4..1ea30fe783 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs @@ -18,6 +18,14 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps context.BuildArgs.SolutionName.CompanyName, context.BuildArgs.SolutionName.ProjectName ).Run(); + + new SolutionRenamer( + context.Files, + null, + "MyProjectName", + null, + SolutionName.Parse(context.BuildArgs.SolutionName.CompanyName).ProjectName + ).Run(); } else { From 6c356a828829f2ece413516bf4df1f86046d8799 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 11:48:42 +0300 Subject: [PATCH 034/101] Added content property to BlogPost and ui --- ...5529_Added_Content_To_BlogPost.Designer.cs | 2016 +++++++++++++++++ ...0210302075529_Added_Content_To_BlogPost.cs | 24 + .../UnifiedDbContextModelSnapshot.cs | 4 + .../Volo/CmsKit/Admin/Blogs/BlogPostDto.cs | 5 +- .../CmsKit/Admin/Blogs/CreateBlogPostDto.cs | 3 + .../CmsKit/Admin/Blogs/UpdateBlogPostDto.cs | 4 +- .../Admin/Blogs/BlogPostAdminAppService.cs | 5 +- .../Pages/CmsKit/BlogPosts/Create.cshtml | 28 +- .../Pages/CmsKit/BlogPosts/Create.cshtml.cs | 4 + .../Pages/CmsKit/BlogPosts/Update.cshtml | 29 +- .../Pages/CmsKit/BlogPosts/Update.cshtml.cs | 4 + .../Pages/CmsKit/BlogPosts/create.js | 109 +- .../Pages/CmsKit/BlogPosts/update.js | 132 +- .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 2 + .../Volo/CmsKit/Blogs/BlogPost.cs | 16 +- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 6 +- .../CmsKitDbContextModelCreatingExtensions.cs | 8 +- .../CmsKit/Public/Blogs/BlogPostPublicDto.cs | 2 + .../Components/Blogs/BlogPost/Default.cshtml | 6 +- .../Blogs/BlogPostAdminAppService_Tests.cs | 14 +- .../CmsKitDataSeedContributor.cs | 6 +- 21 files changed, 2318 insertions(+), 109 deletions(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.Designer.cs create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.Designer.cs new file mode 100644 index 0000000000..8f6bd9239d --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.Designer.cs @@ -0,0 +1,2016 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20210302075529_Added_Content_To_BlogPost")] + partial class Added_Content_To_BlogPost + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.3") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)") + .HasColumnName("Exceptions"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpFeatureValues"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogs"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogFeature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeatureName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogFeatures"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ShortDescription") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("Slug", "BlogId"); + + b.ToTable("CmsBlogPosts"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.MediaDescriptors.MediaDescriptor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Size") + .HasMaxLength(2147483647) + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsMediaDescriptors"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Slug"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.HasOne("Volo.CmsKit.Users.CmsUser", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.cs new file mode 100644 index 0000000000..836507c222 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302075529_Added_Content_To_BlogPost.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class Added_Content_To_BlogPost : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Content", + table: "CmsBlogPosts", + type: "nvarchar(max)", + maxLength: 2147483647, + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Content", + table: "CmsBlogPosts"); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index cd61c93ff2..e3e9f4cc68 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1269,6 +1269,10 @@ namespace Volo.CmsKit.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + b.Property("CreationTime") .HasColumnType("datetime2") .HasColumnName("CreationTime"); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs index d12a2f2982..5222b50fe8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs @@ -11,6 +11,9 @@ namespace Volo.CmsKit.Admin.Blogs public string Title { get; set; } public string Slug { get; set; } - public string ShortDescription { get; protected set; } + + public string ShortDescription { get; set; } + + public string Content { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs index 7780a21669..3e339c738c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs @@ -21,5 +21,8 @@ namespace Volo.CmsKit.Admin.Blogs [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] public string ShortDescription { get; set; } + + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxContentLength))] + public string Content { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs index eeb4548c8e..7aaf775427 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs @@ -18,6 +18,8 @@ namespace Volo.CmsKit.Admin.Blogs [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] public string ShortDescription { get; set; } - + + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxContentLength))] + public string Content { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 4fbbf88675..a25aa07a09 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -54,7 +54,7 @@ namespace Volo.CmsKit.Admin.Blogs input.Title, input.Slug, input.ShortDescription, - CurrentTenant.Id); + input.Content); await BlogPostRepository.InsertAsync(blogPost); @@ -68,7 +68,8 @@ namespace Volo.CmsKit.Admin.Blogs blogPost.SetTitle(input.Title); blogPost.SetShortDescription(input.ShortDescription); - + blogPost.SetContent(input.Content); + if (blogPost.Slug != input.Slug) { await BlogPostManager.SetSlugUrlAsync(blogPost, input.Slug); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml index ae5c3ce9bd..8440bc0c40 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml @@ -1,5 +1,7 @@ @page +@using System.Globalization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar @using Volo.CmsKit.Admin.Web.Pages @@ -22,12 +24,19 @@ @section scripts { - - - + + + + } +@section styles { + + + +} + @section content_toolbar { @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(CreateModel).FullName }) } @@ -50,15 +59,14 @@ - - @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new - { - entityType = BlogPostConsts.EntityType, - displaySubmitButton = false - }) - + +
+
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs index 2d01e55668..2d3c7d36ab 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs @@ -58,6 +58,10 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] public string ShortDescription { get; set; } + + [HiddenInput] + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxContentLength))] + public string Content { get; set; } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml index b4692365ef..b9a1dbb638 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml @@ -1,5 +1,7 @@ @page "{Id}" +@using System.Globalization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.CmsKit.Blogs @using Volo.CmsKit.Admin.Web.Pages @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar @@ -22,12 +24,19 @@ @section scripts { - - - + + + + } +@section styles { + + + +} + @section content_toolbar { @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(UpdateModel).FullName }) } @@ -49,14 +58,14 @@ - @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new - { - entityType = BlogPostConsts.EntityType, - entityId = Model.Id.ToString(), - displaySubmitButton = false - }) - + +
+
+ @if (Model.TagsFeature?.IsEnabled == true) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs index 29c839a947..5fef40f8a1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs @@ -72,6 +72,10 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] [DisplayOrder(10001)] public string ShortDescription { get; set; } + + [HiddenInput] + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxContentLength))] + public string Content { get; set; } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js index b2fd0613e6..e1e132e2a0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js @@ -41,7 +41,12 @@ $formCreate.ajaxSubmit({ success: function (result) { - submitEntityContent(result.id); + if (isTagsEnabled) { + submitEntityTags(result.id); + } + else { + submitCoverImage(result.id); + } }, error: function (result) { abp.notify.error(result.responseJSON.error.message); @@ -55,29 +60,16 @@ e.preventDefault(); $formCreate.submit(); }); - - function submitEntityContent(blogPostId) { - volo.cmsKit.admin.contents.contentAdmin - .create( - { - entityType: 'BlogPost', - entityId: blogPostId, - value: $pageContentInput.val() - }) - .then(function (result) { - if (isTagsEnabled) { - submitEntityTags(blogPostId) - } - else { - submitCoverImage(blogPostId); - } - }); - } - + function submitEntityTags(blogPostId) { - var tags = $tagsInput.val().split(","); - + var tags = $tagsInput.val().split(',').map(x => x.trim()).filter(x => x); + + if(tags.length === 0){ + submitCoverImage(blogPostId); + return; + } + volo.cmsKit.admin.tags.entityTagAdmin .setEntityTags({ entityType: 'BlogPost', @@ -209,4 +201,77 @@ } }); }); + + // ----------------------------------- + var fileUploadUri = "/api/cms-kit-admin/media/blogpost"; + var fileUriPrefix = "/api/cms-kit/media/"; + + var editorDataKey = "tuiEditor"; + + initAllEditors(); + + function initAllEditors() { + $('.content-editor').each(function (i, item) { + initEditor(item); + }); + } + + function initEditor(element) { + var $editorContainer = $(element); + var inputName = $editorContainer.data('input-id'); + var $editorInput = $('#' + inputName); + var initialValue = $editorInput.val(); + + var editor = $editorContainer.tuiEditor({ + usageStatistics: false, + useCommandShortcut: true, + initialValue: initialValue, + previewStyle: 'tab', + height: "25em", + minHeight: "25em", + initialEditType: initialValue ? 'wysiwyg' : 'markdown', + language: $editorContainer.data("language"), + hooks: { + addImageBlobHook: uploadFile, + }, + events: { + change: function (_val) { + $editorInput.val(editor.getHtml()); + $editorInput.trigger("change"); + } + } + }).data(editorDataKey); + } + + function uploadFile(blob, callback, source) { + var UPPY_OPTIONS = { + endpoint: fileUploadUri, + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + UPPY.addFile({ + id: "content-file", + name: blob.name, + type: blob.type, + data: blob, + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error("File upload failed"); + } else { + var mediaDto = result.successful[0].response.body; + var fileUrl = (fileUriPrefix + mediaDto.id); + + callback(fileUrl, mediaDto.name); + } + }); + } }); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js index 9a2fb3c69a..14bfdc6f55 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js @@ -8,15 +8,15 @@ var $titleClone = $('#title-clone'); var $slug = $('#ViewModel_Slug'); var $buttonSubmit = $('#button-blog-post-update'); - var $contentValueInput = $('#ViewModel_Value'); var $blogPostIdInput = $('#Id'); - var $contentIdInput = $('#ViewModel_Id'); var $tagsInput = $('.tag-editor-form input[name=tags]'); var $fileInput = $('#BlogPostCoverImage'); var UPPY_UPLOAD_ENDPOINT = "/api/cms-kit-admin/blogs/blog-posts/{0}/cover-image"; var UPPY_FILE_ID = "uppy-upload-file"; + var isTagsEnabled = true; + $formUpdate.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; function initSelectBlog() { @@ -40,7 +40,12 @@ $formUpdate.ajaxSubmit({ success: function (result) { - submitEntityContent(); + if (isTagsEnabled) { + submitEntityTags($blogPostIdInput.val()); + } + else { + submitCoverImage($blogPostIdInput.val()); + } }, error: function (result) { abp.ui.clearBusy(); abp.notify.error(result.responseJSON.error.message); @@ -53,49 +58,16 @@ e.preventDefault(); $formUpdate.submit(); }); + + function submitEntityTags(blogPostId) { - function submitEntityContent() { - - var contentId = $contentIdInput.val(); - var blogPostId = $blogPostIdInput.val(); - var contentValue = $contentValueInput.val(); - - if (contentId) { - volo.cmsKit.admin.contents.contentAdmin - .update(contentId, - { - value: contentValue - }) - .then(function (result) { - entityContentCallback(blogPostId); - }); - } - else { - volo.cmsKit.admin.contents.contentAdmin - .create({ - entityType: 'BlogPost', - entityId: blogPostId, - value: contentValue - }) - .then(function (result) { - entityContentCallback(blogPostId); - }); - } - } + var tags = $tagsInput.val().split(',').map(x => x.trim()).filter(x => x); - function entityContentCallback(blogPostId) { - if ($tagsInput.val()) { - submitEntityTags(blogPostId); - } - else { + if(tags.length === 0){ submitCoverImage(blogPostId); + return; } - } - - function submitEntityTags(blogPostId) { - - var tags = $tagsInput.val().split(","); - + volo.cmsKit.admin.tags.entityTagAdmin .setEntityTags({ entityType: 'BlogPost', @@ -154,7 +126,7 @@ function finishSaving(result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = "../BlogPosts/"; + location.href = "/CmsKit/BlogPosts/"; } $titleClone.on('change paste keyup', function () { @@ -177,4 +149,78 @@ }); } } + + + // ----------------------------------- + var fileUploadUri = "/api/cms-kit-admin/media/blogpost"; + var fileUriPrefix = "/api/cms-kit/media/"; + + var editorDataKey = "tuiEditor"; + + initAllEditors(); + + function initAllEditors() { + $('.content-editor').each(function (i, item) { + initEditor(item); + }); + } + + function initEditor(element) { + var $editorContainer = $(element); + var inputName = $editorContainer.data('input-id'); + var $editorInput = $('#' + inputName); + var initialValue = $editorInput.val(); + + var editor = $editorContainer.tuiEditor({ + usageStatistics: false, + useCommandShortcut: true, + initialValue: initialValue, + previewStyle: 'tab', + height: "25em", + minHeight: "25em", + initialEditType: initialValue ? 'wysiwyg' : 'markdown', + language: $editorContainer.data("language"), + hooks: { + addImageBlobHook: uploadFile, + }, + events: { + change: function (_val) { + $editorInput.val(editor.getHtml()); + $editorInput.trigger("change"); + } + } + }).data(editorDataKey); + } + + function uploadFile(blob, callback, source) { + var UPPY_OPTIONS = { + endpoint: fileUploadUri, + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + UPPY.addFile({ + id: "content-file", + name: blob.name, + type: blob.type, + data: blob, + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error("File upload failed"); + } else { + var mediaDto = result.successful[0].response.body; + var fileUrl = (fileUriPrefix + mediaDto.id); + + callback(fileUrl, mediaDto.name); + } + }); + } }); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index 7e1de6e7c0..91748dc1e3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -11,6 +11,8 @@ namespace Volo.CmsKit.Blogs public static int MinSlugLength { get; set; } = 2; public static int MaxShortDescriptionLength { get; set; } = 256; + + public static int MaxContentLength { get; set; } = int.MaxValue; public const string EntityType = "BlogPost"; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index dc10725359..251a9c2895 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -21,9 +21,10 @@ namespace Volo.CmsKit.Blogs [NotNull] public virtual string ShortDescription { get; protected set; } + public virtual string Content { get; protected set; } + public virtual Guid? TenantId { get; protected set; } - [NotNull] public Guid AuthorId { get; set; } public virtual CmsUser Author { get; set; } @@ -38,13 +39,17 @@ namespace Volo.CmsKit.Blogs Guid authorId, [NotNull] string title, [NotNull] string slug, - [CanBeNull] string shortDescription = null) : base(id) + [CanBeNull] string shortDescription = null, + [CanBeNull] string content = null, + [CanBeNull] Guid? tenantId = null) : base(id) { + TenantId = tenantId; BlogId = blogId; AuthorId = authorId; SetTitle(title); SetSlug(slug); - ShortDescription = shortDescription; + SetShortDescription(shortDescription); + SetContent(content); } public virtual void SetTitle(string title) @@ -63,5 +68,10 @@ namespace Volo.CmsKit.Blogs { ShortDescription = Check.Length(shortDescription, nameof(shortDescription), BlogPostConsts.MaxShortDescriptionLength); } + + public virtual void SetContent(string content) + { + Content = Check.Length(content, nameof(content), BlogPostConsts.MaxContentLength); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 4ee29608b4..3e15b91117 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -27,7 +27,7 @@ namespace Volo.CmsKit.Blogs [NotNull] string title, [NotNull] string slug, [CanBeNull] string shortDescription = null, - [CanBeNull] Guid? tenantId = null) + [CanBeNull] string content = null) { Check.NotNull(author, nameof(author)); Check.NotNull(blog, nameof(blog)); @@ -42,7 +42,9 @@ namespace Volo.CmsKit.Blogs author.Id, title, slug, - shortDescription + shortDescription, + content, + CurrentTenant.Id ); await CheckSlugExistenceAsync(blog.Id, blogPost.Slug); diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 476e2a3111..8208dd38ea 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -207,14 +207,12 @@ namespace Volo.CmsKit.EntityFrameworkCore b.ConfigureByConvention(); + b.Property(p => p.AuthorId).IsRequired(); b.Property(p => p.Title).IsRequired().HasMaxLength(BlogPostConsts.MaxTitleLength); - b.Property(p => p.Slug).IsRequired().HasMaxLength(BlogPostConsts.MaxSlugLength); - b.Property(p => p.ShortDescription).HasMaxLength(BlogPostConsts.MaxShortDescriptionLength); - - b.Property(p => p.AuthorId).IsRequired(); - + b.Property(p => p.Content).HasMaxLength(BlogPostConsts.MaxContentLength); + b.HasIndex(x => new { x.Slug, x.BlogId }); }); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs index ece2704513..a7358f176a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs @@ -15,6 +15,8 @@ namespace Volo.CmsKit.Public.Blogs public string ShortDescription { get; set; } + public string Content { get; set; } + public CmsUserDto Author { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml index 39737ba8df..76d1487861 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml @@ -14,11 +14,7 @@ - @await Component.InvokeAsync(typeof(ContentViewComponent), new - { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.Id.ToString() - }) + @Html.Raw(Model.Content) @Model.CreationTime diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs index 4fe6f2e23e..28e3daea8d 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs @@ -30,13 +30,15 @@ namespace Volo.CmsKit.Blogs var title = "My awesome new Post"; var slug = "my-awesome-new-post"; var shortDescription = "This blog is all about awesomeness 🤗!"; - + var content = "Another blog post shared on internet"; + var created = await blogPostAdminAppService.CreateAsync(new CreateBlogPostDto { BlogId = cmsKitTestData.Blog_Id, Title = title, Slug = slug, - ShortDescription = shortDescription + ShortDescription = shortDescription, + Content = content }); created.Id.ShouldNotBe(Guid.Empty); @@ -46,6 +48,7 @@ namespace Volo.CmsKit.Blogs blogPost.Title.ShouldBe(title); blogPost.Slug.ShouldBe(slug); blogPost.ShortDescription.ShouldBe(shortDescription); + blogPost.Content.ShouldBe(content); } [Fact] @@ -54,6 +57,7 @@ namespace Volo.CmsKit.Blogs var title = "Another My Awesome New Post"; var slug = "another-my-awesome-new-post"; var shortDescription = "This blog is all about awesomeness 🤗!"; + var content = "Another blog post shared on internet"; var dto = new CreateBlogPostDto { @@ -61,7 +65,8 @@ namespace Volo.CmsKit.Blogs BlogId = Guid.NewGuid(), Title = title, Slug = slug, - ShortDescription = shortDescription + ShortDescription = shortDescription, + Content = content }; var exception = await Should.ThrowAsync(async () => @@ -107,12 +112,14 @@ namespace Volo.CmsKit.Blogs var shortDescription = "Another short description"; var title = "[Solved] Another Blog Post"; var slug = "another-short-blog-post"; + var content = "Another blog post shared on internet"; await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, new UpdateBlogPostDto { ShortDescription = shortDescription, Title = title, Slug = slug, + Content = content }); var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_2_Id); @@ -120,6 +127,7 @@ namespace Volo.CmsKit.Blogs blogPost.Title.ShouldBe(title); blogPost.ShortDescription.ShouldBe(shortDescription); blogPost.Slug.ShouldBe(slug); + blogPost.Content.ShouldBe(content); } [Fact] diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 9bdd1cfb96..00969c46ab 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -367,7 +367,8 @@ namespace Volo.CmsKit blog, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_Slug, - "Short desc 1"))).Id; + "Short desc 1", + "Blog Post 1 Content"))).Id; _cmsKitTestData.BlogPost_2_Id = (await _blogPostRepository.InsertAsync( @@ -376,7 +377,8 @@ namespace Volo.CmsKit blog, _cmsKitTestData.BlogPost_2_Title, _cmsKitTestData.BlogPost_2_Slug, - "Short desc 2"))).Id; + "Short desc 2", + "Blog Post 2 Content"))).Id; } private async Task SeedBlogFeaturesAsync() From 39b449569aedb700e7dfc8f3cb9efcd9faf97c0a Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 12:19:11 +0300 Subject: [PATCH 035/101] CmsKit - Update tests for MediaDescriptor --- .../MediaDescriptorAdminAppService.cs | 2 +- .../Volo/CmsKit/AssemblyInfo.cs | 4 ++ .../DefaultMediaDescriptorDefinitionStore.cs | 6 ++- .../MediaDescriptorDefinition.cs | 8 +++- .../MediaDescriptorManager.cs | 9 +--- .../MediaDescriptorAdminAppService_Tests.cs | 3 +- .../MediaDescriptorManager_Test.cs | 44 +++++++++++++++++++ .../CmsKitDataSeedContributor.cs | 7 ++- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 12 ++--- 9 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/AssemblyInfo.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.Domain.Tests/MediaDescriptors/MediaDescriptorManager_Test.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index dfa752aeb5..5307591447 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -40,7 +40,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors var newId = GuidGenerator.Create(); using (var stream = inputStream.GetStream()) { - var newEntity = await MediaDescriptorManager.Create(inputStream.ContentType, inputStream.Name, inputStream.ContentType, inputStream.ContentLength ?? 0); + var newEntity = await MediaDescriptorManager.CreateAsync(inputStream.EntityType, inputStream.Name, inputStream.ContentType, inputStream.ContentLength ?? 0); await MediaContainer.SaveAsync(newId.ToString(), stream); await MediaDescriptorRepository.InsertAsync(newEntity); diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/AssemblyInfo.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/AssemblyInfo.cs new file mode 100644 index 0000000000..f8d4fc09f3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/AssemblyInfo.cs @@ -0,0 +1,4 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Volo.CmsKit.Domain.Tests", AllInternalsVisible = true)] +[assembly: InternalsVisibleTo("Volo.CmsKit.TestBase", AllInternalsVisible = true)] \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs index 4cf5889dcc..4bdd4d6e98 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs @@ -37,7 +37,11 @@ namespace Volo.CmsKit.MediaDescriptors public Task IsDefinedAsync([NotNull] string entityType) { - return Task.Run(() => Options.EntityTypes.Any(a => a.EntityType == entityType)); + Check.NotNullOrEmpty(entityType, nameof(entityType)); + + var isDefined = Options.EntityTypes.Any(a => a.EntityType == entityType); + + return Task.FromResult(isDefined); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs index b2ccb01460..073ed694f6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs @@ -1,8 +1,9 @@ using JetBrains.Annotations; +using System; namespace Volo.CmsKit.MediaDescriptors { - public class MediaDescriptorDefinition : PolicySpecifiedDefinition + public class MediaDescriptorDefinition : PolicySpecifiedDefinition, IEquatable { public MediaDescriptorDefinition( [NotNull] string entityType, @@ -14,5 +15,10 @@ namespace Volo.CmsKit.MediaDescriptors deletePolicy) { } + + public bool Equals(MediaDescriptorDefinition other) + { + return base.Equals(other); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs index f0773ad7ff..730e4e3ccf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorManager.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; using Volo.Abp.Domain.Services; -using Volo.CmsKit.MediaDescriptors; namespace Volo.CmsKit.MediaDescriptors { @@ -17,7 +12,7 @@ namespace Volo.CmsKit.MediaDescriptors MediaDescriptorDefinitionStore = mediaDescriptorDefinitionStore; } - public virtual async Task Create(string entityType, string name, string mimeType, long size) + public virtual async Task CreateAsync(string entityType, string name, string mimeType, long size) { if(!await MediaDescriptorDefinitionStore.IsDefinedAsync(entityType)) { diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs index 20bfaf2c12..52169eddbe 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs @@ -34,7 +34,8 @@ namespace Volo.CmsKit.MediaDescriptors var inputStream = new CreateMediaInputStream(stream) { ContentType = mediaType, - Name = mediaName + Name = mediaName, + EntityType = _cmsKitTestData.Media_1_EntityType }; var media = await _mediaDescriptorAdminAppService.CreateAsync(inputStream); diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/MediaDescriptors/MediaDescriptorManager_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/MediaDescriptors/MediaDescriptorManager_Test.cs new file mode 100644 index 0000000000..6bf183564e --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/MediaDescriptors/MediaDescriptorManager_Test.cs @@ -0,0 +1,44 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Blogs; +using Xunit; + +namespace Volo.CmsKit.MediaDescriptors +{ + public class MediaDescriptorManager_Test : CmsKitDomainTestBase + { + private readonly MediaDescriptorManager manager; + private readonly CmsKitTestData testData; + + public MediaDescriptorManager_Test() + { + manager = GetRequiredService(); + testData = GetRequiredService(); + } + + [Fact] + public async Task CreateAsync_ShouldWorkProperly_WithDefinedEntityType() + { + var created = await manager.CreateAsync(testData.Media_1_EntityType, "MyAwesomeImage.png", "image/png", 128000); + + created.ShouldNotBeNull(); + created.Id.ShouldNotBe(Guid.Empty); + } + + [Fact] + public async Task CreateAsync_ShouldThrowException_WithUndefinedEntityType() + { + var undefinedEntityType = "My.Any.EntityType"; + + var exception = await Should.ThrowAsync(async () => + await manager.CreateAsync(undefinedEntityType, "import.json", "application/json", 256000)); + + exception.ShouldNotBeNull(); + exception.EntityType.ShouldBe(undefinedEntityType); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 9bdd1cfb96..e2c928be2a 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -48,6 +48,7 @@ namespace Volo.CmsKit private readonly IMediaDescriptorRepository _mediaDescriptorRepository; private readonly IBlobContainer _mediaBlobContainer; private readonly BlogManager _blogManager; + private readonly IOptions _mediaOptions; public CmsKitDataSeedContributor( IGuidGenerator guidGenerator, @@ -71,7 +72,8 @@ namespace Volo.CmsKit IOptions tagOptions, IMediaDescriptorRepository mediaDescriptorRepository, IBlobContainer mediaBlobContainer, - BlogManager blogManager) + BlogManager blogManager, + IOptions cmsMediaOptions) { _guidGenerator = guidGenerator; _cmsUserRepository = cmsUserRepository; @@ -95,6 +97,7 @@ namespace Volo.CmsKit _mediaDescriptorRepository = mediaDescriptorRepository; _mediaBlobContainer = mediaBlobContainer; _blogManager = blogManager; + _mediaOptions = cmsMediaOptions; } public async Task SeedAsync(DataSeedContext context) @@ -133,6 +136,8 @@ namespace Volo.CmsKit _tagOptions.Value.EntityTypes.AddIfNotContains(new TagEntityTypeDefiniton(_cmsKitTestData.Content_2_EntityType)); _tagOptions.Value.EntityTypes.AddIfNotContains(new TagEntityTypeDefiniton(_cmsKitTestData.TagDefinition_1_EntityType)); + _mediaOptions.Value.EntityTypes.AddIfNotContains(new MediaDescriptorDefinition(_cmsKitTestData.Media_1_EntityType)); + return Task.CompletedTask; } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 32e4cd9f84..396ae5a013 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -101,13 +101,13 @@ namespace Volo.CmsKit public bool BlogFeature_2_Enabled => false; public Guid Media_1_Id { get; } = Guid.NewGuid(); - - public string Media_1_EntityType = nameof(Blog); - - public string Media_1_Content = "Hi, this is text file"; - public string Media_1_Name = "hello.txt"; + public string Media_1_EntityType => nameof(Blog); - public string Media_1_ContentType = "text/plain"; + public string Media_1_Content { get; } = "Hi, this is text file"; + + public string Media_1_Name { get; } = "hello.txt"; + + public string Media_1_ContentType { get; } = "text/plain"; } } From db84676bfd10f5b33541e2fe86844401efcb9950 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 13:10:31 +0300 Subject: [PATCH 036/101] CmsKit - Change policies of PolicySpecifiedDefinition to collection --- .../Permissions/CmsKitAdminPermissions.cs | 8 ++-- .../CmsKit/Admin/CmsKitAdminAppServiceBase.cs | 35 ++++++++++++++++- .../Admin/CmsKitAdminApplicationModule.cs | 16 ++++---- .../MediaDescriptorAdminAppService.cs | 4 +- .../Admin/Tags/EntityTagAdminAppService.cs | 6 +-- .../MediaDescriptorDefinition.cs | 20 ++++------ .../Volo/CmsKit/PolicySpecifiedDefinition.cs | 38 +++++++++++++------ .../CmsKit/Tags/TagEntityTypeDefiniton.cs | 9 +++-- ...TagEntityTypeDefinitionDictionary_Tests.cs | 8 ++-- 9 files changed, 94 insertions(+), 50 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs index 6de7bad5e4..baa26b0fff 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs @@ -5,13 +5,13 @@ namespace Volo.CmsKit.Permissions public class CmsKitAdminPermissions { public const string GroupName = "CmsKit"; - + public static class Comments { public const string Default = GroupName + ".Comments"; public const string Delete = Default + ".Delete"; } - + public static class Tags { public const string Default = GroupName + ".Tags"; @@ -19,7 +19,7 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } - + public static class Contents { public const string Default = GroupName + ".Contents"; @@ -52,7 +52,7 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } - + public static class MediaDescriptors { public const string Default = GroupName + ".MediaDescriptors"; diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs index 3f4596f586..83d36431c8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs @@ -1,4 +1,13 @@ -namespace Volo.CmsKit.Admin +using JetBrains.Annotations; +using Microsoft.AspNetCore.Authorization; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices.ComTypes; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Authorization; + +namespace Volo.CmsKit.Admin { public abstract class CmsKitAdminAppServiceBase : CmsKitAppServiceBase { @@ -6,5 +15,29 @@ { ObjectMapperContext = typeof(CmsKitAdminApplicationModule); } + + /// + /// Checks given policies until finding granted policy. If none of them is granted, throws + /// + /// Policies to be checked. + /// Thrown when none of policies is granted. + protected async Task CheckAnyOfPoliciesAsync([NotNull] IEnumerable policies) + { + Check.NotNull(policies, nameof(policies)); + + foreach (var policy in policies) + { + if (await AuthorizationService.IsGrantedAsync(policy)) + { + return; + } + } + + var exception = new AbpAuthorizationException(); + + exception.Data[nameof(policies)] = policies; + + throw exception; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index 6da0e9233a..95dbe44a04 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -46,9 +46,9 @@ namespace Volo.CmsKit.Admin new TagEntityTypeDefiniton( BlogPostConsts.EntityType, LocalizableString.Create("BlogPost"), - CmsKitAdminPermissions.BlogPosts.Update, - CmsKitAdminPermissions.BlogPosts.Update, - CmsKitAdminPermissions.BlogPosts.Update)); + new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, + new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, + new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update })); } }); @@ -60,9 +60,9 @@ namespace Volo.CmsKit.Admin { options.EntityTypes.AddIfNotContains( new MediaDescriptorDefinition( - BlogPostConsts.EntityType, - createPolicy: CmsKitAdminPermissions.BlogPosts.Update, - deletePolicy: CmsKitAdminPermissions.BlogPosts.Delete)); + BlogPostConsts.EntityType, + createPolicies: new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, + deletePolicies: new[] { CmsKitAdminPermissions.BlogPosts.Delete })); } if (GlobalFeatureManager.Instance.IsEnabled()) @@ -70,8 +70,8 @@ namespace Volo.CmsKit.Admin options.EntityTypes.AddIfNotContains( new MediaDescriptorDefinition( PageConsts.EntityType, - createPolicy: CmsKitAdminPermissions.Pages.Update, - deletePolicy: CmsKitAdminPermissions.Pages.Delete)); + createPolicies: new[] { CmsKitAdminPermissions.Pages.Create, CmsKitAdminPermissions.Pages.Update }, + deletePolicies: new[] { CmsKitAdminPermissions.Pages.Delete })); } }); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index 5307591447..ba2b1a70b5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -35,7 +35,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors { var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(inputStream.EntityType); - await CheckPolicyAsync(definition.CreatePolicy); + await CheckAnyOfPoliciesAsync(definition.CreatePolicies); var newId = GuidGenerator.Create(); using (var stream = inputStream.GetStream()) @@ -56,7 +56,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(mediaDescriptor.EntityType); - await CheckPolicyAsync(definition.DeletePolicy); + await CheckAnyOfPoliciesAsync(definition.DeletePolicies); await MediaContainer.DeleteAsync(id.ToString()); await MediaDescriptorRepository.DeleteAsync(id); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs index cf3de19933..d118ddece7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs @@ -31,7 +31,7 @@ namespace Volo.CmsKit.Admin.Tags { var definition = await TagDefinitionStore.GetTagEntityTypeDefinitionAsync(input.EntityType); - await CheckPolicyAsync(definition.CreatePolicy); + await CheckAnyOfPoliciesAsync(definition.CreatePolicies); var tag = await TagManager.GetOrAddAsync(input.EntityType, input.TagName); @@ -46,7 +46,7 @@ namespace Volo.CmsKit.Admin.Tags { var definition = await TagDefinitionStore.GetTagEntityTypeDefinitionAsync(input.EntityType); - await CheckPolicyAsync(definition.DeletePolicy); + await CheckAnyOfPoliciesAsync(definition.DeletePolicies); await EntityTagManager.RemoveTagFromEntityAsync( input.TagId, @@ -59,7 +59,7 @@ namespace Volo.CmsKit.Admin.Tags { var definition = await TagDefinitionStore.GetTagEntityTypeDefinitionAsync(input.EntityType); - await CheckPolicyAsync(definition.UpdatePolicy); + await CheckAnyOfPoliciesAsync(definition.UpdatePolicies); await EntityTagManager.SetEntityTagsAsync(input.EntityType, input.EntityId, input.Tags); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs index 073ed694f6..95bfaacb61 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/MediaDescriptorDefinition.cs @@ -1,24 +1,20 @@ using JetBrains.Annotations; using System; +using System.Collections.Generic; namespace Volo.CmsKit.MediaDescriptors { - public class MediaDescriptorDefinition : PolicySpecifiedDefinition, IEquatable + public class MediaDescriptorDefinition : PolicySpecifiedDefinition { public MediaDescriptorDefinition( [NotNull] string entityType, - [CanBeNull] string createPolicy = null, - [CanBeNull] string updatePolicy = null, - [CanBeNull] string deletePolicy = null) : base(entityType, - createPolicy, - updatePolicy, - deletePolicy) + IEnumerable createPolicies = null, + IEnumerable updatePolicies = null, + IEnumerable deletePolicies = null) : base(entityType, + createPolicies, + updatePolicies, + deletePolicies) { } - - public bool Equals(MediaDescriptorDefinition other) - { - return base.Equals(other); - } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs index 2a5f69b69e..edfee13337 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/PolicySpecifiedDefinition.cs @@ -1,5 +1,7 @@ using JetBrains.Annotations; using System; +using System.Collections.Generic; +using System.Linq; using Volo.Abp; namespace Volo.CmsKit @@ -12,27 +14,39 @@ namespace Volo.CmsKit public PolicySpecifiedDefinition( [NotNull] string entityType, - [CanBeNull] string createPolicy = null, - [CanBeNull] string updatePolicy = null, - [CanBeNull] string deletePolicy = null) + IEnumerable createPolicies = null, + IEnumerable updatePolicies = null, + IEnumerable deletePolicies = null) { EntityType = Check.NotNullOrEmpty(entityType, nameof(entityType)); - CreatePolicy = createPolicy; - DeletePolicy = deletePolicy; - UpdatePolicy = updatePolicy; + + if (createPolicies != null) + { + CreatePolicies = CreatePolicies.Concat(createPolicies).ToList(); + } + + if (updatePolicies != null) + { + UpdatePolicies = UpdatePolicies.Concat(updatePolicies).ToList(); + } + + if (deletePolicies != null) + { + DeletePolicies = DeletePolicies.Concat(deletePolicies).ToList(); + } } [NotNull] public string EntityType { get; set; } - [CanBeNull] - public virtual string CreatePolicy { get; set; } + [NotNull] + public virtual ICollection CreatePolicies { get; } = new List(); - [CanBeNull] - public virtual string UpdatePolicy { get; set; } + [NotNull] + public virtual ICollection UpdatePolicies { get; } = new List(); - [CanBeNull] - public virtual string DeletePolicy { get; set; } + [NotNull] + public virtual ICollection DeletePolicies { get; } = new List(); public bool Equals(PolicySpecifiedDefinition other) { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs index a6fb4cde7a..6dedb1410e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/TagEntityTypeDefiniton.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using System; +using System.Collections.Generic; using Volo.Abp; using Volo.Abp.Localization; @@ -17,12 +18,12 @@ namespace Volo.CmsKit.Tags public TagEntityTypeDefiniton( [NotNull] string entityType, [CanBeNull] ILocalizableString displayName = null, - [CanBeNull] string createPolicy = null, - [CanBeNull] string updatePolicy = null, - [CanBeNull] string deletePolicy = null) : base(entityType, createPolicy, updatePolicy, deletePolicy) + IEnumerable createPolicies = null, + IEnumerable updatePolicies = null, + IEnumerable deletePolicies = null) : base(entityType, createPolicies, updatePolicies, deletePolicies) { - EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); DisplayName = displayName; + } public bool Equals(TagEntityTypeDefiniton other) diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Tags/TagEntityTypeDefinitionDictionary_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Tags/TagEntityTypeDefinitionDictionary_Tests.cs index a405c27190..2f2013cd0b 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Tags/TagEntityTypeDefinitionDictionary_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Tags/TagEntityTypeDefinitionDictionary_Tests.cs @@ -42,11 +42,11 @@ namespace Volo.CmsKit.Tags { cmsKitTagOptions.EntityTypes.Add( new TagEntityTypeDefiniton( - "My.Entity.Type", + "My.Entity.Type", LocalizableString.Create("MyEntity"), - "SomeCreatePolicy", - "SomeUpdatePolicy", - "SomeDeletePolicy" + new[] { "SomeCreatePolicy" }, + new[] { "SomeUpdatePolicy" }, + new[] { "SomeDeletePolicy" } )); } From e6ffc14c2b4591d609d322d79bcbf74b5ea05a88 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 13:16:55 +0300 Subject: [PATCH 037/101] Added content property to page & update ui --- ...02091451_Added_Content_To_Page.Designer.cs | 2020 +++++++++++++++++ .../20210302091451_Added_Content_To_Page.cs | 24 + .../UnifiedDbContextModelSnapshot.cs | 4 + .../CmsKit/Admin/Pages/CreatePageInputDto.cs | 3 + .../Volo/CmsKit/Admin/Pages/PageDto.cs | 2 + .../CmsKit/Admin/Pages/UpdatePageInputDto.cs | 3 + .../CmsKit/Admin/Pages/PageAdminAppService.cs | 3 +- .../Pages/CmsKit/Pages/Create.cshtml | 44 +- .../Pages/CmsKit/Pages/Create.cshtml.cs | 11 +- .../Pages/CmsKit/Pages/Index.cshtml | 2 - .../Pages/CmsKit/Pages/Update.cshtml | 1 - .../Pages/CmsKit/Pages/Update.cshtml.cs | 3 - .../Pages/CmsKit/Pages/create.js | 116 +- .../Volo/CmsKit/Pages/PageConsts.cs | 2 + .../Volo/CmsKit/Pages/Page.cs | 22 +- .../CmsKitDbContextModelCreatingExtensions.cs | 1 + .../Volo/CmsKit/Public/Pages/PageDto.cs | 2 + .../Shared/Components/Pages/Default.cshtml | 10 +- .../Pages/DefaultPageViewComponent.cs | 7 +- .../Pages/Public/CmsKit/Pages/Index.cshtml | 3 +- .../Pages/PageAdminAppService_Tests.cs | 9 +- .../CmsKitDataSeedContributor.cs | 10 +- 22 files changed, 2218 insertions(+), 84 deletions(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.Designer.cs create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.Designer.cs new file mode 100644 index 0000000000..6c89519250 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.Designer.cs @@ -0,0 +1,2020 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20210302091451_Added_Content_To_Page")] + partial class Added_Content_To_Page + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.3") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)") + .HasColumnName("Exceptions"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpFeatureValues"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogs"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogFeature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeatureName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogFeatures"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuthorId") + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ShortDescription") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("Slug", "BlogId"); + + b.ToTable("CmsBlogPosts"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.MediaDescriptors.MediaDescriptor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Size") + .HasMaxLength(2147483647) + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsMediaDescriptors"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Slug"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.HasOne("Volo.CmsKit.Users.CmsUser", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.cs new file mode 100644 index 0000000000..b7ae92ccc7 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210302091451_Added_Content_To_Page.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class Added_Content_To_Page : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Content", + table: "CmsPages", + type: "nvarchar(max)", + maxLength: 2147483647, + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Content", + table: "CmsPages"); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index e3e9f4cc68..c14e469499 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -1537,6 +1537,10 @@ namespace Volo.CmsKit.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + b.Property("CreationTime") .HasColumnType("datetime2") .HasColumnName("CreationTime"); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs index 465408a8bf..174278d829 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs @@ -16,5 +16,8 @@ namespace Volo.CmsKit.Admin.Pages [Required] [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] public string Slug { get; set; } + + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxContentLength))] + public string Content { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs index e8117ed7b1..5297e9b7d0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs @@ -9,5 +9,7 @@ namespace Volo.CmsKit.Admin.Pages public string Title { get; set; } public string Slug { get; set; } + + public string Content { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs index f33c40be6a..eff3cb2919 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs @@ -16,5 +16,8 @@ namespace Volo.CmsKit.Admin.Pages [Required] [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] public string Slug { get; set; } + + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxContentLength))] + public string Content { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs index 9016a620c8..102b2a6afd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs @@ -50,7 +50,7 @@ namespace Volo.CmsKit.Admin.Pages { await CheckPageSlugAsync(input.Slug); - var page = new Page(GuidGenerator.Create(), input.Title, input.Slug, CurrentTenant.Id); + var page = new Page(GuidGenerator.Create(), input.Title, input.Slug, input.Content, CurrentTenant.Id); await PageRepository.InsertAsync(page); @@ -69,6 +69,7 @@ namespace Volo.CmsKit.Admin.Pages page.SetTitle(input.Title); page.SetSlug(input.Slug); + page.SetContent(input.Content); await PageRepository.UpdateAsync(page); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml index fe9f8d4b69..f7a584c940 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml @@ -1,9 +1,10 @@ @page -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor +@using System.Globalization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Menus -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages @using Volo.CmsKit.Admin.Web.Bundles @inherits CmsKitAdminPageBase @@ -17,27 +18,36 @@ } @section scripts { - - - - + + + + + + +} + +@section styles { + + + } - - - +
+ + - - - @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new - { - entityType = "Page", - displaySubmitButton = false - }) - + + + +
+
+
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs index a4d90abafb..430c516ce3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs @@ -2,10 +2,8 @@ using Microsoft.AspNetCore.Mvc; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.Validation; using Volo.CmsKit.Admin.Pages; -using Volo.CmsKit.Admin.Web.Pages; using Volo.CmsKit.Pages; namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages @@ -34,14 +32,17 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages [AutoMap(typeof(CreatePageInputDto), ReverseMap = true)] public class CreatePageViewModel { - [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] [Required] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] public string Title { get; set; } - [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] [Required] - [DynamicFormIgnore] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] public string Slug { get; set; } + + [HiddenInput] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] + public string Content { get; set; } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml index 59fa975e24..c85d4759ba 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Index.cshtml @@ -1,6 +1,4 @@ @page - -@using Volo.Abp.AspNetCore.Mvc.UI.Layout @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageSearchBox @using Volo.CmsKit.Admin.Web.Pages diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml index 90f043e89e..35507ef2ae 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml @@ -2,7 +2,6 @@ @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor @using Volo.CmsKit.Admin.Web.Menus -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages @using Volo.CmsKit.Admin.Web.Pages @inherits CmsKitAdminPageBase diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs index e0b2d8b1b1..c80714aa91 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs @@ -1,10 +1,7 @@ using AutoMapper; using Microsoft.AspNetCore.Mvc; using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.Validation; diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js index d0a27aefe3..029ab189cd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js @@ -1,22 +1,25 @@ $(function () { var l = abp.localization.getResource("CmsKit"); - var $formCreate = $('#form-page-create'); + var $createForm = $('#form-page-create'); var $title = $('#ViewModel_Title'); var $slug = $('#ViewModel_Slug'); var $buttonSubmit = $('#button-page-create'); - var $pageContentInput = $('#ViewModel_Value'); - $formCreate.on('submit', function (e) { + $createForm.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; + + $createForm.on('submit', function (e) { e.preventDefault(); - if ($formCreate.valid()) { + if ($createForm.valid()) { abp.ui.setBusy(); - $formCreate.ajaxSubmit({ + $createForm.ajaxSubmit({ success: function (result) { - submitEntityContent(result.id); + abp.notify.success(l('SuccessfullySaved')); + abp.ui.clearBusy(); + location.href = "/CmsKit/Pages/"; } }); } @@ -24,28 +27,9 @@ $buttonSubmit.click(function (e) { e.preventDefault(); - $formCreate.submit(); + $createForm.submit(); }); - function submitEntityContent(pageId) { - volo.cmsKit.admin.contents.contentAdmin - .create( - { - entityType: 'Page', - entityId: pageId, - value: $pageContentInput.val() - }) - .then(function (result) { - finishSaving(); - }); - } - - function finishSaving() { - abp.notify.success(l('SuccessfullySaved')); - abp.ui.clearBusy(); - location.href = "/CmsKit/Pages/"; - } - var slugEdited = false; $title.on('change paste keyup', function () { @@ -69,4 +53,84 @@ $slug.change(function () { slugEdited = true; }); + + // ----------------------------------- + function getUppyHeaders() { + var headers = {}; + headers[abp.security.antiForgery.tokenHeaderName] = abp.security.antiForgery.getToken(); + + return headers; + } + + var fileUploadUri = "/api/cms-kit-admin/media/page"; + var fileUriPrefix = "/api/cms-kit/media/"; + + var editorDataKey = "tuiEditor"; + + initAllEditors(); + + function initAllEditors() { + $('.content-editor').each(function (i, item) { + initEditor(item); + }); + } + + function initEditor(element) { + var $editorContainer = $(element); + var inputName = $editorContainer.data('input-id'); + var $editorInput = $('#' + inputName); + var initialValue = $editorInput.val(); + + var editor = $editorContainer.tuiEditor({ + usageStatistics: false, + useCommandShortcut: true, + initialValue: initialValue, + previewStyle: 'tab', + height: "25em", + minHeight: "25em", + initialEditType: initialValue ? 'wysiwyg' : 'markdown', + language: $editorContainer.data("language"), + hooks: { + addImageBlobHook: uploadFile, + }, + events: { + change: function (_val) { + $editorInput.val(editor.getHtml()); + $editorInput.trigger("change"); + } + } + }).data(editorDataKey); + } + + function uploadFile(blob, callback, source) { + var UPPY_OPTIONS = { + endpoint: fileUploadUri, + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + UPPY.addFile({ + id: "content-file", + name: blob.name, + type: blob.type, + data: blob, + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error("File upload failed"); + } else { + var mediaDto = result.successful[0].response.body; + var fileUrl = (fileUriPrefix + mediaDto.id); + + callback(fileUrl, mediaDto.name); + } + }); + } }); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs index 47d82b5d07..9858f30e14 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs @@ -5,5 +5,7 @@ public static int MaxTitleLength { get; set; } = 256; public static int MaxSlugLength { get; set; } = 256; + + public static int MaxContentLength { get; set; } = int.MaxValue; } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs index 9c0ee2d6b9..dd759ebd08 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs @@ -8,22 +8,25 @@ namespace Volo.CmsKit.Pages { public class Page : FullAuditedAggregateRoot, IMultiTenant { - [CanBeNull] public virtual Guid? TenantId { get; protected set; } + public virtual Guid? TenantId { get; protected set; } - [NotNull] public virtual string Title { get; protected set; } + public virtual string Title { get; protected set; } - [NotNull] public virtual string Slug { get; protected set; } + public virtual string Slug { get; protected set; } + public virtual string Content { get; protected set; } + protected Page() { } - public Page(Guid id, [NotNull] string title, [NotNull] string slug, [CanBeNull]Guid? tenantId = null) : base(id) + public Page(Guid id, [NotNull] string title, [NotNull] string slug, string content = null, Guid? tenantId = null) : base(id) { - Title = Check.NotNullOrEmpty(title, nameof(title), PageConsts.MaxTitleLength); - Slug = Check.NotNullOrEmpty(slug, nameof(slug), PageConsts.MaxSlugLength); - TenantId = tenantId; + + SetTitle(title); + SetSlug(slug); + SetContent(content); } public virtual void SetTitle(string title) @@ -35,5 +38,10 @@ namespace Volo.CmsKit.Pages { Slug = Check.NotNullOrEmpty(slug, nameof(slug), PageConsts.MaxSlugLength); } + + public virtual void SetContent(string content) + { + Content = Check.Length(content, nameof(content), PageConsts.MaxContentLength); + } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 8208dd38ea..14200c5c24 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -179,6 +179,7 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(x => x.Title).IsRequired().HasMaxLength(PageConsts.MaxTitleLength); b.Property(x => x.Slug).IsRequired().HasMaxLength(PageConsts.MaxSlugLength); + b.Property(x => x.Content).HasMaxLength(PageConsts.MaxContentLength); b.HasIndex(x => new { x.TenantId, Url = x.Slug }); }); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs index 2add3c9d38..682c90b8c8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs @@ -9,5 +9,7 @@ namespace Volo.CmsKit.Public.Pages public string Title { get; set; } public string Slug { get; set; } + + public string Content { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml index e10fa0754a..ae23d5757f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml @@ -1,8 +1,5 @@ @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap - -@using Microsoft.AspNetCore.Mvc.RazorPages @using Volo.Abp.AspNetCore.Mvc.UI.Layout -@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents @model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages.PageViewModel @inject IPageLayout PageLayout @@ -12,11 +9,6 @@ - @await Component.InvokeAsync(typeof(ContentViewComponent), - new - { - entityType = nameof(Page), - entityId = Model.Id.ToString() - }) + @Html.Raw(Model.Content) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs index c972643359..3c8be1c2c3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs @@ -16,12 +16,13 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages PagePublicAppService = pagePublicAppService; } - public virtual async Task InvokeAsync(Guid pageId, string title, string description) + public virtual async Task InvokeAsync(Guid pageId, string title, string content) { var model = new PageViewModel { Id = pageId, - Title = title + Title = title, + Content = content }; return View("~/Pages/CmsKit/Shared/Components/Pages/Default.cshtml", model); @@ -33,5 +34,7 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages public Guid Id { get; set; } public string Title { get; set; } + + public string Content { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml index 6060c00304..426b5ebacf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml @@ -9,5 +9,6 @@ new { pageId = Model.Page.Id, - title = Model.Page.Title + title = Model.Page.Title, + content = Model.Page.Content }) \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs index c3e82c58f1..766c482ddd 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs @@ -64,7 +64,8 @@ namespace Volo.CmsKit.Pages var dto = new CreatePageInputDto { Title = "test", - Slug = "test-url" + Slug = "test-url", + Content = "test*content" }; await Should.NotThrowAsync(async () => await _pageAdminAppService.CreateAsync(dto)); @@ -94,7 +95,8 @@ namespace Volo.CmsKit.Pages var dto = new UpdatePageInputDto { Title = _data.Page_1_Title + "++", - Slug = _data.Page_1_Slug+ "test" + Slug = _data.Page_1_Slug+ "test", + Content = "changed" }; await Should.NotThrowAsync(async () => await _pageAdminAppService.UpdateAsync(_data.Page_1_Id, dto)); @@ -106,6 +108,9 @@ namespace Volo.CmsKit.Pages updatedPage.Slug.ShouldNotBe(_data.Page_1_Slug); updatedPage.Slug.ShouldBe(dto.Slug); + + updatedPage.Content.ShouldNotBe(_data.Content_1); + updatedPage.Content.ShouldBe(dto.Content); } [Fact] diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 00969c46ab..504961cf0c 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -338,17 +338,11 @@ namespace Volo.CmsKit private async Task SeedPagesAsync() { - var page1 = new Page(_cmsKitTestData.Page_1_Id, _cmsKitTestData.Page_1_Title, _cmsKitTestData.Page_1_Slug); - var page1Content = new Content(_guidGenerator.Create(), nameof(Page), page1.Id.ToString(), _cmsKitTestData.Page_1_Content); - + var page1 = new Page(_cmsKitTestData.Page_1_Id, _cmsKitTestData.Page_1_Title, _cmsKitTestData.Page_1_Slug, _cmsKitTestData.Content_1); await _pageRepository.InsertAsync(page1); - await _contentRepository.InsertAsync(page1Content); - - var page2 = new Page(_cmsKitTestData.Page_2_Id, _cmsKitTestData.Page_2_Title, _cmsKitTestData.Page_2_Slug); - var page2Content = new Content(_guidGenerator.Create(), nameof(Page), page2.Id.ToString(), _cmsKitTestData.Page_2_Content); + var page2 = new Page(_cmsKitTestData.Page_2_Id, _cmsKitTestData.Page_2_Title, _cmsKitTestData.Page_2_Slug, _cmsKitTestData.Content_2); await _pageRepository.InsertAsync(page2); - await _contentRepository.InsertAsync(page2Content); } private async Task SeedBlogsAsync() From 40bab24cca024ecf18ef0b4c0c533be7a277caf7 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 13:23:17 +0300 Subject: [PATCH 038/101] CmsKit - Remove Media Permissions --- .../Permissions/CmsKitAdminPermissionDefinitionProvider.cs | 7 ------- .../Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs | 7 ------- .../MediaDescriptors/MediaDescriptorAdminAppService.cs | 3 --- .../MediaDescriptors/MediaDescriptorAdminController.cs | 4 ---- 4 files changed, 21 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs index ccb4d1048b..a8317b6b6b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs @@ -56,13 +56,6 @@ namespace Volo.CmsKit.Permissions blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Update, L("Permission:BlogPostManagement.Update")); blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Delete, L("Permission:BlogPostManagement.Delete")); } - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - var mediaDescriptorManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.MediaDescriptors.Default, L("Permission:MediaDescriptorManagement")); - mediaDescriptorManagement.AddChild(CmsKitAdminPermissions.MediaDescriptors.Create, L("Permission:MediaDescriptorManagement:Create")); - mediaDescriptorManagement.AddChild(CmsKitAdminPermissions.MediaDescriptors.Delete, L("Permission:MediaDescriptorManagement:Delete")); - } } private static LocalizableString L(string name) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs index baa26b0fff..c524e7e6b5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs @@ -52,12 +52,5 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } - - public static class MediaDescriptors - { - public const string Default = GroupName + ".MediaDescriptors"; - public const string Create = Default + ".Create"; - public const string Delete = Default + ".Delete"; - } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index ba2b1a70b5..45774ca1f2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -10,7 +10,6 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.MediaDescriptors { [RequiresGlobalFeature(typeof(MediaFeature))] - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Default)] public class MediaDescriptorAdminAppService : CmsKitAdminAppServiceBase, IMediaDescriptorAdminAppService { protected IBlobContainer MediaContainer { get; } @@ -30,7 +29,6 @@ namespace Volo.CmsKit.Admin.MediaDescriptors MediaDescriptorDefinitionStore = mediaDescriptorDefinitionStore; } - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Create)] public virtual async Task CreateAsync(CreateMediaInputStream inputStream) { var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(inputStream.EntityType); @@ -49,7 +47,6 @@ namespace Volo.CmsKit.Admin.MediaDescriptors } } - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Delete)] public virtual async Task DeleteAsync(Guid id) { var mediaDescriptor = await MediaDescriptorRepository.GetAsync(id); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs index 124cfcba1c..91cd5170a5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs @@ -13,7 +13,6 @@ namespace Volo.CmsKit.Admin.MediaDescriptors { [RequiresGlobalFeature(typeof(MediaFeature))] [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Default)] [Area("cms-kit")] [Route("api/cms-kit-admin/media")] public class MediaDescriptorAdminController : CmsKitAdminController, IMediaDescriptorAdminAppService @@ -26,7 +25,6 @@ namespace Volo.CmsKit.Admin.MediaDescriptors } [HttpPost] - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Create)] [NonAction] public virtual Task CreateAsync(CreateMediaInputStream inputStream) { @@ -35,7 +33,6 @@ namespace Volo.CmsKit.Admin.MediaDescriptors [HttpDelete] [Route("{id}")] - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Delete)] public virtual Task DeleteAsync(Guid id) { return MediaDescriptorAdminAppService.DeleteAsync(id); @@ -43,7 +40,6 @@ namespace Volo.CmsKit.Admin.MediaDescriptors [HttpPost] [Route("{entityType}")] - [Authorize(CmsKitAdminPermissions.MediaDescriptors.Create)] public virtual async Task UploadAsync(string entityType, IFormFile file) { if (file == null) From 0d9b602f7e5454822abdb6d0f1d5a1323724cc63 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 13:23:30 +0300 Subject: [PATCH 039/101] CmsKit - Add policies to test data --- .../test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index e2c928be2a..8fd8b14f46 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -136,7 +136,11 @@ namespace Volo.CmsKit _tagOptions.Value.EntityTypes.AddIfNotContains(new TagEntityTypeDefiniton(_cmsKitTestData.Content_2_EntityType)); _tagOptions.Value.EntityTypes.AddIfNotContains(new TagEntityTypeDefiniton(_cmsKitTestData.TagDefinition_1_EntityType)); - _mediaOptions.Value.EntityTypes.AddIfNotContains(new MediaDescriptorDefinition(_cmsKitTestData.Media_1_EntityType)); + _mediaOptions.Value.EntityTypes.AddIfNotContains( + new MediaDescriptorDefinition( + _cmsKitTestData.Media_1_EntityType, + createPolicies: new[] { "SomeCreatePolicy" }, + deletePolicies: new[] { "SomeDeletePolicy" })); return Task.CompletedTask; } From 5e32bfd579220ae0779032b5ce13e84d789789e8 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 13:29:07 +0300 Subject: [PATCH 040/101] CmsKit - Refactoring for DefaultMediaDescriptorDefinitionStore --- .../MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs index 4bdd4d6e98..5a1553c3fc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs @@ -25,7 +25,7 @@ namespace Volo.CmsKit.MediaDescriptors /// EntityType to get definition. /// Thrown when EntityType is not configured as taggable. /// More than one element satisfies the condition in predicate. - public Task GetDefinitionAsync([NotNull] string entityType) + public virtual Task GetDefinitionAsync([NotNull] string entityType) { Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); @@ -35,7 +35,7 @@ namespace Volo.CmsKit.MediaDescriptors return Task.FromResult(result); } - public Task IsDefinedAsync([NotNull] string entityType) + public virtual Task IsDefinedAsync([NotNull] string entityType) { Check.NotNullOrEmpty(entityType, nameof(entityType)); From 2c089a24433191d0bde664bb8111cbb7ae33290f Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 13:30:47 +0300 Subject: [PATCH 041/101] remove content from cms-kit --- ...CmsKitAdminApplicationAutoMapperProfile.cs | 7 - .../Admin/Contents/ContentAdminAppService.cs | 71 --------- .../Pages/CmsKit/BlogPosts/Create.cshtml | 1 - .../Pages/CmsKit/BlogPosts/Update.cshtml | 1 - .../ContentEditorViewComponent.cs | 44 ------ .../Components/ContentEditor/Default.cshtml | 7 - .../Components/ContentEditor/default.js | 80 ---------- .../EntityContentEditor/ContentViewModel.cs | 28 ---- .../EntityContentEditor/Default.cshtml | 27 ---- .../EntityContentEditorViewComponent.cs | 65 -------- .../Components/EntityContentEditor/default.js | 34 ----- .../Pages/CmsKit/Pages/Create.cshtml | 2 +- .../Pages/CmsKit/Pages/Update.cshtml | 11 +- .../Volo/CmsKit/Contents/Content.cs | 44 ------ .../Contents/ContentAlreadyExistException.cs | 17 --- .../Volo/CmsKit/Contents/ContentManager.cs | 32 ---- .../Volo/CmsKit/Contents/IContentManager.cs | 11 -- .../CmsKit/Contents/IContentRepository.cs | 35 ----- .../Contents/EfCoreContentRepository.cs | 86 ----------- .../EntityFrameworkCore/CmsKitDbContext.cs | 2 - .../CmsKitDbContextModelCreatingExtensions.cs | 21 --- .../CmsKitEntityFrameworkCoreModule.cs | 1 - .../EntityFrameworkCore/ICmsKitDbContext.cs | 2 - .../CmsKit/MongoDB/CmsKitMongoDbContext.cs | 2 - .../MongoDB/CmsKitMongoDbContextExtensions.cs | 5 - .../CmsKit/MongoDB/CmsKitMongoDbModule.cs | 3 - .../Contents/MongoContentRepository.cs | 80 ---------- .../CmsKit/MongoDB/ICmsKitMongoDbContext.cs | 2 - .../Contents/ContentPublicAppService.cs | 25 --- .../PublicApplicationAutoMapperProfile.cs | 4 - .../Contents/ContentAdminAppService_Tests.cs | 142 ------------------ .../Contents/ContentRepository_Test.cs | 9 -- .../Contents/ContentRepository_Test.cs | 11 -- .../CmsKitDataSeedContributor.cs | 39 ----- .../Contents/ContentRepository_Tests.cs | 63 -------- 35 files changed, 2 insertions(+), 1012 deletions(-) delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/Content.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentAlreadyExistException.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentRepository.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Contents/EfCoreContentRepository.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Contents/MongoContentRepository.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Contents/ContentPublicAppService.cs delete mode 100644 modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentAdminAppService_Tests.cs delete mode 100644 modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Contents/ContentRepository_Test.cs delete mode 100644 modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Contents/ContentRepository_Test.cs delete mode 100644 modules/cms-kit/test/Volo.CmsKit.TestBase/Contents/ContentRepository_Tests.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs index b78910ce01..a2615292f0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs @@ -2,13 +2,11 @@ using Volo.Abp.AutoMapper; using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Admin.Comments; -using Volo.CmsKit.Admin.Contents; using Volo.CmsKit.Admin.MediaDescriptors; using Volo.CmsKit.Admin.Pages; using Volo.CmsKit.Blogs; using Volo.CmsKit.Admin.Tags; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Tags; @@ -28,11 +26,6 @@ namespace Volo.CmsKit.Admin CreateMap(); - CreateMap(MemberList.Destination); - CreateMap(MemberList.Destination); - CreateMap(MemberList.Source); - CreateMap(MemberList.Source); - CreateMap(MemberList.Destination); CreateMap(MemberList.Source); CreateMap(MemberList.Source); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs deleted file mode 100644 index 1aa0bffcfa..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs +++ /dev/null @@ -1,71 +0,0 @@ -using JetBrains.Annotations; -using Microsoft.AspNetCore.Authorization; -using System; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Services; -using Volo.Abp.Domain.Repositories; -using Volo.CmsKit.Contents; -using Volo.CmsKit.Permissions; - -namespace Volo.CmsKit.Admin.Contents -{ - [Authorize(CmsKitAdminPermissions.Contents.Default)] - public class ContentAdminAppService : - CrudAppService< - Content, - ContentDto, - ContentGetListDto, - Guid, - ContentGetListInput, - ContentCreateDto, - ContentUpdateDto - >, IContentAdminAppService - { - protected IContentManager ContentManager { get; } - - protected IContentRepository ContentRepository { get; } - - public ContentAdminAppService( - IRepository repository, - IContentManager contentManager, - IContentRepository contentRepository) : base(repository) - { - ContentManager = contentManager; - ContentRepository = contentRepository; - - GetListPolicyName = CmsKitAdminPermissions.Contents.Default; - GetPolicyName = CmsKitAdminPermissions.Contents.Default; - CreatePolicyName = CmsKitAdminPermissions.Contents.Create; - UpdatePolicyName = CmsKitAdminPermissions.Contents.Update; - DeletePolicyName = CmsKitAdminPermissions.Contents.Delete; - } - - [Authorize(CmsKitAdminPermissions.Contents.Create)] - public override async Task CreateAsync(ContentCreateDto input) - { - var entity = new Content( - GuidGenerator.Create(), - input.EntityType, - input.EntityId, - input.Value, - CurrentTenant?.Id); - - await ContentManager.InsertAsync(entity); - - return await MapToGetOutputDtoAsync(entity); - } - - public virtual async Task GetAsync( - [NotNull] string entityType, - [NotNull] string entityId) - { - Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); - Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); - - var content = await ContentRepository.GetAsync(entityType, entityId, CurrentTenant?.Id); - - return ObjectMapper.Map(content); - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml index 8440bc0c40..4659ca4198 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml @@ -2,7 +2,6 @@ @using System.Globalization @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar @using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Menus diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml index b9a1dbb638..7c56152b8e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml @@ -5,7 +5,6 @@ @using Volo.CmsKit.Blogs @using Volo.CmsKit.Admin.Web.Pages @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor @using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs deleted file mode 100644 index bba95a0e45..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/ContentEditorViewComponent.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ViewFeatures; -using System.Threading.Tasks; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor; -using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy; -using Volo.Abp.AspNetCore.Mvc.UI.Widgets; - -namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.ContentEditor -{ - [Widget( - StyleTypes = new[] - { - typeof(TuiEditorStyleContributor) - }, - ScriptTypes = new[] - { - typeof(TuiEditorScriptContributor), - typeof(UppyScriptContributor) - }, - ScriptFiles = new[] - { - "/Pages/CmsKit/Contents/Components/ContentEditor/default.js" - })] - public class ContentEditorViewComponent : AbpViewComponent - { - public async Task InvokeAsync(string inputId) - { - return View( - "~/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml", - new ContentEditorViewModel(inputId)); - } - - public class ContentEditorViewModel - { - public ContentEditorViewModel(string inputId) - { - InputId = inputId; - } - - public string InputId { get; set; } - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml deleted file mode 100644 index cde532b02c..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/Default.cshtml +++ /dev/null @@ -1,7 +0,0 @@ -@using System.Globalization -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.ContentEditor - -@model ContentEditorViewComponent.ContentEditorViewModel - -
-
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js deleted file mode 100644 index a6ccbbde65..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/ContentEditor/default.js +++ /dev/null @@ -1,80 +0,0 @@ -$(function () { - var fileUploadUri = "/api/cms-kit-admin/media"; - var fileUriPrefix = "/api/cms-kit/media/"; - - var editorDataKey = "tuiEditor"; - - initAllEditors(); - - function initAllEditors() { - $('.content-editor').each(function (i, item) { - initEditor(item); - }); - } - - function initEditor(element) { - var $editorContainer = $(element); - var inputName = $editorContainer.data('input-id'); - var $editorInput = $('#' + inputName); - var initialValue = $editorInput.val(); - - var editor = $editorContainer.tuiEditor({ - usageStatistics: false, - useCommandShortcut: true, - initialValue: initialValue, - previewStyle: 'tab', - height: "25em", - minHeight: "25em", - initialEditType: initialValue ? 'wysiwyg' : 'markdown', - language: $editorContainer.data("language"), - hooks: { - addImageBlobHook: uploadFile, - }, - events: { - change: function (_val) { - $editorInput.val(editor.getHtml()); - $editorInput.trigger("change"); - } - } - }).data(editorDataKey); - } - - function getUppyHeaders() { - var headers = {}; - headers[abp.security.antiForgery.tokenHeaderName] = abp.security.antiForgery.getToken(); - - return headers; - } - - function uploadFile(blob, callback, source) { - var UPPY_OPTIONS = { - endpoint: fileUploadUri, - formData: true, - fieldName: "file", - method: "post", - headers: getUppyHeaders() - }; - - var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); - - UPPY.reset(); - - UPPY.addFile({ - id: "content-file", - name: blob.name, - type: blob.type, - data: blob, - }); - - UPPY.upload().then((result) => { - if (result.failed.length > 0) { - abp.message.error("File upload failed"); - } else { - var mediaDto = result.successful[0].response.body; - var fileUrl = (fileUriPrefix + mediaDto.id); - - callback(fileUrl, mediaDto.name); - } - }); - } -}); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs deleted file mode 100644 index 891fe50bd1..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/ContentViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System; - -namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor -{ - public class ContentViewModel - { - public ContentViewModel(string entityType, string entityId, string value = null, Guid? id = null) - { - EntityType = entityType; - EntityId = entityId; - Value = value; - Id = id; - } - - [HiddenInput] - public string EntityType { get; set; } - - [HiddenInput] - public string EntityId { get; set; } - - [HiddenInput] - public string Value { get; set; } - - [HiddenInput] - public Guid? Id { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml deleted file mode 100644 index ba8132ccc1..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml +++ /dev/null @@ -1,27 +0,0 @@ -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.ContentEditor -@using Volo.CmsKit.Localization -@using Microsoft.Extensions.Localization - -@model EntityContentEditorViewComponent.EntityContentEditorViewModel - -@inject IStringLocalizer L - -@if (Model.DisplaySubmitButton) -{ - - - - - - -} -else -{ - - - - -} - -@await Component.InvokeAsync(typeof(ContentEditorViewComponent), new { inputId = Html.IdFor(m => m.ViewModel.Value) }) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs deleted file mode 100644 index 44db557f16..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/EntityContentEditorViewComponent.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; -using Volo.Abp.AspNetCore.Mvc.UI.Widgets; -using Volo.Abp.Domain.Entities; -using Volo.CmsKit.Admin.Contents; - -namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor -{ - [Widget( - ScriptFiles = new[] - { - "/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js" - })] - public class EntityContentEditorViewComponent : AbpViewComponent - { - private readonly IContentAdminAppService contentAdminAppService; - - public EntityContentEditorViewComponent(IContentAdminAppService contentAdminAppService) - { - this.contentAdminAppService = contentAdminAppService; - } - - public async Task InvokeAsync(string entityType, string entityId, bool displaySubmitButton = true) - { - var viewModel = new ContentViewModel(entityType, entityId); - - try - { - if (entityId != null) - { - var content = await contentAdminAppService.GetAsync(entityType, entityId); - viewModel.Value = content.Value; - viewModel.Id = content.Id; - } - } - catch (EntityNotFoundException) - { - // Initialize editor even content doesn't exist. - } - - return View( - "~/Pages/CmsKit/Contents/Components/EntityContentEditor/Default.cshtml", - new EntityContentEditorViewModel(viewModel, displaySubmitButton)); - } - - public class EntityContentEditorViewModel - { - public ContentViewModel ViewModel { get; set; } - - public bool DisplaySubmitButton { get; set; } - - public EntityContentEditorViewModel(ContentViewModel viewModel, bool displaySubmitButton) - { - ViewModel = viewModel; - DisplaySubmitButton = displaySubmitButton; - } - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js deleted file mode 100644 index 34f84f8419..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Contents/Components/EntityContentEditor/default.js +++ /dev/null @@ -1,34 +0,0 @@ -$(function () { - - $entityContentEditors = $('.form-entity-content-editor'); - - var contentAdminService = volo.cmsKit.admin.contents.contentAdmin; - - $entityContentEditors.on('submit', function (e, obj) { - e.preventDefault(); - - var $form = $(e.currentTarget); - - if ($form.valid()) { - - var data = form.serializeFormToObject().viewModel; - - abp.ui.setBusy(e); - if (data.id) { - contentAdminService - .update(data.id, data) - .then(function (result) { - abp.ui.clearBusy(); - }); - - } - else { - contentAdminService - .create(data) - .then(function (result) { - abp.ui.clearBusy(); - }); - } - } - }) -}) \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml index f7a584c940..b4896a7449 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml @@ -9,7 +9,7 @@ @inherits CmsKitAdminPageBase -@model CreateModel +@model Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.CreateModel @{ PageLayout.Content.Title = L["Pages"].Value; diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml index 35507ef2ae..c79ff8b72c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml @@ -1,12 +1,11 @@ @page "{Id}" -@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Contents.Components.EntityContentEditor @using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Admin.Web.Pages @inherits CmsKitAdminPageBase -@model UpdateModel +@model Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.UpdateModel @{ PageLayout.Content.Title = L["Pages"].Value; @@ -29,14 +28,6 @@ - - @await Component.InvokeAsync(typeof(EntityContentEditorViewComponent), new - { - entityType = "Page", - entityId = Model.Id.ToString(), - displaySubmitButton = false - }) - diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/Content.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/Content.cs deleted file mode 100644 index 392abfbc6f..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/Content.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using JetBrains.Annotations; -using Volo.Abp; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace Volo.CmsKit.Contents -{ - public class Content : FullAuditedAggregateRoot, IMultiTenant - { - [CanBeNull] public virtual Guid? TenantId { get; protected set; } - - [NotNull] public virtual string EntityType { get; protected set; } - - [NotNull] public virtual string EntityId { get; protected set; } - - [NotNull] public virtual string Value { get; protected set; } - - protected Content() - { - } - - public Content(Guid id, [NotNull] string entityType, [NotNull] string entityId, [NotNull] string value, - Guid? tenantId = null) : base(id) - { - EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId), ContentConsts.MaxEntityIdLength); - EntityType = Check.NotNullOrEmpty(entityType, nameof(entityType), ContentConsts.MaxEntityTypeLength); - Value = Check.NotNullOrEmpty(value, nameof(value), ContentConsts.MaxValueLength); - - TenantId = tenantId; - } - - public virtual void SetValue([NotNull] string value) - { - Value = Check.NotNullOrEmpty(value, nameof(value), ContentConsts.MaxValueLength); - } - - public virtual void SetEntity([NotNull] string entityType, [NotNull] string entityId) - { - EntityType = Check.NotNullOrEmpty(entityType, nameof(entityType), ContentConsts.MaxEntityTypeLength); - EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId), ContentConsts.MaxEntityIdLength); - } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentAlreadyExistException.cs deleted file mode 100644 index 8ea4d4c54a..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentAlreadyExistException.cs +++ /dev/null @@ -1,17 +0,0 @@ -using JetBrains.Annotations; -using System; -using Volo.Abp; - -namespace Volo.CmsKit.Contents -{ - [Serializable] - public class ContentAlreadyExistException : BusinessException - { - public ContentAlreadyExistException([NotNull] string entityType, [NotNull] string entityId) - { - Code = CmsKitErrorCodes.ContentAlreadyExist; - WithData(nameof(Content.EntityType), entityType); - WithData(nameof(Content.EntityId), entityId); - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs deleted file mode 100644 index 707f15bbb9..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.Contents -{ - public class ContentManager : DomainService, IContentManager - { - protected IContentRepository ContentRepository { get; } - - public ContentManager(IContentRepository contentRepository) - { - ContentRepository = contentRepository; - } - - public virtual async Task InsertAsync(Content content, CancellationToken cancellationToken = default) - { - if (await ContentRepository.ExistsAsync(content.EntityType, content.EntityId, content.TenantId, - cancellationToken)) - { - throw new ContentAlreadyExistException(content.EntityType, content.EntityId); - } - - return await ContentRepository.InsertAsync(content, cancellationToken: cancellationToken); - } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs deleted file mode 100644 index d64bd0effe..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.Contents -{ - public interface IContentManager - { - Task InsertAsync(Content content, CancellationToken cancellationToken = default); - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentRepository.cs deleted file mode 100644 index 3b767b4722..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentRepository.cs +++ /dev/null @@ -1,35 +0,0 @@ -using JetBrains.Annotations; -using System; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp.Domain.Repositories; - -namespace Volo.CmsKit.Contents -{ - public interface IContentRepository : IBasicRepository - { - Task GetAsync( - [NotNull] string entityType, - [NotNull] string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default); - - Task FindAsync( - [NotNull] string entityType, - [NotNull] string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default); - - Task DeleteAsync( - [NotNull] string entityType, - [NotNull] string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default); - - Task ExistsAsync( - [NotNull] string entityType, - [NotNull] string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default); - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Contents/EfCoreContentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Contents/EfCoreContentRepository.cs deleted file mode 100644 index 9a99bc5eca..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Contents/EfCoreContentRepository.cs +++ /dev/null @@ -1,86 +0,0 @@ -using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore; -using System; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Domain.Repositories.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore; -using Volo.CmsKit.EntityFrameworkCore; - -namespace Volo.CmsKit.Contents -{ - public class EfCoreContentRepository : EfCoreRepository, IContentRepository - { - public EfCoreContentRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) - { - } - - public virtual Task GetAsync( - string entityType, - string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return GetAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken) - ); - } - - public virtual Task FindAsync( - string entityType, - string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return FindAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken) - ); - } - - public virtual Task DeleteAsync( - string entityType, - string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return DeleteAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken)); - } - - public virtual async Task ExistsAsync( - [NotNull] string entityType, - [NotNull] string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - var dbSet = await GetDbSetAsync(); - return await dbSet.AnyAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken)); - } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs index 749a0653f9..7fc05ea042 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs @@ -3,7 +3,6 @@ using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; @@ -16,7 +15,6 @@ namespace Volo.CmsKit.EntityFrameworkCore [ConnectionStringName(CmsKitDbProperties.ConnectionStringName)] public class CmsKitDbContext : AbpDbContext, ICmsKitDbContext { - public DbSet Contents { get; set; } public DbSet Comments { get; set; } public DbSet User { get; set; } public DbSet Reactions { get; set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 14200c5c24..57a8e062fc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -8,7 +8,6 @@ using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; using Volo.CmsKit.Users; using Volo.Abp.Users.EntityFrameworkCore; -using Volo.CmsKit.Contents; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; @@ -111,26 +110,6 @@ namespace Volo.CmsKit.EntityFrameworkCore builder.Ignore(); } - if (GlobalFeatureManager.Instance.IsEnabled()) - { - builder.Entity(b => - { - b.ToTable(options.TablePrefix + "Contents", options.Schema); - - b.ConfigureByConvention(); - - b.Property(x => x.EntityType).IsRequired().HasMaxLength(ContentConsts.MaxEntityTypeLength); - b.Property(x => x.EntityId).IsRequired().HasMaxLength(ContentConsts.MaxEntityIdLength); - b.Property(x => x.Value).IsRequired().HasMaxLength(ContentConsts.MaxValueLength); - - b.HasIndex(x => new { x.TenantId, x.EntityType, x.EntityId }); - }); - } - else - { - builder.Ignore(); - } - if (GlobalFeatureManager.Instance.IsEnabled()) { builder.Entity(b => diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs index 335bbb9f78..0bbb9ea58b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs @@ -29,7 +29,6 @@ namespace Volo.CmsKit.EntityFrameworkCore options.AddRepository(); options.AddRepository(); options.AddRepository(); - options.AddRepository(); options.AddRepository(); options.AddRepository(); options.AddRepository(); diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs index 0299856341..0484676a94 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs @@ -3,7 +3,6 @@ using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; @@ -16,7 +15,6 @@ namespace Volo.CmsKit.EntityFrameworkCore [ConnectionStringName(CmsKitDbProperties.ConnectionStringName)] public interface ICmsKitDbContext : IEfCoreDbContext { - DbSet Contents { get; } DbSet Comments { get; } DbSet User { get; } DbSet Reactions { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs index cd03531448..4d8f86b823 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs @@ -24,8 +24,6 @@ namespace Volo.CmsKit.MongoDB public IMongoCollection CmsUsers => Collection(); public IMongoCollection Ratings => Collection(); - - public IMongoCollection Contents => Collection(); public IMongoCollection Tags => Collection(); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs index 2a542472d2..8585f988f9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs @@ -47,11 +47,6 @@ namespace Volo.CmsKit.MongoDB x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Ratings"; }); - builder.Entity(x => - { - x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Contents"; - }); - builder.Entity(x => { x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Tags"; diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs index 11e3a0eb86..f18e92e2ba 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs @@ -4,11 +4,9 @@ using Volo.Abp.MongoDB; using Volo.Abp.Users.MongoDB; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.MongoDB.Blogs; using Volo.CmsKit.MongoDB.Comments; -using Volo.CmsKit.MongoDB.Contents; using Volo.CmsKit.MongoDB.MediaDescriptors; using Volo.CmsKit.MongoDB.Pages; using Volo.CmsKit.MongoDB.Ratings; @@ -38,7 +36,6 @@ namespace Volo.CmsKit.MongoDB options.AddRepository(); options.AddRepository(); options.AddRepository(); - options.AddRepository(); options.AddRepository(); options.AddRepository(); options.AddRepository(); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Contents/MongoContentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Contents/MongoContentRepository.cs deleted file mode 100644 index fded228c16..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Contents/MongoContentRepository.cs +++ /dev/null @@ -1,80 +0,0 @@ -using JetBrains.Annotations; -using MongoDB.Driver.Linq; -using System; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Domain.Repositories.MongoDB; -using Volo.Abp.MongoDB; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.MongoDB.Contents -{ - public class MongoContentRepository : MongoDbRepository, IContentRepository - { - public MongoContentRepository(IMongoDbContextProvider dbContextProvider) : base( - dbContextProvider) - { - } - - public virtual Task GetAsync( - string entityType, - string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return GetAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken) - ); - } - - public virtual Task FindAsync( - string entityType, - string entityId, - Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return FindAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken) - ); - } - - public virtual Task DeleteAsync(string entityType, string entityId, Guid? tenantId = null, - CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return DeleteAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken)); - } - - public virtual async Task ExistsAsync([NotNull] string entityType, [NotNull] string entityId, - Guid? tenantId = null, CancellationToken cancellationToken = default) - { - Check.NotNullOrEmpty(entityType, nameof(entityType)); - Check.NotNullOrEmpty(entityId, nameof(entityId)); - - return await (await GetMongoQueryableAsync(cancellationToken)).AnyAsync(x => - x.EntityType == entityType && - x.EntityId == entityId && - x.TenantId == tenantId, - cancellationToken: GetCancellationToken(cancellationToken)); - } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs index 742d40dfc6..5110bca501 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs @@ -25,8 +25,6 @@ namespace Volo.CmsKit.MongoDB IMongoCollection Ratings { get; } - IMongoCollection Contents { get; } - IMongoCollection Tags { get; } IMongoCollection EntityTags { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Contents/ContentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Contents/ContentPublicAppService.cs deleted file mode 100644 index 995c99c2ed..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Contents/ContentPublicAppService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.Public.Contents -{ - public class ContentPublicAppService : CmsKitPublicAppServiceBase, IContentPublicAppService - { - protected IContentRepository ContentRepository { get; } - - public ContentPublicAppService(IContentRepository contentRepository) - { - ContentRepository = contentRepository; - } - - public virtual async Task GetAsync(GetContentInput input) - { - var entity = await ContentRepository.GetAsync( - input.EntityType, - input.EntityId, - CurrentTenant.Id); - - return ObjectMapper.Map(entity); - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs index 46dab5a9a1..b8684f2463 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs @@ -2,11 +2,9 @@ using Volo.Abp.AutoMapper; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Comments; -using Volo.CmsKit.Public.Contents; using Volo.CmsKit.Public.Pages; using Volo.CmsKit.Public.Ratings; using Volo.CmsKit.Ratings; @@ -29,8 +27,6 @@ namespace Volo.CmsKit.Public CreateMap(); - CreateMap(); - CreateMap(); CreateMap(MemberList.None); diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentAdminAppService_Tests.cs deleted file mode 100644 index 5c7e5969f1..0000000000 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentAdminAppService_Tests.cs +++ /dev/null @@ -1,142 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using NSubstitute; -using Shouldly; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Users; -using Volo.CmsKit.Admin.Contents; -using Xunit; - -namespace Volo.CmsKit.Contents -{ - public class ContentAdminAppService_Tests : CmsKitApplicationTestBase - { - private ICurrentUser _currentUser; - private readonly CmsKitTestData _data; - private readonly IContentAdminAppService _service; - public ContentAdminAppService_Tests() - { - _data = GetRequiredService(); - _service = GetRequiredService(); - } - - protected override void AfterAddApplication(IServiceCollection services) - { - _currentUser = Substitute.For(); - services.AddSingleton(_currentUser); - } - - [Fact] - public async Task ShouldGetListAsync() - { - var result = await _service.GetListAsync(new ContentGetListInput()); - - result.ShouldNotBeNull(); - result.Items.ShouldNotBeEmpty(); - result.Items.Count.ShouldBe(4); - result.Items.All(x => x.ShouldBeOfType() != null); - } - - [Fact] - public async Task ShouldGetAsync() - { - var result = await _service.GetAsync(_data.Content_1_Id); - - result.ShouldNotBeNull(); - result.ShouldBeOfType(); - result.ShouldNotBeNull(result.Value); - } - - [Fact] - public async Task ShouldCreateAsync() - { - var entityId = "1-2-3"; - var entityType = "My.Awesome.Blog"; - var value = "Some long content"; - - var created = await _service.CreateAsync(new ContentCreateDto - { - EntityId = entityId, - EntityType = entityType, - Value = value - }); - - created.Id.ShouldNotBe(Guid.Empty); - - var content = await _service.GetAsync(created.Id); - - content.ShouldNotBeNull(); - content.EntityType.ShouldBe(entityType); - } - - [Fact] - public async Task ShouldNotCreateWithSameParametersAsync() - { - var entityTtype = "My.Awesome.Book"; - var entityId = "1"; - - await _service.CreateAsync(new ContentCreateDto - { - EntityId = entityId, - EntityType = entityTtype, - Value = "Some long content" - }); - - await Should.ThrowAsync(async () => - await _service.CreateAsync(new ContentCreateDto - { - EntityId = entityId, - EntityType = entityTtype, - Value = "Yet another long content" - }) - ); - } - - [Fact] - public async Task ShouldUpdateAsync() - { - string newValue = "Newly created fresh value"; - var updateDto = new ContentUpdateDto - { - Value = newValue - }; - - await _service.UpdateAsync(_data.Content_1_Id, updateDto); - - var content = await _service.GetAsync(_data.Content_1_Id); - content.ShouldNotBeNull(); - content.Value.ShouldBe(newValue); - } - - [Fact] - public async Task ShouldDeleteAsync() - { - await _service.DeleteAsync(_data.Content_2_Id); - - await Should.ThrowAsync(async () => await _service.GetAsync(_data.Content_2_Id)); - } - - [Fact] - public async Task ShouldNotThrowEntityNotFoundExceptionWhileDeletingAlreadyDeletedAsync() - { - await _service.DeleteAsync(_data.Content_2_Id); - - await Should.NotThrowAsync(async () => - await _service.DeleteAsync(_data.Content_2_Id)); - } - - [Fact] - public async Task ShouldGetByEntityAsync() - { - var entity = await _service.GetAsync(_data.Content_1_EntityType, _data.Content_1_EntityId); - - entity.ShouldNotBeNull(); - entity.EntityId.ShouldBe(_data.Content_1_EntityId); - entity.EntityType.ShouldBe(_data.Content_1_EntityType); - } - } -} diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Contents/ContentRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Contents/ContentRepository_Test.cs deleted file mode 100644 index 72f0b47485..0000000000 --- a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Contents/ContentRepository_Test.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.EntityFrameworkCore.Contents -{ - public class ContentRepository_Test : ContentRepository_Tests - { - - } -} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Contents/ContentRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Contents/ContentRepository_Test.cs deleted file mode 100644 index bb467a4844..0000000000 --- a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Contents/ContentRepository_Test.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Volo.CmsKit.Contents; -using Xunit; - -namespace Volo.CmsKit.MongoDB.Contents -{ - [Collection(MongoTestCollection.Name)] - public class ContentRepository_Test : ContentRepository_Tests - { - - } -} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 504961cf0c..e8c5155377 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -2,19 +2,16 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; using Volo.Abp.BlobStoring; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Repositories; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Abp.Users; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; @@ -33,7 +30,6 @@ namespace Volo.CmsKit private readonly ReactionManager _reactionManager; private readonly IRatingRepository _ratingRepository; private readonly ICurrentTenant _currentTenant; - private readonly IContentRepository _contentRepository; private readonly EntityTagManager _entityTagManager; private readonly TagManager _tagManager; private readonly ITagRepository _tagRepository; @@ -57,7 +53,6 @@ namespace Volo.CmsKit ReactionManager reactionManager, IRatingRepository ratingRepository, ICurrentTenant currentTenant, - IContentRepository contentRepository, TagManager tagManager, ITagRepository tagRepository, IEntityTagRepository entityTagRepository, @@ -80,7 +75,6 @@ namespace Volo.CmsKit _reactionManager = reactionManager; _ratingRepository = ratingRepository; _currentTenant = currentTenant; - _contentRepository = contentRepository; _tagManager = tagManager; _tagRepository = tagRepository; _entityTagManager = entityTagManager; @@ -111,8 +105,6 @@ namespace Volo.CmsKit await SeedRatingsAsync(); - await SeedContentsAsync(); - await SeedTagsAsync(); await SeedPagesAsync(); @@ -264,37 +256,6 @@ namespace Volo.CmsKit )); } - private async Task SeedContentsAsync() - { - var content1 = new Content( - _cmsKitTestData.Content_1_Id, - _cmsKitTestData.Content_1_EntityType, - _cmsKitTestData.Content_1_EntityId, - _cmsKitTestData.Content_1 - ); - - var content2 = new Content( - _cmsKitTestData.Content_2_Id, - _cmsKitTestData.Content_2_EntityType, - _cmsKitTestData.Content_2_EntityId, - _cmsKitTestData.Content_2 - ); - - var content3 = new Content( - Guid.NewGuid(), - "deleted_entity_type", - "deleted_entity_id", - "Content" - ) - { - IsDeleted = true, - }; - - await _contentRepository.InsertAsync(content1); - await _contentRepository.InsertAsync(content2); - await _contentRepository.InsertAsync(content3); - } - private async Task SeedTagsAsync() { var created1 = await _tagRepository.InsertAsync( diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Contents/ContentRepository_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Contents/ContentRepository_Tests.cs deleted file mode 100644 index c5b166551e..0000000000 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Contents/ContentRepository_Tests.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Modularity; -using Xunit; - -namespace Volo.CmsKit.Contents -{ - public abstract class ContentRepository_Tests : CmsKitTestBase - where TStartupModule : IAbpModule - { - private readonly CmsKitTestData _cmsKitTestData; - private readonly IContentRepository _contentRepository; - - protected ContentRepository_Tests() - { - _cmsKitTestData = GetRequiredService(); - _contentRepository = GetRequiredService(); - } - - [Theory] - [InlineData("Lyrics", "1", "First things first")] - [InlineData("LyricsAlso", "2", "Second thing second")] - public async Task ShouldGetAsync(string entityType, string entityId, string contentStartsWith = null) - { - var content = await _contentRepository.GetAsync(entityType, entityId); - - content.ShouldNotBeNull(); - - if (contentStartsWith != null) - { - content.Value.ShouldStartWith(contentStartsWith); - } - } - - [Fact] - public async Task ShouldNotGetAsync() - { - Should.Throw( - async () - => - await _contentRepository.GetAsync("not_exist_entity", Guid.NewGuid().ToString())); - } - - [Fact] - public async Task ShouldFindAsync() - { - var content = - await _contentRepository.FindAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.Content_1_EntityId); - - content.ShouldNotBeNull(); - } - - [Fact] - public async Task ShouldNotFindAsync() - { - var content = await _contentRepository.FindAsync("not_exist_entity", Guid.NewGuid().ToString()); - - content.ShouldBeNull(); - } - } -} \ No newline at end of file From 0b34091a3f2a5ea112b6b077b2b83fd6bd33601a Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 13:39:03 +0300 Subject: [PATCH 042/101] remove content related classes --- .../Pages/Index.cshtml | 6 - .../CmsKit/Admin/Contents/ContentCreateDto.cs | 23 ---- .../Volo/CmsKit/Admin/Contents/ContentDto.cs | 15 --- .../Admin/Contents/ContentGetListDto.cs | 13 -- .../Admin/Contents/ContentGetListInput.cs | 10 -- .../CmsKit/Admin/Contents/ContentUpdateDto.cs | 15 --- .../Admin/Contents/IContentAdminAppService.cs | 19 --- .../Admin/Contents/ContentAdminController.cs | 71 ----------- .../Pages/CmsKit/Pages/Update.cshtml | 35 +++++- .../Pages/CmsKit/Pages/Update.cshtml.cs | 9 +- .../Pages/CmsKit/Pages/update.js | 114 ++++++++++++------ .../Volo/CmsKit/Public/Contents/ContentDto.cs | 11 -- .../CmsKit/Public/Contents/GetContentInput.cs | 12 -- .../Contents/IContentPublicAppService.cs | 10 -- .../Public/Contents/ContentController.cs | 29 ----- .../Components/Blogs/BlogPost/Default.cshtml | 2 - .../Contents/ContentViewComponent.cs | 59 --------- .../Shared/Components/Contents/Default.cshtml | 3 - 18 files changed, 114 insertions(+), 342 deletions(-) delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentCreateDto.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentDto.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListDto.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListInput.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentUpdateDto.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/ContentDto.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/GetContentInput.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/IContentPublicAppService.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Contents/ContentController.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/ContentViewComponent.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/Default.cshtml diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml index 885034b055..31267b61aa 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml @@ -8,7 +8,6 @@ @using Volo.CmsKit.GlobalFeatures @using Volo.CmsKit.Pages @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting -@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Tags @@ -31,11 +30,6 @@ - @if (GlobalFeatureManager.Instance.IsEnabled()) - { - @await Component.InvokeAsync(typeof(ContentViewComponent), new {entityType = "quote", entityId = "1"}) - } - @if (GlobalFeatureManager.Instance.IsEnabled()) { @await Component.InvokeAsync(typeof(TagViewComponent), new diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentCreateDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentCreateDto.cs deleted file mode 100644 index 6832d26bd3..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentCreateDto.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Volo.Abp.Validation; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.Admin.Contents -{ - [Serializable] - public class ContentCreateDto - { - [Required] - [DynamicMaxLength(typeof(ContentConsts), nameof(ContentConsts.MaxEntityTypeLength))] - public string EntityType { get; set; } - - [Required] - [DynamicMaxLength(typeof(ContentConsts), nameof(ContentConsts.MaxEntityIdLength))] - public string EntityId { get; set; } - - [Required] - [DynamicMaxLength(typeof(ContentConsts), nameof(ContentConsts.MaxValueLength))] - public string Value { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentDto.cs deleted file mode 100644 index 8cfb2e2e7c..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using Volo.Abp.Application.Dtos; - -namespace Volo.CmsKit.Admin.Contents -{ - [Serializable] - public class ContentDto : EntityDto - { - public string EntityType { get; set; } - - public string EntityId { get; set; } - - public string Value { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListDto.cs deleted file mode 100644 index ba44253ae9..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using Volo.Abp.Application.Dtos; - -namespace Volo.CmsKit.Admin.Contents -{ - [Serializable] - public class ContentGetListDto : EntityDto - { - public string EntityType { get; set; } - - public string EntityId { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListInput.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListInput.cs deleted file mode 100644 index fbca53a7b9..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentGetListInput.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using Volo.Abp.Application.Dtos; - -namespace Volo.CmsKit.Admin.Contents -{ - [Serializable] - public class ContentGetListInput : PagedAndSortedResultRequestDto - { - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentUpdateDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentUpdateDto.cs deleted file mode 100644 index c59075cc8d..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/ContentUpdateDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using Volo.Abp.Validation; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.Admin.Contents -{ - [Serializable] - public class ContentUpdateDto - { - [Required] - [DynamicMaxLength(typeof(ContentConsts), nameof(ContentConsts.MaxValueLength))] - public string Value { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs deleted file mode 100644 index 52bd07aa86..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Contents/IContentAdminAppService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Threading.Tasks; -using Volo.Abp.Application.Services; -using Volo.CmsKit.Admin.Contents; - -namespace Volo.CmsKit.Admin.Contents -{ - public interface IContentAdminAppService - : ICrudAppService< - ContentDto, - ContentGetListDto, - Guid, - ContentGetListInput, - ContentCreateDto, - ContentUpdateDto> - { - Task GetAsync(string entityType, string entityId); - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs deleted file mode 100644 index 4e3a56a8e2..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Contents/ContentAdminController.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using System; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.GlobalFeatures; -using Volo.CmsKit.Admin.Contents; -using Volo.CmsKit.GlobalFeatures; -using Volo.CmsKit.Permissions; - -namespace Volo.CmsKit.Admin.Contents -{ - [Authorize(CmsKitAdminPermissions.Contents.Default)] - [RequiresGlobalFeature(typeof(ContentsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] - [Area("cms-kit")] - [Route("api/cms-kit-admin/contents")] - public class ContentAdminController : CmsKitAdminController, IContentAdminAppService - { - protected IContentAdminAppService ContentAdminAppService { get; } - - public ContentAdminController(IContentAdminAppService contentAdminAppService) - { - ContentAdminAppService = contentAdminAppService; - } - - [HttpPost] - [Authorize(CmsKitAdminPermissions.Contents.Create)] - public Task CreateAsync(ContentCreateDto input) - { - return ContentAdminAppService.CreateAsync(input); - } - - [HttpDelete("{id}")] - [Authorize(CmsKitAdminPermissions.Contents.Delete)] - public Task DeleteAsync(Guid id) - { - return ContentAdminAppService.DeleteAsync(id); - } - - [HttpGet("{id}")] - [Authorize(CmsKitAdminPermissions.Contents.Default)] - public Task GetAsync(Guid id) - { - return ContentAdminAppService.GetAsync(id); - } - - [HttpGet] - [Authorize(CmsKitAdminPermissions.Contents.Default)] - public Task> GetListAsync(ContentGetListInput input) - { - return ContentAdminAppService.GetListAsync(input); - } - - [HttpPut] - [Authorize(CmsKitAdminPermissions.Contents.Update)] - public Task UpdateAsync(Guid id, ContentUpdateDto input) - { - return ContentAdminAppService.UpdateAsync(id, input); - } - - [HttpGet] - [Route("{entityType}/{entityId}")] - [Authorize(CmsKitAdminPermissions.Contents.Default)] - public Task GetAsync(string entityType, string entityId) - { - return ContentAdminAppService.GetAsync(entityType, entityId); - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml index c79ff8b72c..1b35e6c913 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml @@ -1,5 +1,9 @@ @page "{Id}" +@using System.Globalization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy +@using Volo.CmsKit.Admin.Web.Bundles @using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Admin.Web.Pages @@ -15,19 +19,38 @@ @section scripts { - + + + + + + +} + +@section styles { + + + } - - +
+ + + + + - + - - +
+
+
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs index c80714aa91..c21f8f587c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs @@ -46,14 +46,17 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages [AutoMap(typeof(UpdatePageInputDto), ReverseMap = true)] public class UpdatePageViewModel { - [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] [Required] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] public string Title { get; set; } - [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] [Required] - [DynamicFormIgnore] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] public string Slug { get; set; } + + [HiddenInput] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxSlugLength))] + public string Content { get; set; } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js index 3f8b971866..7b9cb10570 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js @@ -4,9 +4,6 @@ var $formUpdate = $('#form-page-update'); var $buttonSubmit = $('#button-page-update'); - var $pageContentInput = $('#ViewModel_Value'); - var $pageIdInput = $('#Id'); - var $contentIdInput = $('#ViewModel_Id'); $formUpdate.on('submit', function (e) { e.preventDefault(); @@ -17,7 +14,9 @@ $formUpdate.ajaxSubmit({ success: function (result) { - submitEntityContent(); + abp.notify.success(l('SuccessfullySaved')); + abp.ui.clearBusy(); + location.href = "/CmsKit/Pages/"; } }); } @@ -28,38 +27,83 @@ $formUpdate.submit(); }); - function submitEntityContent() { - - var contentId = $contentIdInput.val(); - var pageId = $pageIdInput.val(); - var contentValue = $pageContentInput.val(); - - if (contentId) { - volo.cmsKit.admin.contents.contentAdmin - .update(contentId, - { - value: contentValue - }) - .then(function (result) { - finishSaving(result); - }); - } - else { - volo.cmsKit.admin.contents.contentAdmin - .create({ - entityType: 'Page', - entityId: pageId, - value: contentValue - }) - .then(function (result) { - finishSaving(result); - }); - } + // ----------------------------------- + function getUppyHeaders() { + var headers = {}; + headers[abp.security.antiForgery.tokenHeaderName] = abp.security.antiForgery.getToken(); + + return headers; } - function finishSaving(result) { - abp.notify.success(l('SuccessfullySaved')); - abp.ui.clearBusy(); - location.href = "/CmsKit/Pages/"; + var fileUploadUri = "/api/cms-kit-admin/media/page"; + var fileUriPrefix = "/api/cms-kit/media/"; + + var editorDataKey = "tuiEditor"; + + initAllEditors(); + + function initAllEditors() { + $('.content-editor').each(function (i, item) { + initEditor(item); + }); + } + + function initEditor(element) { + var $editorContainer = $(element); + var inputName = $editorContainer.data('input-id'); + var $editorInput = $('#' + inputName); + var initialValue = $editorInput.val(); + + var editor = $editorContainer.tuiEditor({ + usageStatistics: false, + useCommandShortcut: true, + initialValue: initialValue, + previewStyle: 'tab', + height: "25em", + minHeight: "25em", + initialEditType: initialValue ? 'wysiwyg' : 'markdown', + language: $editorContainer.data("language"), + hooks: { + addImageBlobHook: uploadFile, + }, + events: { + change: function (_val) { + $editorInput.val(editor.getHtml()); + $editorInput.trigger("change"); + } + } + }).data(editorDataKey); + } + + function uploadFile(blob, callback, source) { + var UPPY_OPTIONS = { + endpoint: fileUploadUri, + formData: true, + fieldName: "file", + method: "post", + headers: getUppyHeaders() + }; + + var UPPY = Uppy.Core().use(Uppy.XHRUpload, UPPY_OPTIONS); + + UPPY.reset(); + + UPPY.addFile({ + id: "content-file", + name: blob.name, + type: blob.type, + data: blob, + }); + + UPPY.upload().then((result) => { + if (result.failed.length > 0) { + abp.message.error("File upload failed"); + } else { + var mediaDto = result.successful[0].response.body; + var fileUrl = (fileUriPrefix + mediaDto.id); + + callback(fileUrl, mediaDto.name); + } + }); } }); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/ContentDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/ContentDto.cs deleted file mode 100644 index f11b4c8681..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/ContentDto.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using Volo.Abp.Application.Dtos; - -namespace Volo.CmsKit.Public.Contents -{ - [Serializable] - public class ContentDto : EntityDto - { - public string Value { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/GetContentInput.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/GetContentInput.cs deleted file mode 100644 index 26a127e105..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/GetContentInput.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Volo.CmsKit.Public.Contents -{ - [Serializable] - public class GetContentInput - { - public string EntityType { get; set; } - - public string EntityId { get; set; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/IContentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/IContentPublicAppService.cs deleted file mode 100644 index df8b07cfce..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Contents/IContentPublicAppService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using Volo.CmsKit.Contents; - -namespace Volo.CmsKit.Public.Contents -{ - public interface IContentPublicAppService - { - Task GetAsync(GetContentInput input); - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Contents/ContentController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Contents/ContentController.cs deleted file mode 100644 index 9ba368f03d..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Contents/ContentController.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp; -using Volo.Abp.GlobalFeatures; -using Volo.CmsKit.Contents; -using Volo.CmsKit.GlobalFeatures; - -namespace Volo.CmsKit.Public.Contents -{ - [RequiresGlobalFeature(typeof(ContentsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] - [Area("cms-kit")] - [Route("api/cms-kit-public/contents")] - public class ContentController : CmsKitControllerBase, IContentPublicAppService - { - protected IContentPublicAppService ContentAppService { get; } - - public ContentController(IContentPublicAppService contentAppService) - { - ContentAppService = contentAppService; - } - - [HttpGet] - public virtual Task GetAsync(GetContentInput input) - { - return ContentAppService.GetAsync(input); - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml index 76d1487861..0ed8987d72 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml @@ -1,6 +1,4 @@ @model Volo.CmsKit.Public.Blogs.BlogPostPublicDto -@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents -@using Volo.Abp.AspNetCore.Mvc.UI.Layout @using Volo.CmsKit.Localization @using Microsoft.Extensions.Localization diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/ContentViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/ContentViewComponent.cs deleted file mode 100644 index 70baaf4436..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/ContentViewComponent.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.Domain.Entities; -using Volo.CmsKit.Public.Contents; -using Volo.CmsKit.Web.Contents; - -namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents -{ - [ViewComponent(Name = "CmsContent")] - public class ContentViewComponent : AbpViewComponent - { - private readonly IContentRenderer contentRenderer; - private readonly IContentPublicAppService contentAppService; - - public ContentViewComponent( - IContentRenderer contentRenderer, - IContentPublicAppService contentAppService) - { - this.contentRenderer = contentRenderer; - this.contentAppService = contentAppService; - } - - public virtual async Task InvokeAsync( - string entityType, - string entityId) - { - var content = string.Empty; - - try - { - var contentDto = await contentAppService.GetAsync(new GetContentInput - { - EntityId = entityId, - EntityType = entityType - }); - - content = contentDto.Value; - } - catch (EntityNotFoundException e) - { - // ContentDto can be null, we will render empty content. - } - - var viewModel = new ContentViewModel - { - Value = await contentRenderer.RenderAsync(content) - }; - - return View("~/Pages/CmsKit/Shared/Components/Contents/Default.cshtml", viewModel); - } - - public class ContentViewModel - { - public string Value { get; set; } - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/Default.cshtml deleted file mode 100644 index 0f1ddedfe5..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Contents/Default.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents.ContentViewComponent.ContentViewModel - -@Html.Raw(Model.Value) From 3daf4a22f81dafd082234653df5674827bca23c9 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 13:41:33 +0300 Subject: [PATCH 043/101] update validator setting --- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js index 7b9cb10570..1dd4734150 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js @@ -5,6 +5,8 @@ var $formUpdate = $('#form-page-update'); var $buttonSubmit = $('#button-page-update'); + $formUpdate.data('validator').settings.ignore = ":hidden, [contenteditable='true']:not([name]), .tui-popup-wrapper"; + $formUpdate.on('submit', function (e) { e.preventDefault(); From cf8986a13d4fcef4bd784c6754171c78ace6fac9 Mon Sep 17 00:00:00 2001 From: Zony Date: Tue, 2 Mar 2021 21:21:32 +0800 Subject: [PATCH 044/101] Improve the RabbitMQ documentation. --- docs/en/Background-Jobs-RabbitMq.md | 20 +++++++++++++++++ ...tributed-Event-Bus-RabbitMQ-Integration.md | 22 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/en/Background-Jobs-RabbitMq.md b/docs/en/Background-Jobs-RabbitMq.md index 2ee478ed17..16b8b0981a 100644 --- a/docs/en/Background-Jobs-RabbitMq.md +++ b/docs/en/Background-Jobs-RabbitMq.md @@ -66,6 +66,26 @@ Defining multiple connections is allowed. In this case, you can use different co } ```` +If you need to connect to the RabbitMQ cluster, you can use the `;` character to separate the host names. + +**Example: Connect to the RabbitMQ cluster** + +```json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123;234.234.234.234" + } + }, + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName" + } + } +} +``` + #### AbpRabbitMqOptions `AbpRabbitMqOptions` class can be used to configure the connection strings for the RabbitMQ. You can configure this options inside the `ConfigureServices` of your [module](Module-Development-Basics.md). diff --git a/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md index 9587a111bf..3d99e1e3cf 100644 --- a/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md +++ b/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md @@ -90,7 +90,7 @@ You can use any of the [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dot **Example: Specify the connection port** -````csharp +````json { "RabbitMQ": { "Connections": { @@ -103,6 +103,26 @@ You can use any of the [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dot } ```` +If you need to connect to the RabbitMQ cluster, you can use the `;` character to separate the host names. + +**Example: Connect to the RabbitMQ cluster** + +```json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123;234.234.234.234" + } + }, + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName" + } + } +} +``` + ### The Options Classes `AbpRabbitMqOptions` and `AbpRabbitMqEventBusOptions` classes can be used to configure the connection strings and event bus options for the RabbitMQ. From d43370e0fb3a12847f83aa3f0a1c2be7439eb75f Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 2 Mar 2021 16:40:16 +0300 Subject: [PATCH 045/101] make url and rootNamespace optional for api config --- npm/ng-packs/packages/core/src/lib/models/environment.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/models/environment.ts b/npm/ng-packs/packages/core/src/lib/models/environment.ts index b29f0d338d..da04384cab 100644 --- a/npm/ng-packs/packages/core/src/lib/models/environment.ts +++ b/npm/ng-packs/packages/core/src/lib/models/environment.ts @@ -21,12 +21,11 @@ export interface ApplicationInfo { export type ApiConfig = { [key: string]: string; url: string; -} & Partial<{ rootNamespace: string; -}>; +}; export interface Apis { - [key: string]: ApiConfig; + [key: string]: Partial; default: ApiConfig; } From 55fa6468744570e743cb1167509b1aba871a25ac Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 2 Mar 2021 16:40:35 +0300 Subject: [PATCH 046/101] remove url from dev-app api configs --- npm/ng-packs/apps/dev-app/src/environments/environment.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.ts index 87ca8d1447..771698e394 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.ts @@ -23,23 +23,18 @@ export const environment = { rootNamespace: 'MyCompanyName.MyProjectName', }, AbpFeatureManagement: { - url: 'https://localhost:44305', rootNamespace: 'Volo.Abp', }, AbpPermissionManagement: { - url: 'https://localhost:44305', rootNamespace: 'Volo.Abp.PermissionManagement', }, AbpTenantManagement: { - url: 'https://localhost:44305', rootNamespace: 'Volo.Abp.TenantManagement', }, AbpIdentity: { - url: 'https://localhost:44305', rootNamespace: 'Volo.Abp', }, AbpSettingManagement: { - url: 'https://localhost:44305', rootNamespace: 'Volo.Abp.SettingManagement', }, }, From 3b633f631e818532853e2983eb003f1628ecfc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 2 Mar 2021 16:44:27 +0300 Subject: [PATCH 047/101] Static property must be initialized in static constructor. --- .../Configuration/AbpApiProxyScriptingOptions.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs index 21bc6783bb..76c7dc74f5 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs @@ -10,10 +10,8 @@ namespace Volo.Abp.Http.ProxyScripting.Configuration public static Func PropertyNameGenerator { get; set; } - public AbpApiProxyScriptingOptions() + static AbpApiProxyScriptingOptions() { - Generators = new Dictionary(); - PropertyNameGenerator = propertyInfo => { var jsonPropertyNameAttribute = propertyInfo.GetSingleAttributeOrNull(true); @@ -33,5 +31,10 @@ namespace Volo.Abp.Http.ProxyScripting.Configuration return null; }; } + + public AbpApiProxyScriptingOptions() + { + Generators = new Dictionary(); + } } } \ No newline at end of file From dc83964fe829ba7662cc8c499e0d4efec8e329c6 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 2 Mar 2021 16:57:27 +0300 Subject: [PATCH 048/101] deprecate legacy object extensions types --- .../lib/models/internal/object-extensions.ts | 143 ------------------ 1 file changed, 143 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/internal/object-extensions.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/internal/object-extensions.ts index 448183b8a0..ea8a9dad8f 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/internal/object-extensions.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/models/internal/object-extensions.ts @@ -106,146 +106,3 @@ export interface PropContributors { createForm: PropContributorCallbacks>; editForm: PropContributorCallbacks>; } - -/** - * @deprecated To be deleted in v4.2. - */ -export interface Config { - objectExtensions: Item; -} - -/** - * @deprecated Use ObjectExtensionsDto. To be deleted in v4.2. - */ -export interface Item { - modules: Modules; - enums: Enums; -} - -/** - * @deprecated Use Record. To be deleted in v4.2. - */ -export type Modules = Configuration; - -/** - * @deprecated Use ModuleExtensionDto. To be deleted in v4.2. - */ -export interface Module { - configuration: Configuration; - entities: Entities; -} - -/** - * @deprecated Use Record. To be deleted in v4.2. - */ -export type Entities = Configuration; - -/** - * @deprecated Use EntityExtensionDto. To be deleted in v4.2. - */ -export interface Entity { - configuration: Configuration; - properties: Properties; -} - -/** - * @deprecated Use Record. To be deleted in v4.2. - */ -export type Properties = Configuration; - -/** - * @deprecated Use ExtensionPropertyDto. To be deleted in v4.2. - */ -export interface Property { - type: string; - typeSimple: ePropType; - displayName: DisplayName | null; - api: Api; - ui: Ui; - attributes: Attribute[]; - configuration: Configuration; - defaultValue?: any; -} - -/** - * @deprecated Use LocalizableStringDto. To be deleted in v4.2. - */ -export interface DisplayName { - name: string; - resource: string; -} - -/** - * @deprecated Use ExtensionPropertyApiDto. To be deleted in v4.2. - */ -export interface Api { - onGet: ApiConfig; - onCreate: ApiConfig; - onUpdate: ApiConfig; -} - -/** - * @deprecated Use ExtensionPropertyApiCreateDto. To be deleted in v4.2. - */ -export interface ApiConfig { - isAvailable: boolean; -} - -/** - * @deprecated Use ExtensionPropertyUiDto. To be deleted in v4.2. - */ -export interface Ui { - onTable: UiPropConfig; - onCreateForm: UiFormConfig; - onEditForm: UiFormConfig; -} - -/** - * @deprecated Use ExtensionPropertyUiTableDto. To be deleted in v4.2. - */ -export interface UiPropConfig { - isSortable: boolean; - isVisible: boolean; -} - -/** - * @deprecated Use ExtensionPropertyUiFormDto. To be deleted in v4.2. - */ -export interface UiFormConfig { - isVisible: boolean; -} - -/** - * @deprecated Use ExtensionPropertyAttributeDto. To be deleted in v4.2. - */ -export interface Attribute { - typeSimple: string; - config: Configuration; -} - -/** - * @deprecated To be deleted in v4.2. - */ -export type Configuration = Record; - -/** - * @deprecated Use Record. To be deleted in v4.2. - */ -export type Enums = Record; - -/** - * @deprecated Use ExtensionEnumDto. To be deleted in v4.2. - */ -export interface Enum { - fields: EnumMember[]; - localizationResource?: string; - transformed?: any; -} - -/** - * @deprecated Use ExtensionEnumFieldDto. To be deleted in v4.2. - */ -export interface EnumMember { - name: string; - value: any; -} From bce5c1660dd94a16934afb6b482585b07951e245 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 2 Mar 2021 17:00:45 +0300 Subject: [PATCH 049/101] make ApiConfig interface instead of type literal --- npm/ng-packs/packages/core/src/lib/models/environment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/models/environment.ts b/npm/ng-packs/packages/core/src/lib/models/environment.ts index da04384cab..dc5fab9ef7 100644 --- a/npm/ng-packs/packages/core/src/lib/models/environment.ts +++ b/npm/ng-packs/packages/core/src/lib/models/environment.ts @@ -18,11 +18,11 @@ export interface ApplicationInfo { logoUrl?: string; } -export type ApiConfig = { +export interface ApiConfig { [key: string]: string; url: string; rootNamespace: string; -}; +} export interface Apis { [key: string]: Partial; From 17ad81cbd9301f6f7ebcaf6130830ee862deef7e Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 17:03:33 +0300 Subject: [PATCH 050/101] CmsKit - Remove required permissions from AbpAuthorizationException --- .../Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs index 83d36431c8..9d4c109698 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminAppServiceBase.cs @@ -33,11 +33,7 @@ namespace Volo.CmsKit.Admin } } - var exception = new AbpAuthorizationException(); - - exception.Data[nameof(policies)] = policies; - - throw exception; + throw new AbpAuthorizationException(); } } } From d0a52b1b1e16a717c864e77f3b0a8522c53d587c Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 2 Mar 2021 17:04:26 +0300 Subject: [PATCH 051/101] make rootNamespace optional again --- npm/ng-packs/packages/core/src/lib/models/environment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/models/environment.ts b/npm/ng-packs/packages/core/src/lib/models/environment.ts index dc5fab9ef7..46596685b0 100644 --- a/npm/ng-packs/packages/core/src/lib/models/environment.ts +++ b/npm/ng-packs/packages/core/src/lib/models/environment.ts @@ -21,7 +21,7 @@ export interface ApplicationInfo { export interface ApiConfig { [key: string]: string; url: string; - rootNamespace: string; + rootNamespace?: string; } export interface Apis { From 272361159d7ee4e0d7fb1b41cfddbf95a03fdc0f Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 2 Mar 2021 17:04:45 +0300 Subject: [PATCH 052/101] update environment service to handle optional urls --- .../src/lib/services/environment.service.ts | 9 +++--- .../src/lib/tests/environment.service.spec.ts | 31 +++++++++++++------ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/environment.service.ts b/npm/ng-packs/packages/core/src/lib/services/environment.service.ts index 2062294b7b..10d7664acb 100644 --- a/npm/ng-packs/packages/core/src/lib/services/environment.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/environment.service.ts @@ -4,6 +4,9 @@ import { map } from 'rxjs/operators'; import { Apis, Environment } from '../models/environment'; import { InternalStore } from '../utils/internal-store-utils'; +const mapToApiUrl = (key: string) => (apis: Apis) => + (apis[key] || apis.default).url || apis.default.url; + @Injectable({ providedIn: 'root' }) export class EnvironmentService { private readonly store = new InternalStore({} as Environment); @@ -21,13 +24,11 @@ export class EnvironmentService { } getApiUrl(key?: string) { - return (this.store.state.apis[key || 'default'] || this.store.state.apis.default).url; + return mapToApiUrl(key)(this.store.state.apis); } getApiUrl$(key?: string) { - return this.store - .sliceState(state => state.apis) - .pipe(map((apis: Apis) => (apis[key || 'default'] || apis.default).url)); + return this.store.sliceState(state => state.apis).pipe(map(mapToApiUrl(key))); } setState(environment: Environment) { diff --git a/npm/ng-packs/packages/core/src/lib/tests/environment.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/environment.service.spec.ts index fe9f50a546..95c2b58a6c 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/environment.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/environment.service.spec.ts @@ -1,3 +1,4 @@ +import { waitForAsync } from '@angular/core/testing'; import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; import { Environment } from '../models'; import { EnvironmentService } from '../services'; @@ -17,6 +18,7 @@ export const ENVIRONMENT_DATA = ({ other: { url: 'https://localhost:44306', }, + yetAnother: {}, }, localization: { defaultResourceName: 'MyProjectName', @@ -39,19 +41,28 @@ describe('ConfigState', () => { }); describe('#getEnvironment', () => { - it('should return ENVIRONMENT_DATA', () => { - expect(environment.getEnvironment()).toEqual(ENVIRONMENT_DATA); - environment.getEnvironment$().subscribe(data => expect(data).toEqual(ENVIRONMENT_DATA)); - }); + it( + 'should return ENVIRONMENT_DATA', + waitForAsync(() => { + expect(environment.getEnvironment()).toEqual(ENVIRONMENT_DATA); + environment.getEnvironment$().subscribe(data => expect(data).toEqual(ENVIRONMENT_DATA)); + }), + ); }); describe('#getApiUrl', () => { - it('should return api url', () => { - expect(environment.getApiUrl()).toEqual(ENVIRONMENT_DATA.apis.default.url); - environment - .getApiUrl$('other') - .subscribe(data => expect(data).toEqual(ENVIRONMENT_DATA.apis.other.url)); - }); + it( + 'should return api url', + waitForAsync(() => { + expect(environment.getApiUrl()).toEqual(ENVIRONMENT_DATA.apis.default.url); + environment + .getApiUrl$('other') + .subscribe(data => expect(data).toEqual(ENVIRONMENT_DATA.apis.other.url)); + environment + .getApiUrl$('yetAnother') + .subscribe(data => expect(data).toEqual(ENVIRONMENT_DATA.apis.default.url)); + }), + ); }); // TODO: create permission.service.spec.ts From b7217ab9127be8184e32c718a01e39c406b56630 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Mar 2021 17:06:43 +0300 Subject: [PATCH 053/101] CmsKit - Add Create & Update policies to delete Media & Tags --- .../Admin/CmsKitAdminApplicationModule.cs | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index 95dbe44a04..17c242755e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -46,9 +46,21 @@ namespace Volo.CmsKit.Admin new TagEntityTypeDefiniton( BlogPostConsts.EntityType, LocalizableString.Create("BlogPost"), - new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, - new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, - new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update })); + createPolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update + }, + updatePolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update + }, + deletePolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update + })); } }); @@ -61,8 +73,17 @@ namespace Volo.CmsKit.Admin options.EntityTypes.AddIfNotContains( new MediaDescriptorDefinition( BlogPostConsts.EntityType, - createPolicies: new[] { CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, - deletePolicies: new[] { CmsKitAdminPermissions.BlogPosts.Delete })); + createPolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update + }, + deletePolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update, + CmsKitAdminPermissions.BlogPosts.Delete + })); } if (GlobalFeatureManager.Instance.IsEnabled()) @@ -70,8 +91,17 @@ namespace Volo.CmsKit.Admin options.EntityTypes.AddIfNotContains( new MediaDescriptorDefinition( PageConsts.EntityType, - createPolicies: new[] { CmsKitAdminPermissions.Pages.Create, CmsKitAdminPermissions.Pages.Update }, - deletePolicies: new[] { CmsKitAdminPermissions.Pages.Delete })); + createPolicies: new[] + { + CmsKitAdminPermissions.Pages.Create, + CmsKitAdminPermissions.Pages.Update + }, + deletePolicies: new[] + { + CmsKitAdminPermissions.Pages.Create, + CmsKitAdminPermissions.Pages.Update, + CmsKitAdminPermissions.Pages.Delete + })); } }); } From 12da9394e6932c972d50c6693da4bdc523ca98df Mon Sep 17 00:00:00 2001 From: Zony Date: Tue, 2 Mar 2021 22:47:03 +0800 Subject: [PATCH 054/101] Improve RabbitMQ Chinese documentation. --- ...tributed-Event-Bus-RabbitMQ-Integration.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md index 2a1810e309..ab7cb68bd7 100644 --- a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md +++ b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md @@ -103,6 +103,26 @@ } ```` +如果需要连接到 RabbitMQ 集群,你可以指定多个 HostName。 + +**示例: 连接到 RabbitMQ 集群** + +```json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123;234.234.234.234" + } + }, + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName" + } + } +} +``` + ### 选项类 `AbpRabbitMqOptions` 和 `AbpRabbitMqEventBusOptions` 类用于配置RabbitMQ的连接字符串和事件总线选项. From 252f7c9a32c485d6c8014b76ba00b14710540c21 Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Tue, 2 Mar 2021 17:48:59 +0300 Subject: [PATCH 055/101] Add missing localizations --- .../AbpIoLocalization/Admin/Localization/Resources/en.json | 6 ++++-- .../AbpIoLocalization/Admin/Localization/Resources/tr.json | 5 ++++- .../Community/Localization/Resources/en.json | 4 +++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index c02e6e13de..0ada3327df 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -213,7 +213,9 @@ "Currency": "Currency", "Gateway": "Gateway", "State": "State", - "FailReason": "Fail reason" - + "FailReason": "Fail reason", + "ReIndexAllPosts": "ReIndex All Posts", + "ReIndexAllPostsConfirmationMessage": "Are you sure to reindex all posts?", + "SuccessfullyReIndexAllPosts": "Successfully reindex for all posts" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json index 1884b0025f..34ee392140 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json @@ -163,6 +163,9 @@ "Enum:ContentSource:2": "Video İçerik", "DeleteCoverImage": "Kapak Fotoğrafını Sil", "DeleteCoverImageConfirmationMessage": "Kapak fotoğrafını \"{0}\" isimli makale için silmek istediğinize emin misiniz?", - "DeleteCoverImageSuccessMessage": "Kapak fotoğrafı başarılı bir şekilde silinmiştir" + "DeleteCoverImageSuccessMessage": "Kapak fotoğrafı başarılı bir şekilde silinmiştir", + "ReIndexAllPosts": "Yeniden indeksle", + "ReIndexAllPostsConfirmationMessage": "Tüm gönderileri yeniden indeksleyeceğinizden emin misiniz?", + "SuccessfullyReIndexAllPosts": "Tüm gönderiler başarıyla yeniden indekslendi" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json index 9c1e434ac1..9c5ae26f89 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json @@ -136,6 +136,8 @@ "GitHubUserNameValidationMessage": "Your Github username can not include whitespace, please be sure your Github username is correct.", "PersonalSiteUrlValidationMessage": "Your personal site URL can not include whitespace, please be sure your personal site URL is correct.", "TwitterUserNameValidationMessage": "Your Twitter username can not include whitespace, please be sure your Twitter username is correct.", - "LinkedinUrlValidationMessage": "Your Linkedin URL can not include whitespace, please be sure your Linkedin URL is correct." + "LinkedinUrlValidationMessage": "Your Linkedin URL can not include whitespace, please be sure your Linkedin URL is correct.", + "NoPostsFound": "No posts found!", + "SearchInPosts": "Search in posts..." } } From e4b7a6adc0473795140f250fb2843a60eba31158 Mon Sep 17 00:00:00 2001 From: Zony Date: Tue, 2 Mar 2021 22:48:48 +0800 Subject: [PATCH 056/101] Submit the `RabbitMQ Background Job Manager` Chinese document. --- docs/zh-Hans/Background-Jobs-RabbitMq.md | 154 ++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/Background-Jobs-RabbitMq.md b/docs/zh-Hans/Background-Jobs-RabbitMq.md index 979beec872..45c2978593 100644 --- a/docs/zh-Hans/Background-Jobs-RabbitMq.md +++ b/docs/zh-Hans/Background-Jobs-RabbitMq.md @@ -1,3 +1,153 @@ -# RabbitMQ Background Job Manager +# RabbitMQ 后台作业管理 -待添加 \ No newline at end of file +RabbitMQ 是一个标准的消息队列中间件,虽然它常用于消息传递/分布式事件,但也非常适合存储 FIFO(先进先出) 顺序的后台作业。 + +ABP Framework 提供了 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包,将使用 RabbitMQ 来执行后台作业。 + +> 参阅 [后台作业文档](Background-Jobs.md) 学习如何使用后台作业系统,本文只介绍了如何安装和配置 RabbitMQ 集成。 + +## 安装 + +使用 ABP CLI 将 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包添加到你的项目: + +- 如果之前没有安装过 [ABP CLI](https://docs.abp.io/en/abp/latest/CLI),请先安装它。 +- 跳转到待安装后台作业管理的项目目录中(包含 `.csproj` 文件的目录),打开终端管理器。 +- 执行 `abp add-package Volo.Abp.BackgroundJobs.RabbitMQ` 命令。 + +如果你想要手动安装,请先用 NuGet 包管理器安装 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包到指定项目,之后使在你的 [模块](Module-Development-Basics.md) 上面添加 `[DependsOn(typeof(AbpBackgroundJobsRabbitMqModule))]` 配置依赖。 + +## 配置 + +### 默认配置 + +默认配置将会使用标准端口和主机名(localhost)连接到 RabbitMQ 服务,**你不需要进行额外配置**。 + +### RabbitMQ 连接 + +你可以使用 ASP.NET Core 的 [标准配置系统](Configuration.md) 对 RabbitMQ 进行详细配置,比如 `appsettings.json` 或者是 [选项类](Options.md)。 + +#### 通过 `appsettings.json` 文件配置 + +这种方式是配置 RabbitMQ 连接最简单的方式,你可以使用其他的配置源(例如环境变量)。这些强大的功能都是由 [ASP.NET Core](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/) 提供的支持。 + +**示例: 配置默认的 RabbitMQ 连接** + +```json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123", + "Port": "5672" + } + } + } +} +``` + +你可以在配置文件使用所有 [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) 的属性,关于这些属性的具体含义,可以查看 RabbitMQ 的 [官方文档](https://www.rabbitmq.com/dotnet-api-guide.html#exchanges-and-queues)。 + +目前我们允许定义多个连接,多连接的情况适用于不同的后台作业,具体配置信息可以参考下面的 RabbitMQ 后台作业配置说明。 + +**示例: 定义两个 RabbitMQ 连接** + +```json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123" + }, + "SecondConnection": { + "HostName": "321.321.321.321" + } + } + } +} +``` + +如果需要连接到 RabbitMQ 集群,你可以指定多个 HostName。 + +**示例: 连接到 RabbitMQ 集群** + +```json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123;234.234.234.234" + } + }, + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName" + } + } +} +``` + +#### 使用选项类 + +`AbpRabbitMqOptions` 类型用于配置 RabbitMQ 的连接字符串,你可以在 [模块](Module-Development-Basics.md) 的 `ConfigureService` 方法中进行配置。 + +**示例: 配置 RabbitMQ 连接** + +```csharp +Configure(options => +{ + options.Connections.Default.UserName = "user"; + options.Connections.Default.Password = "pass"; + options.Connections.Default.HostName = "123.123.123.123"; + options.Connections.Default.Port = 5672; +}); +``` + +关于选项类,可以结合 `appsettings.json` 文件一起使用。针对同一个属性,在选项类里面对该值进行了设定,会覆盖掉 `appsettings.json` 的值。 + +### RabbitMQ 后台作业配置说明 + +#### 后台作业队列的名称 + +默认情况下,每个后台作业都会使用一个单独的队列,结合标准前缀和作业名称来构造一个完整的队列名称。默认的前缀为 `AbpBackgroundJobs`,所以有一个作业的名称是 `EmailSending` 的话,在 RabbitMQ 的队列名称就是 `AbpBackgroundJobs.EmailSending`。 + +> 在后台作业的参数类上,可以使用 `BackgroundJobName` 特性指定后台作业的名称。否则的话,后台作业的名称将会是后台作业类的全名(Full Name)(也包含命名空间)。 + +#### 后台作业使用的连接 + +默认情况下,后台作业都会使用 `Default` 作为默认连接。 + +#### 自定义 + +`AbpRabbitMqBackgroundJobOptions` 可以自定义队列名和作业使用的 RabbitMQ 连接。 + +**示例: ** + +```csharp +Configure(options => +{ + options.DefaultQueueNamePrefix = "my_app_jobs."; + options.JobQueues[typeof(EmailSendingArgs)] = + new JobQueueConfiguration( + typeof(EmailSendingArgs), + queueName: "my_app_jobs.emails", + connectionName: "SecondConnection" + ); +}); +``` + +- 这个示例将默认的队列名前缀设置为 `my_app_jobs.`,如果多个项目都使用的同一个 RabbitMQ 服务,设置不同的前缀可以避免执行其他项目的后台作业。 +- 这里还设置了 `EmailSendingArgs` 绑定的 RabbitMQ 连接。 + +`JobQueueConfiguration` 类的构造函数中,还有一些其他的可选参数。 + +- `queueName`: 指定后台作业对应的队列名称(全名)。 +- `connectionName`: 后台作业对应的 RabbitMQ 连接名称,默认是 `Default`。 +- `durable`: 可选参数,默认为 `true`。 +- `exclusive`: 可选参数,默认为 `false`。 +- `autoDelete`: 可选参数,默认为 `false`。 + +如果你想要更多地了解 `durable`、`exclusive`、`autoDelete` 的用法,请阅读 RabbitMQ 提供的文档。 + +## 参考 + +- [后台作业](Background-Jobs.md) \ No newline at end of file From 36097d2e402df345eaf16b98ae9a577f81612f13 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 18:06:30 +0300 Subject: [PATCH 057/101] PropertyNameGenerator moved to static class --- .../Modeling/PropertyApiDescriptionModel.cs | 2 +- .../AbpApiPropertyNameConfiguration.cs | 32 +++++++++++++++++++ .../AbpApiProxyScriptingOptions.cs | 25 --------------- 3 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs index 678798ae39..8eb307c630 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs @@ -24,7 +24,7 @@ namespace Volo.Abp.Http.Modeling return new PropertyApiDescriptionModel { Name = propertyInfo.Name, - JsonName = AbpApiProxyScriptingOptions.PropertyNameGenerator.Invoke(propertyInfo), + JsonName = AbpApiPropertyNameConfiguration.PropertyNameGenerator.Invoke(propertyInfo), Type = ApiTypeNameHelper.GetTypeName(propertyInfo.PropertyType), TypeSimple = ApiTypeNameHelper.GetSimpleTypeName(propertyInfo.PropertyType), IsRequired = propertyInfo.IsDefined(typeof(RequiredAttribute), true) diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs new file mode 100644 index 0000000000..4320e9905f --- /dev/null +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; + +namespace Volo.Abp.Http.ProxyScripting.Configuration +{ + public static class AbpApiPropertyNameConfiguration + { + public static Func PropertyNameGenerator { get; set; } + + static AbpApiPropertyNameConfiguration() + { + PropertyNameGenerator = propertyInfo => + { + var jsonPropertyNameAttribute = propertyInfo.GetSingleAttributeOrNull(true); + + if (jsonPropertyNameAttribute != null) + { + return jsonPropertyNameAttribute.Name; + } + + var jsonPropertyAttribute = propertyInfo.GetSingleAttributeOrNull(true); + + if (jsonPropertyAttribute != null) + { + return jsonPropertyAttribute.PropertyName; + } + + return null; + }; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs index 76c7dc74f5..e698d00416 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingOptions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Reflection; namespace Volo.Abp.Http.ProxyScripting.Configuration { @@ -8,30 +7,6 @@ namespace Volo.Abp.Http.ProxyScripting.Configuration { public IDictionary Generators { get; } - public static Func PropertyNameGenerator { get; set; } - - static AbpApiProxyScriptingOptions() - { - PropertyNameGenerator = propertyInfo => - { - var jsonPropertyNameAttribute = propertyInfo.GetSingleAttributeOrNull(true); - - if (jsonPropertyNameAttribute != null) - { - return jsonPropertyNameAttribute.Name; - } - - var jsonPropertyAttribute = propertyInfo.GetSingleAttributeOrNull(true); - - if (jsonPropertyAttribute != null) - { - return jsonPropertyAttribute.PropertyName; - } - - return null; - }; - } - public AbpApiProxyScriptingOptions() { Generators = new Dictionary(); From dc95eabf4305bace4a20100c82ae32f7f9325dfd Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 2 Mar 2021 18:10:29 +0300 Subject: [PATCH 058/101] rename configuration class name --- .../Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs | 2 +- ...eConfiguration.cs => AbpApiProxyScriptingConfiguration.cs} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/{AbpApiPropertyNameConfiguration.cs => AbpApiProxyScriptingConfiguration.cs} (89%) diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs index 8eb307c630..fc9f13edbc 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs @@ -24,7 +24,7 @@ namespace Volo.Abp.Http.Modeling return new PropertyApiDescriptionModel { Name = propertyInfo.Name, - JsonName = AbpApiPropertyNameConfiguration.PropertyNameGenerator.Invoke(propertyInfo), + JsonName = AbpApiProxyScriptingConfiguration.PropertyNameGenerator.Invoke(propertyInfo), Type = ApiTypeNameHelper.GetTypeName(propertyInfo.PropertyType), TypeSimple = ApiTypeNameHelper.GetSimpleTypeName(propertyInfo.PropertyType), IsRequired = propertyInfo.IsDefined(typeof(RequiredAttribute), true) diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs similarity index 89% rename from framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs rename to framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs index 4320e9905f..1f17d0d2cf 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiPropertyNameConfiguration.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Configuration/AbpApiProxyScriptingConfiguration.cs @@ -3,11 +3,11 @@ using System.Reflection; namespace Volo.Abp.Http.ProxyScripting.Configuration { - public static class AbpApiPropertyNameConfiguration + public static class AbpApiProxyScriptingConfiguration { public static Func PropertyNameGenerator { get; set; } - static AbpApiPropertyNameConfiguration() + static AbpApiProxyScriptingConfiguration() { PropertyNameGenerator = propertyInfo => { From e7f908e44a9fbef5b5ddccd1859baf7831c129de Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 3 Mar 2021 09:44:49 +0800 Subject: [PATCH 059/101] Update Background-Jobs-RabbitMq.md --- docs/zh-Hans/Background-Jobs-RabbitMq.md | 58 ++++++++++++------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/zh-Hans/Background-Jobs-RabbitMq.md b/docs/zh-Hans/Background-Jobs-RabbitMq.md index 45c2978593..8fb5cc58b7 100644 --- a/docs/zh-Hans/Background-Jobs-RabbitMq.md +++ b/docs/zh-Hans/Background-Jobs-RabbitMq.md @@ -1,34 +1,34 @@ # RabbitMQ 后台作业管理 -RabbitMQ 是一个标准的消息队列中间件,虽然它常用于消息传递/分布式事件,但也非常适合存储 FIFO(先进先出) 顺序的后台作业。 +RabbitMQ 是一个标准的消息队列中间件,虽然它常用于消息传递/分布式事件,但也非常适合存储 FIFO(先进先出) 顺序的后台作业. -ABP Framework 提供了 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包,将使用 RabbitMQ 来执行后台作业。 +ABP Framework 提供了 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包,将使用 RabbitMQ 来执行后台作业. -> 参阅 [后台作业文档](Background-Jobs.md) 学习如何使用后台作业系统,本文只介绍了如何安装和配置 RabbitMQ 集成。 +> 参阅 [后台作业文档](Background-Jobs.md) 学习如何使用后台作业系统,本文只介绍了如何安装和配置 RabbitMQ 集成. ## 安装 使用 ABP CLI 将 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包添加到你的项目: -- 如果之前没有安装过 [ABP CLI](https://docs.abp.io/en/abp/latest/CLI),请先安装它。 -- 跳转到待安装后台作业管理的项目目录中(包含 `.csproj` 文件的目录),打开终端管理器。 -- 执行 `abp add-package Volo.Abp.BackgroundJobs.RabbitMQ` 命令。 +- 如果之前没有安装过 [ABP CLI](https://docs.abp.io/en/abp/latest/CLI),请先安装它. +- 跳转到待安装后台作业管理的项目目录中(包含 `.csproj` 文件的目录),打开终端管理器. +- 执行 `abp add-package Volo.Abp.BackgroundJobs.RabbitMQ` 命令. -如果你想要手动安装,请先用 NuGet 包管理器安装 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包到指定项目,之后使在你的 [模块](Module-Development-Basics.md) 上面添加 `[DependsOn(typeof(AbpBackgroundJobsRabbitMqModule))]` 配置依赖。 +如果你想要手动安装,请先用 NuGet 包管理器安装 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.BackgroundJobs.RabbitMQ) 包到指定项目,之后使在你的 [模块](Module-Development-Basics.md) 上面添加 `[DependsOn(typeof(AbpBackgroundJobsRabbitMqModule))]` 配置依赖. ## 配置 ### 默认配置 -默认配置将会使用标准端口和主机名(localhost)连接到 RabbitMQ 服务,**你不需要进行额外配置**。 +默认配置将会使用标准端口和主机名(localhost)连接到 RabbitMQ 服务,**你不需要进行额外配置**. ### RabbitMQ 连接 -你可以使用 ASP.NET Core 的 [标准配置系统](Configuration.md) 对 RabbitMQ 进行详细配置,比如 `appsettings.json` 或者是 [选项类](Options.md)。 +你可以使用 ASP.NET Core 的 [标准配置系统](Configuration.md) 对 RabbitMQ 进行详细配置,比如 `appsettings.json` 或者是 [选项类](Options.md). #### 通过 `appsettings.json` 文件配置 -这种方式是配置 RabbitMQ 连接最简单的方式,你可以使用其他的配置源(例如环境变量)。这些强大的功能都是由 [ASP.NET Core](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/) 提供的支持。 +这种方式是配置 RabbitMQ 连接最简单的方式,你可以使用其他的配置源(例如环境变量).这些强大的功能都是由 [ASP.NET Core](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/) 提供的支持. **示例: 配置默认的 RabbitMQ 连接** @@ -45,9 +45,9 @@ ABP Framework 提供了 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org } ``` -你可以在配置文件使用所有 [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) 的属性,关于这些属性的具体含义,可以查看 RabbitMQ 的 [官方文档](https://www.rabbitmq.com/dotnet-api-guide.html#exchanges-and-queues)。 +你可以在配置文件使用所有 [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) 的属性,关于这些属性的具体含义,可以查看 RabbitMQ 的 [官方文档](https://www.rabbitmq.com/dotnet-api-guide.html#exchanges-and-queues). -目前我们允许定义多个连接,多连接的情况适用于不同的后台作业,具体配置信息可以参考下面的 RabbitMQ 后台作业配置说明。 +目前我们允许定义多个连接,多连接的情况适用于不同的后台作业,具体配置信息可以参考下面的 RabbitMQ 后台作业配置说明. **示例: 定义两个 RabbitMQ 连接** @@ -66,7 +66,7 @@ ABP Framework 提供了 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org } ``` -如果需要连接到 RabbitMQ 集群,你可以指定多个 HostName。 +如果需要连接到 RabbitMQ 集群,你可以指定多个 HostName. **示例: 连接到 RabbitMQ 集群** @@ -88,7 +88,7 @@ ABP Framework 提供了 [Volo.Abp.BackgroundJobs.RabbitMQ](https://www.nuget.org #### 使用选项类 -`AbpRabbitMqOptions` 类型用于配置 RabbitMQ 的连接字符串,你可以在 [模块](Module-Development-Basics.md) 的 `ConfigureService` 方法中进行配置。 +`AbpRabbitMqOptions` 类型用于配置 RabbitMQ 的连接字符串,你可以在 [模块](Module-Development-Basics.md) 的 `ConfigureService` 方法中进行配置. **示例: 配置 RabbitMQ 连接** @@ -102,23 +102,23 @@ Configure(options => }); ``` -关于选项类,可以结合 `appsettings.json` 文件一起使用。针对同一个属性,在选项类里面对该值进行了设定,会覆盖掉 `appsettings.json` 的值。 +关于选项类,可以结合 `appsettings.json` 文件一起使用.针对同一个属性,在选项类里面对该值进行了设定,会覆盖掉 `appsettings.json` 的值. ### RabbitMQ 后台作业配置说明 #### 后台作业队列的名称 -默认情况下,每个后台作业都会使用一个单独的队列,结合标准前缀和作业名称来构造一个完整的队列名称。默认的前缀为 `AbpBackgroundJobs`,所以有一个作业的名称是 `EmailSending` 的话,在 RabbitMQ 的队列名称就是 `AbpBackgroundJobs.EmailSending`。 +默认情况下,每个后台作业都会使用一个单独的队列,结合标准前缀和作业名称来构造一个完整的队列名称.默认的前缀为 `AbpBackgroundJobs`,所以有一个作业的名称是 `EmailSending` 的话,在 RabbitMQ 的队列名称就是 `AbpBackgroundJobs.EmailSending`. -> 在后台作业的参数类上,可以使用 `BackgroundJobName` 特性指定后台作业的名称。否则的话,后台作业的名称将会是后台作业类的全名(Full Name)(也包含命名空间)。 +> 在后台作业的参数类上,可以使用 `BackgroundJobName` 特性指定后台作业的名称.否则的话,后台作业的名称将会是后台作业类的全名(也包含命名空间). #### 后台作业使用的连接 -默认情况下,后台作业都会使用 `Default` 作为默认连接。 +默认情况下,后台作业都会使用 `Default` 作为默认连接. #### 自定义 -`AbpRabbitMqBackgroundJobOptions` 可以自定义队列名和作业使用的 RabbitMQ 连接。 +`AbpRabbitMqBackgroundJobOptions` 可以自定义队列名和作业使用的 RabbitMQ 连接. **示例: ** @@ -135,19 +135,19 @@ Configure(options => }); ``` -- 这个示例将默认的队列名前缀设置为 `my_app_jobs.`,如果多个项目都使用的同一个 RabbitMQ 服务,设置不同的前缀可以避免执行其他项目的后台作业。 -- 这里还设置了 `EmailSendingArgs` 绑定的 RabbitMQ 连接。 +- 这个示例将默认的队列名前缀设置为 `my_app_jobs.`,如果多个项目都使用的同一个 RabbitMQ 服务,设置不同的前缀可以避免执行其他项目的后台作业. +- 这里还设置了 `EmailSendingArgs` 绑定的 RabbitMQ 连接. -`JobQueueConfiguration` 类的构造函数中,还有一些其他的可选参数。 +`JobQueueConfiguration` 类的构造函数中,还有一些其他的可选参数. -- `queueName`: 指定后台作业对应的队列名称(全名)。 -- `connectionName`: 后台作业对应的 RabbitMQ 连接名称,默认是 `Default`。 -- `durable`: 可选参数,默认为 `true`。 -- `exclusive`: 可选参数,默认为 `false`。 -- `autoDelete`: 可选参数,默认为 `false`。 +- `queueName`: 指定后台作业对应的队列名称(全名). +- `connectionName`: 后台作业对应的 RabbitMQ 连接名称,默认是 `Default`. +- `durable`: 可选参数,默认为 `true`. +- `exclusive`: 可选参数,默认为 `false`. +- `autoDelete`: 可选参数,默认为 `false`. -如果你想要更多地了解 `durable`、`exclusive`、`autoDelete` 的用法,请阅读 RabbitMQ 提供的文档。 +如果你想要更多地了解 `durable`,`exclusive`,`autoDelete` 的用法,请阅读 RabbitMQ 提供的文档. ## 参考 -- [后台作业](Background-Jobs.md) \ No newline at end of file +- [后台作业](Background-Jobs.md) From eb3b320f1ea76c1f98427bd40427d3e861a4f210 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 3 Mar 2021 09:45:09 +0800 Subject: [PATCH 060/101] Update Background-Jobs-RabbitMq.md --- docs/zh-Hans/Background-Jobs-RabbitMq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-Hans/Background-Jobs-RabbitMq.md b/docs/zh-Hans/Background-Jobs-RabbitMq.md index 8fb5cc58b7..0f9fb21d8a 100644 --- a/docs/zh-Hans/Background-Jobs-RabbitMq.md +++ b/docs/zh-Hans/Background-Jobs-RabbitMq.md @@ -148,6 +148,6 @@ Configure(options => 如果你想要更多地了解 `durable`,`exclusive`,`autoDelete` 的用法,请阅读 RabbitMQ 提供的文档. -## 参考 +## 另请参阅 - [后台作业](Background-Jobs.md) From 9ac0cb04d89b8fec2f0ff0ad4c2098ba5f6fc59c Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 3 Mar 2021 10:33:35 +0800 Subject: [PATCH 061/101] Use Index API to add or update documents --- .../Elastic/ElasticDocumentFullSearch.cs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs index 8e0a51324a..7160ca405b 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/FullSearch/Elastic/ElasticDocumentFullSearch.cs @@ -60,11 +60,6 @@ namespace Volo.Docs.Documents.FullSearch.Elastic var client = _clientProvider.GetClient(); - var existsResponse = await client.DocumentExistsAsync(DocumentPath.Id(document.Id), - x => x.Index(_options.IndexName), cancellationToken); - - HandleError(existsResponse); - var esDocument = new EsDocument { Id = NormalizeField(document.Id), @@ -76,17 +71,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic Version = NormalizeField(document.Version) }; - if (!existsResponse.Exists) - { - HandleError(await client.IndexAsync(esDocument, - x => x.Id(document.Id).Index(_options.IndexName), cancellationToken)); - } - else - { - HandleError(await client.UpdateAsync(DocumentPath.Id(document.Id), - x => x.Doc(esDocument).Index(_options.IndexName), cancellationToken)); - } - + await client.IndexAsync(esDocument , x=>x.Index(_options.IndexName), cancellationToken); } public virtual async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) @@ -94,7 +79,7 @@ namespace Volo.Docs.Documents.FullSearch.Elastic ValidateElasticSearchEnabled(); HandleError(await _clientProvider.GetClient() - .DeleteAsync(DocumentPath.Id(id), x => x.Index(_options.IndexName), cancellationToken)); + .DeleteAsync(DocumentPath.Id( NormalizeField(id)), x => x.Index(_options.IndexName), cancellationToken)); } public virtual async Task DeleteAllAsync(CancellationToken cancellationToken = default) From 706986715ca682008eeefea70df5cd2bb20517a7 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 3 Mar 2021 13:53:05 +0800 Subject: [PATCH 062/101] Check whether the controller implements the IRemoteService interface. Resolve #7920 --- .../AbpRemoteServiceApiDescriptionProvider.cs | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider.cs index ae09573d60..1a017e9925 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider.cs @@ -3,6 +3,7 @@ using System.Linq; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.Options; @@ -19,7 +20,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApiExploring public AbpRemoteServiceApiDescriptionProvider( IModelMetadataProvider modelMetadataProvider, - IOptions mvcOptionsAccessor, + IOptions mvcOptionsAccessor, IOptions optionsAccessor) { _modelMetadataProvider = modelMetadataProvider; @@ -41,7 +42,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApiExploring { foreach (var apiResponseType in GetApiResponseTypes()) { - foreach (var result in context.Results.Where(x => IsRemoteService(x.ActionDescriptor))) + foreach (var result in context.Results.Where(IsRemoteService)) { var actionProducesResponseTypeAttributes = ReflectionHelper.GetAttributesOfMemberOrDeclaringType( @@ -62,7 +63,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApiExploring foreach (var apiResponse in _options.SupportedResponseTypes) { apiResponse.ModelMetadata = _modelMetadataProvider.GetMetadataForType(apiResponse.Type); - + foreach (var responseTypeMetadataProvider in _mvcOptions.OutputFormatters.OfType()) { var formatterSupportedContentTypes = responseTypeMetadataProvider.GetSupportedContentTypes(null, apiResponse.Type); @@ -85,10 +86,29 @@ namespace Volo.Abp.AspNetCore.Mvc.ApiExploring return _options.SupportedResponseTypes; } - protected virtual bool IsRemoteService(ActionDescriptor actionDescriptor) + protected virtual bool IsRemoteService(ApiDescription actionDescriptor) { - var remoteServiceAttr = ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(actionDescriptor.GetMethodInfo()); - return remoteServiceAttr != null && remoteServiceAttr.IsEnabled; + if (actionDescriptor.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor) + { + var remoteServiceAttr = ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(controllerActionDescriptor.MethodInfo); + if (remoteServiceAttr != null && remoteServiceAttr.IsEnabled) + { + return true; + } + + remoteServiceAttr = ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(controllerActionDescriptor.ControllerTypeInfo); + if (remoteServiceAttr != null && remoteServiceAttr.IsEnabled) + { + return true; + } + + if (typeof(IRemoteService).IsAssignableFrom(controllerActionDescriptor.ControllerTypeInfo)) + { + return true; + } + } + + return false; } } -} \ No newline at end of file +} From bee8331660a592e791d24070a1bc0363b420842f Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Wed, 3 Mar 2021 10:56:59 +0300 Subject: [PATCH 063/101] add iis express caveat to service proxy document --- docs/en/UI/Angular/Service-Proxies.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/UI/Angular/Service-Proxies.md b/docs/en/UI/Angular/Service-Proxies.md index 8f6b1c4d60..3a10f1b6e8 100644 --- a/docs/en/UI/Angular/Service-Proxies.md +++ b/docs/en/UI/Angular/Service-Proxies.md @@ -137,3 +137,7 @@ export class BookComponent implements OnInit { ``` > Please [see this article](https://github.com/abpframework/abp/blob/dev/docs/en/Blog-Posts/2020-09-07%20Angular-Service-Proxies/POST.md) to learn more about service proxies. + +### Known Limitations + +When you run a project on Visual Studio using IIS Express as the web server, there will be no remote access to your endpoints. This is the default behavior of IIS Express since it explicitly protects you from the security risks of running over the network. However, that will cause the proxy generator to fail because it needs a response from the `/api/abp/api-definition` endpoint. You may serve your endpoints via Kestrel to avoid this. Running `dotnet run` in your command line (at your project folder) will do that for you. From f0a1e4a0507240ae5af46beb137bc95788c3ad3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 3 Mar 2021 11:42:51 +0300 Subject: [PATCH 064/101] Define ApplyDatabaseMigrationsEto. --- framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj | 2 +- .../Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs | 4 +++- .../Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs | 4 ++-- .../Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs | 14 ++++++++++++++ 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs diff --git a/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj b/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj index cde2718a56..b1077c82da 100644 --- a/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj +++ b/framework/src/Volo.Abp.Data/Volo.Abp.Data.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs index bc3bc8e5dd..6690f855e4 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.EventBus.Abstractions; using Volo.Abp.Modularity; using Volo.Abp.ObjectExtending; using Volo.Abp.Uow; @@ -10,7 +11,8 @@ namespace Volo.Abp.Data { [DependsOn( typeof(AbpObjectExtendingModule), - typeof(AbpUnitOfWorkModule) + typeof(AbpUnitOfWorkModule), + typeof(AbpEventBusAbstractionsModule) )] public class AbpDataModule : AbpModule { diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs index 4f719a862a..33e545d10f 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs @@ -12,8 +12,8 @@ namespace Volo.Abp.Data public HashSet MappedConnections { get; } /// - /// Is this database used by tenants. Set this to true if this database - /// can't owned by tenants. + /// Is this database used by tenants. Set this to false if this database + /// can not owned by tenants. /// /// Default: true. /// diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs new file mode 100644 index 0000000000..be31bbe74f --- /dev/null +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp.EventBus; + +namespace Volo.Abp.Data +{ + [Serializable] + [EventName("abp.data.apply_database_migrations")] + public class ApplyDatabaseMigrationsEto + { + public Guid? TenantId { get; set; } + + public string DatabaseName { get; set; } + } +} \ No newline at end of file From 9e1ae1171bc086e315d8051d5d909a833bfa4315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 3 Mar 2021 11:44:48 +0300 Subject: [PATCH 065/101] Inherit ApplyDatabaseMigrationsEto from EtoBase --- .../Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs index be31bbe74f..86c2003aad 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/ApplyDatabaseMigrationsEto.cs @@ -1,11 +1,12 @@ using System; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; namespace Volo.Abp.Data { [Serializable] [EventName("abp.data.apply_database_migrations")] - public class ApplyDatabaseMigrationsEto + public class ApplyDatabaseMigrationsEto : EtoBase { public Guid? TenantId { get; set; } From f91cf9bc887b32167fab755e58a532949f57b171 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Mar 2021 11:56:10 +0300 Subject: [PATCH 066/101] CmsKit - Fix JS url redirections --- .../cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs | 4 ++-- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js | 4 ++-- .../Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs index 4834670b3c..25dd69cd63 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs @@ -76,11 +76,11 @@ namespace Volo.CmsKit.Admin.Web options.Conventions.AddPageRoute("/CmsKit/Tags/Index", "/Cms/Tags"); options.Conventions.AddPageRoute("/CmsKit/Pages/Index", "/Cms/Pages"); options.Conventions.AddPageRoute("/CmsKit/Pages/Create", "/Cms/Pages/Create"); - options.Conventions.AddPageRoute("/CmsKit/Pages/Update", "/Cms/Pages/Update"); + options.Conventions.AddPageRoute("/CmsKit/Pages/Update", "/Cms/Pages/Update/{Id}"); options.Conventions.AddPageRoute("/CmsKit/Blogs/Index", "/Cms/Blogs"); options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Index", "/Cms/BlogPosts"); options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Create", "/Cms/BlogPosts/Create"); - options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update"); + options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update/{Id}"); options.Conventions.AddPageRoute("/CmsKit/Comments/Index", "/Cms/Comments"); options.Conventions.AddPageRoute("/CmsKit/Comments/Details", "/Cms/Details"); }); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js index 7302299419..e2f19079b7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/index.js @@ -27,7 +27,7 @@ $(function () { text: l('Edit'), visible: abp.auth.isGranted('CmsKit.Blogs.Update'), action: function (data) { - location.href = "/CmsKit/BlogPosts/Update/" + data.record.id + location.href = "BlogPosts/Update/" + data.record.id } }, { @@ -63,6 +63,6 @@ $(function () { $('#AbpContentToolbar button[name=CreateBlogPost]').on('click', function (e) { e.preventDefault(); - window.location.href = "/CmsKit/BlogPosts/Create" + window.location.href = "BlogPosts/Create" }); }); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js index 14bfdc6f55..cfabca29ea 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js @@ -126,7 +126,7 @@ function finishSaving(result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = "/CmsKit/BlogPosts/"; + location.href = ".."; } $titleClone.on('change paste keyup', function () { From 249dabdef4c979971e3a138cbfb0f64ccbea5206 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Mar 2021 12:24:23 +0300 Subject: [PATCH 067/101] CmsKit - Make case-insensitive check for MediaDescriptorDefinitionStore --- .../Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs | 7 ++----- .../DefaultMediaDescriptorDefinitionStore.cs | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index 17c242755e..575e8950a6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -21,15 +21,12 @@ namespace Volo.CmsKit.Admin )] public class CmsKitAdminApplicationModule : AbpModule { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - ConfigureTagOptions(); - } - public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAutoMapperObjectMapper(); + ConfigureTagOptions(); + Configure(options => { options.AddMaps(validate: true); diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs index 5a1553c3fc..752f921da7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs @@ -29,7 +29,7 @@ namespace Volo.CmsKit.MediaDescriptors { Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); - var result = Options.EntityTypes.SingleOrDefault(x => x.EntityType == entityType) ?? + var result = Options.EntityTypes.SingleOrDefault(x => x.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase)) ?? throw new EntityCantHaveMediaException(entityType); return Task.FromResult(result); @@ -39,7 +39,7 @@ namespace Volo.CmsKit.MediaDescriptors { Check.NotNullOrEmpty(entityType, nameof(entityType)); - var isDefined = Options.EntityTypes.Any(a => a.EntityType == entityType); + var isDefined = Options.EntityTypes.Any(a => a.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase)); return Task.FromResult(isDefined); } From 42d3f7c4beecb745ba5eaacd46cb23ea7ee5d261 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Mar 2021 12:29:08 +0300 Subject: [PATCH 068/101] CmsKit - Fix js redirection for BlogPost Update --- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js index cfabca29ea..ee6da62f6a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/update.js @@ -126,7 +126,7 @@ function finishSaving(result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = ".."; + location.href = "../../BlogPosts"; } $titleClone.on('change paste keyup', function () { From b16fc75f29dc27d1da49a1525d225ab5acf4afe2 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Mar 2021 14:30:49 +0300 Subject: [PATCH 069/101] CmsKit - Add EntityType configuration to Comments --- .../Admin/CmsKitAdminApplicationModule.cs | 51 ++++++++++------ .../Volo/CmsKit/CmsKitErrorCodes.cs | 5 ++ .../CmsKit/Localization/Resources/en.json | 3 +- .../CmsKit/Localization/Resources/tr.json | 1 + .../CmsKit/Comments/CmsKitCommentOptions.cs | 11 ++++ .../Volo/CmsKit/Comments/Comment.cs | 2 +- .../Comments/CommentEntityTypeDefinition.cs | 21 +++++++ .../Volo/CmsKit/Comments/CommentManager.cs | 42 +++++++++++++ ...DefaultCommentEntityTypeDefinitionStore.cs | 41 +++++++++++++ .../Comments/EntityNotCommentableException.cs | 26 ++++++++ .../ICommentEntityTypeDefinitionStore.cs | 17 ++++++ .../Comments/CommentPublicAppService.cs | 16 +++-- .../Comments/CommentManager_Test.cs | 59 +++++++++++++++++++ .../CmsKitDataSeedContributor.cs | 14 +++-- 14 files changed, 277 insertions(+), 32 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CmsKitCommentOptions.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentEntityTypeDefinition.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/DefaultCommentEntityTypeDefinitionStore.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentEntityTypeDefinitionStore.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Comments/CommentManager_Test.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index 575e8950a6..ec926999f9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -5,6 +5,7 @@ using Volo.Abp.GlobalFeatures; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Comments; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Localization; using Volo.CmsKit.MediaDescriptors; @@ -43,20 +44,20 @@ namespace Volo.CmsKit.Admin new TagEntityTypeDefiniton( BlogPostConsts.EntityType, LocalizableString.Create("BlogPost"), - createPolicies: new[] + createPolicies: new[] { - CmsKitAdminPermissions.BlogPosts.Create, - CmsKitAdminPermissions.BlogPosts.Update + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update }, - updatePolicies: new[] - { - CmsKitAdminPermissions.BlogPosts.Create, - CmsKitAdminPermissions.BlogPosts.Update + updatePolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update }, - deletePolicies: new[] - { - CmsKitAdminPermissions.BlogPosts.Create, - CmsKitAdminPermissions.BlogPosts.Update + deletePolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, + CmsKitAdminPermissions.BlogPosts.Update })); } }); @@ -70,9 +71,9 @@ namespace Volo.CmsKit.Admin options.EntityTypes.AddIfNotContains( new MediaDescriptorDefinition( BlogPostConsts.EntityType, - createPolicies: new[] - { - CmsKitAdminPermissions.BlogPosts.Create, + createPolicies: new[] + { + CmsKitAdminPermissions.BlogPosts.Create, CmsKitAdminPermissions.BlogPosts.Update }, deletePolicies: new[] @@ -88,20 +89,36 @@ namespace Volo.CmsKit.Admin options.EntityTypes.AddIfNotContains( new MediaDescriptorDefinition( PageConsts.EntityType, - createPolicies: new[] + createPolicies: new[] { CmsKitAdminPermissions.Pages.Create, - CmsKitAdminPermissions.Pages.Update + CmsKitAdminPermissions.Pages.Update }, deletePolicies: new[] { CmsKitAdminPermissions.Pages.Create, CmsKitAdminPermissions.Pages.Update, - CmsKitAdminPermissions.Pages.Delete + CmsKitAdminPermissions.Pages.Delete })); } }); } } + + private void ConfigureCommentOptions() + { + if (GlobalFeatureManager.Instance.IsEnabled()) + { + Configure(options => + { + if (GlobalFeatureManager.Instance.IsEnabled()) + { + options.EntityTypes.AddIfNotContains( + new CommentEntityTypeDefinition(BlogPostConsts.EntityType)); + + } + }); + } + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs index b358672a1a..064c504fb4 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs @@ -24,6 +24,11 @@ { public const string SlugAlreadyExist = "CmsKit:BlogPost:0001"; } + + public static class Comments + { + public const string EntityNotCommentable = "CmsKit:Comments:0001"; + } public static class MediaDescriptors { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 1107d5e5db..5ae38566af 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -17,10 +17,11 @@ "CmsKit:0003": "The entity {0} is not taggable.", "CmsKit:Blog:0001": "The given slug ({Slug}) already exists!", "CmsKit:BlogPost:0001": "The given slug already exists!", + "CmsKit:Comments:0001": "The entity {0} is not commentable.", "CmsKit:Media:0001": "'{Name}' is not a valid media name.", + "CmsKit:Media:0002": "The entity can't have media.", "CmsKit:Page:0001": "The given url ({0}) already exists.", "CmsKit:Tag:0002": "The entity is not taggable!", - "CmsKit:Media:0002": "The entity can't have media.", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", "CommentDeletionConfirmationMessage": "This comment and all replies will be deleted!", "Comments": "Comments", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index f41639325a..2571d7ad96 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -13,6 +13,7 @@ "CmsKit.Ratings": "Puanlama", "CmsKit.Reactions": "Tepkiler", "CmsKit.Tags": "Etiketler", + "CmsKit:Comments:0001": "{0} ögesi yorumlanabilir değil.", "CmsKit:0002": "İçerik zaten mevcut!", "CmsKit:0003": "{0} ögesi etiketlenebilir değil.", "CmsKit:BlogPost:0001": "Aynı url etiketi zaten mevcut.", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CmsKitCommentOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CmsKitCommentOptions.cs new file mode 100644 index 0000000000..7e1dcbc1dd --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CmsKitCommentOptions.cs @@ -0,0 +1,11 @@ +using JetBrains.Annotations; +using System.Collections.Generic; + +namespace Volo.CmsKit.Comments +{ + public class CmsKitCommentOptions + { + [NotNull] + public List EntityTypes { get; } = new List(); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs index 0d2a7e7a18..ea37b5ebdc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs @@ -28,7 +28,7 @@ namespace Volo.CmsKit.Comments } - public Comment( + internal Comment( Guid id, [NotNull] string entityType, [NotNull] string entityId, diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentEntityTypeDefinition.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentEntityTypeDefinition.cs new file mode 100644 index 0000000000..fe0f8ebda3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentEntityTypeDefinition.cs @@ -0,0 +1,21 @@ +using JetBrains.Annotations; +using System; +using Volo.Abp; + +namespace Volo.CmsKit.Comments +{ + public class CommentEntityTypeDefinition : IEquatable + { + public CommentEntityTypeDefinition([NotNull] string entityType) + { + EntityType = Check.NotNullOrEmpty(entityType, nameof(entityType)); + } + + public string EntityType { get; } + + public bool Equals(CommentEntityTypeDefinition other) + { + return EntityType == other?.EntityType; + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs new file mode 100644 index 0000000000..59a3664e09 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs @@ -0,0 +1,42 @@ +using JetBrains.Annotations; +using System; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Domain.Services; +using Volo.CmsKit.Users; + +namespace Volo.CmsKit.Comments +{ + public class CommentManager : DomainService + { + protected ICommentEntityTypeDefinitionStore DefinitionStore { get; } + + public CommentManager(ICommentEntityTypeDefinitionStore definitionStore) + { + DefinitionStore = definitionStore; + } + + public virtual async Task CreateAsync([NotNull] CmsUser creator, + [NotNull] string entityType, + [NotNull] string entityId, + [NotNull] string text, + [CanBeNull] Guid? repliedCommentId = null) + { + Check.NotNull(creator, nameof(creator)); + + if (!await DefinitionStore.IsDefinedAsync(entityType)) + { + throw new EntityNotCommentableException(entityType); + } + + return new Comment( + GuidGenerator.Create(), + entityType, + entityId, + text, + repliedCommentId, + creator.Id, + CurrentTenant.Id); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/DefaultCommentEntityTypeDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/DefaultCommentEntityTypeDefinitionStore.cs new file mode 100644 index 0000000000..bbb1b19aee --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/DefaultCommentEntityTypeDefinitionStore.cs @@ -0,0 +1,41 @@ +using JetBrains.Annotations; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.DependencyInjection; + +namespace Volo.CmsKit.Comments +{ + public class DefaultCommentEntityTypeDefinitionStore : ICommentEntityTypeDefinitionStore, ITransientDependency + { + protected CmsKitCommentOptions Options { get; } + + public DefaultCommentEntityTypeDefinitionStore(IOptions options) + { + Options = options.Value; + } + + public virtual Task GetDefinitionAsync([NotNull] string entityType) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + + var result = Options.EntityTypes.SingleOrDefault(x => x.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase)) ?? + throw new EntityNotCommentableException(entityType); + + return Task.FromResult(result); + } + + public virtual Task IsDefinedAsync([NotNull] string entityType) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + + var isDefined = Options.EntityTypes.Any(x => x.EntityType == entityType); + + return Task.FromResult(isDefined); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs new file mode 100644 index 0000000000..12c3c872fc --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; + +namespace Volo.CmsKit.Comments +{ + public class EntityNotCommentableException : BusinessException + { + public EntityNotCommentableException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) + { + } + + public EntityNotCommentableException(string entityType) + { + Code = CmsKitErrorCodes.Comments.EntityNotCommentable; + EntityType = entityType; + WithData(nameof(EntityType), EntityType); + } + + public string EntityType { get; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentEntityTypeDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentEntityTypeDefinitionStore.cs new file mode 100644 index 0000000000..315b7f878f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentEntityTypeDefinitionStore.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Comments; + +namespace Volo.CmsKit.Comments +{ + public interface ICommentEntityTypeDefinitionStore + { + Task GetDefinitionAsync([NotNull] string entityType); + + Task IsDefinedAsync([NotNull] string entityType); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs index f283473f95..d5dd555b71 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs @@ -21,20 +21,20 @@ namespace Volo.CmsKit.Public.Comments protected ICommentRepository CommentRepository { get; } protected ICmsUserLookupService CmsUserLookupService { get; } public IDistributedEventBus DistributedEventBus { get; } - public IUnitOfWorkManager UnitOfWorkManager { get; } + protected CommentManager CommentManager { get; } public CommentPublicAppService( ICommentRepository commentRepository, ICmsUserLookupService cmsUserLookupService, IDistributedEventBus distributedEventBus, - IUnitOfWorkManager unitOfWorkManager, - IOptions cmsKitOptions) + IOptions cmsKitOptions, + CommentManager commentManager) { CmsKitOptions = cmsKitOptions.Value; CommentRepository = commentRepository; CmsUserLookupService = cmsUserLookupService; DistributedEventBus = distributedEventBus; - UnitOfWorkManager = unitOfWorkManager; + CommentManager = commentManager; } public virtual async Task> GetListAsync(string entityType, string entityId) @@ -58,14 +58,12 @@ namespace Volo.CmsKit.Public.Comments } var comment = await CommentRepository.InsertAsync( - new Comment( - GuidGenerator.Create(), + await CommentManager.CreateAsync( + user, entityType, entityId, input.Text, - input.RepliedCommentId, - user.Id, - CurrentTenant.Id + input.RepliedCommentId ) ); diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Comments/CommentManager_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Comments/CommentManager_Test.cs new file mode 100644 index 0000000000..5065ec9c06 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Comments/CommentManager_Test.cs @@ -0,0 +1,59 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Users; +using Xunit; + +namespace Volo.CmsKit.Comments +{ + public class CommentManager_Test : CmsKitDomainTestBase + { + private readonly CommentManager commentManager; + private readonly CmsKitTestData testData; + private readonly ICmsUserRepository userRepository; + + public CommentManager_Test() + { + commentManager = GetRequiredService(); + testData = GetRequiredService(); + userRepository = GetRequiredService(); + } + + [Fact] + public async Task CreateAsync_ShouldWorkProperly_WithCorrectData() + { + var creator = await userRepository.GetAsync(testData.User1Id); + + var text = "Thank you for the article. It's awesome"; + + var comment = await commentManager.CreateAsync(creator, testData.EntityType1, testData.EntityId1, text); + + comment.Id.ShouldNotBe(Guid.Empty); + comment.CreatorId.ShouldBe(creator.Id); + comment.EntityType.ShouldBe(testData.EntityType1); + comment.EntityId.ShouldBe(testData.EntityId1); + comment.Text.ShouldBe(text); + } + + [Fact] + public async Task CreateAsync_ShouldThrowException_WithNotConfiguredEntityType() + { + var creator = await userRepository.GetAsync(testData.User1Id); + var notConfiguredEntityType = "Some.New.Entity"; + var text = "Thank you for the article. It's awesome"; + + var exception = await Should.ThrowAsync(async () => + await commentManager.CreateAsync( + creator, + notConfiguredEntityType, + testData.EntityId1, + text)); + + exception.ShouldNotBeNull(); + exception.EntityType.ShouldBe(notConfiguredEntityType); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index d218f7e93d..c4fc8de603 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -45,6 +45,7 @@ namespace Volo.CmsKit private readonly IBlobContainer _mediaBlobContainer; private readonly BlogManager _blogManager; private readonly IOptions _mediaOptions; + private readonly IOptions _commentsOptions; public CmsKitDataSeedContributor( IGuidGenerator guidGenerator, @@ -64,11 +65,12 @@ namespace Volo.CmsKit IBlogFeatureRepository blogFeatureRepository, EntityTagManager entityTagManager, IOptions options, - IOptions tagOptions, - IMediaDescriptorRepository mediaDescriptorRepository, - IBlobContainer mediaBlobContainer, + IOptions tagOptions, + IMediaDescriptorRepository mediaDescriptorRepository, + IBlobContainer mediaBlobContainer, BlogManager blogManager, - IOptions cmsMediaOptions) + IOptions cmsMediaOptions, + IOptions commentsOptions) { _guidGenerator = guidGenerator; _cmsUserRepository = cmsUserRepository; @@ -92,6 +94,7 @@ namespace Volo.CmsKit _mediaBlobContainer = mediaBlobContainer; _blogManager = blogManager; _mediaOptions = cmsMediaOptions; + _commentsOptions = commentsOptions; } public async Task SeedAsync(DataSeedContext context) @@ -134,6 +137,9 @@ namespace Volo.CmsKit createPolicies: new[] { "SomeCreatePolicy" }, deletePolicies: new[] { "SomeDeletePolicy" })); + _commentsOptions.Value.EntityTypes.Add( + new CommentEntityTypeDefinition(_cmsKitTestData.EntityType1)); + return Task.CompletedTask; } From c40093dffd26bb4afed698e448947334264378b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 3 Mar 2021 14:33:03 +0300 Subject: [PATCH 070/101] Added AbpAuthorizationServiceExtensions.IsGrantedAnyAsync --- .../AbpAuthorizationServiceExtensions.cs | 17 +++++++++++++++++ .../Volo/Abp/Data/AbpDatabaseInfo.cs | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs b/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs index bb820c3a83..133209f30a 100644 --- a/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs +++ b/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs @@ -65,6 +65,23 @@ namespace Microsoft.AspNetCore.Authorization { return (await authorizationService.AuthorizeAsync(policyName)).Succeeded; } + + public static async Task IsGrantedAnyAsync( + this IAuthorizationService authorizationService, + params string[] policyNames) + { + Check.NotNullOrEmpty(policyNames, nameof(policyNames)); + + foreach (var policyName in policyNames) + { + if ((await authorizationService.AuthorizeAsync(policyName)).Succeeded) + { + return true; + } + } + + return false; + } public static async Task IsGrantedAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement) { diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs index 33e545d10f..bcd08718cb 100644 --- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs +++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs @@ -4,7 +4,7 @@ namespace Volo.Abp.Data { public class AbpDatabaseInfo { - public string DatabaseName { get; set; } + public string DatabaseName { get; } /// /// List of connection names mapped to this database. From eebd5c0b3294d4d0945e7e4a7b3ecf4748122f99 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 4 Mar 2021 14:03:39 +0800 Subject: [PATCH 071/101] Add UpdateNuGetConfigStep to get source command --- .../Building/ModuleProjectBuildPipelineBuilder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs index 9b66f17834..d4a74d9364 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs @@ -1,4 +1,5 @@ using Volo.Abp.Cli.ProjectBuilding.Building.Steps; +using Volo.Abp.Cli.ProjectBuilding.Templates; namespace Volo.Abp.Cli.ProjectBuilding.Building { @@ -12,6 +13,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building pipeline.Steps.Add(new ProjectReferenceReplaceStep()); pipeline.Steps.Add(new ReplaceCommonPropsStep()); pipeline.Steps.Add(new ReplaceConfigureAwaitPropsStep()); + pipeline.Steps.Add(new UpdateNuGetConfigStep("/NuGet.Config")); pipeline.Steps.Add(new CreateProjectResultZipStep()); return pipeline; From e564e338a2a4b0fa45d17932f6533dfdff462f59 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 09:26:08 +0300 Subject: [PATCH 072/101] CmsKit - Add missing configuration to CmsKitAdminApplicationModule --- .../Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index ec926999f9..5eaf3dae28 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -28,6 +28,8 @@ namespace Volo.CmsKit.Admin ConfigureTagOptions(); + ConfigureCommentOptions(); + Configure(options => { options.AddMaps(validate: true); From f5f4f5f371673642b6db96d0b4e019fa49e1a922 Mon Sep 17 00:00:00 2001 From: EngincanV Date: Thu, 4 Mar 2021 10:28:25 +0300 Subject: [PATCH 073/101] Blogging: Cache blog posts --- .../Volo/Blogging/Posts/PostAppService.cs | 128 +++++++++++------- 1 file changed, 79 insertions(+), 49 deletions(-) diff --git a/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs b/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs index 70007a0c56..07d22d3385 100644 --- a/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs +++ b/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs @@ -4,6 +4,8 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using System.Collections.Generic; using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Caching.Distributed; +using Volo.Abp.Caching; using Volo.Blogging.Comments; using Volo.Blogging.Tagging; using Volo.Blogging.Tagging.Dtos; @@ -18,71 +20,41 @@ namespace Volo.Blogging.Posts private readonly IPostRepository _postRepository; private readonly ITagRepository _tagRepository; private readonly ICommentRepository _commentRepository; + private readonly IDistributedCache> _postsCache; - public PostAppService(IPostRepository postRepository, ITagRepository tagRepository, ICommentRepository commentRepository, IBlogUserLookupService userLookupService) + public PostAppService(IPostRepository postRepository, ITagRepository tagRepository, ICommentRepository commentRepository, IBlogUserLookupService userLookupService, IDistributedCache> postsCache) { UserLookupService = userLookupService; _postRepository = postRepository; _tagRepository = tagRepository; _commentRepository = commentRepository; + _postsCache = postsCache; } - + public async Task> GetListByBlogIdAndTagName(Guid id, string tagName) { - var posts = await _postRepository.GetPostsByBlogId(id); - var tag = tagName.IsNullOrWhiteSpace() ? null : await _tagRepository.FindByNameAsync(id, tagName); - var userDictionary = new Dictionary(); - var postDtos = new List(ObjectMapper.Map, List>(posts)); - - foreach (var postDto in postDtos) - { - postDto.Tags = await GetTagsOfPost(postDto.Id); - } - - if (tag != null) - { - postDtos = await FilterPostsByTag(postDtos, tag); - } - - foreach (var postDto in postDtos) - { - if (postDto.CreatorId.HasValue) + var cacheKey = id.ToString() + "-" + tagName; + + return await _postsCache.GetOrAddAsync( + cacheKey, + async () => await GetPostsByBlogIdAndTagName(id, tagName), + () => new DistributedCacheEntryOptions { - if (!userDictionary.ContainsKey(postDto.CreatorId.Value)) - { - var creatorUser = await UserLookupService.FindByIdAsync(postDto.CreatorId.Value); - if (creatorUser != null) - { - userDictionary[creatorUser.Id] = ObjectMapper.Map(creatorUser); - } - } - - if (userDictionary.ContainsKey(postDto.CreatorId.Value)) - { - postDto.Writer = userDictionary[(Guid)postDto.CreatorId]; - } + AbsoluteExpiration = DateTimeOffset.Now.AddHours(6) } - } - - return new ListResultDto(postDtos); + ); } - + public async Task> GetTimeOrderedListAsync(Guid blogId) { - var posts = await _postRepository.GetOrderedList(blogId); - - var postDtos = new List(ObjectMapper.Map, List>(posts)); - - foreach (var postDto in postDtos) - { - var creatorUser = await UserLookupService.FindByIdAsync(postDto.CreatorId.Value); - if (creatorUser != null) + return await _postsCache.GetOrAddAsync( + blogId.ToString(), + async () => await GetTimeOrderedPostsAsync(blogId), + () => new DistributedCacheEntryOptions { - postDto.Writer = ObjectMapper.Map(creatorUser); + AbsoluteExpiration = DateTimeOffset.Now.AddHours(6) } - } - - return new ListResultDto(postDtos); + ); } public async Task GetForReadingAsync(GetPostInput input) @@ -185,6 +157,64 @@ namespace Volo.Blogging.Posts return ObjectMapper.Map(post); } + private async Task> GetPostsByBlogIdAndTagName(Guid id, string tagName) + { + var posts = await _postRepository.GetPostsByBlogId(id); + var tag = tagName.IsNullOrWhiteSpace() ? null : await _tagRepository.FindByNameAsync(id, tagName); + var userDictionary = new Dictionary(); + var postDtos = new List(ObjectMapper.Map, List>(posts)); + + foreach (var postDto in postDtos) + { + postDto.Tags = await GetTagsOfPost(postDto.Id); + } + + if (tag != null) + { + postDtos = await FilterPostsByTag(postDtos, tag); + } + + foreach (var postDto in postDtos) + { + if (postDto.CreatorId.HasValue) + { + if (!userDictionary.ContainsKey(postDto.CreatorId.Value)) + { + var creatorUser = await UserLookupService.FindByIdAsync(postDto.CreatorId.Value); + if (creatorUser != null) + { + userDictionary[creatorUser.Id] = ObjectMapper.Map(creatorUser); + } + } + + if (userDictionary.ContainsKey(postDto.CreatorId.Value)) + { + postDto.Writer = userDictionary[(Guid)postDto.CreatorId]; + } + } + } + + return new ListResultDto(postDtos); + } + + private async Task> GetTimeOrderedPostsAsync(Guid blogId) + { + var posts = await _postRepository.GetOrderedList(blogId); + + var postDtos = new List(ObjectMapper.Map, List>(posts)); + + foreach (var postDto in postDtos) + { + var creatorUser = await UserLookupService.FindByIdAsync(postDto.CreatorId.Value); + if (creatorUser != null) + { + postDto.Writer = ObjectMapper.Map(creatorUser); + } + } + + return new ListResultDto(postDtos); + } + private async Task RenameUrlIfItAlreadyExistAsync(Guid blogId, string url, Post existingPost = null) { if (await _postRepository.IsPostUrlInUseAsync(blogId, url, existingPost?.Id)) From 92d3e6800bf9cec370fcdad08baecb1f8a15a225 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 4 Mar 2021 15:37:41 +0800 Subject: [PATCH 074/101] Make wpf template logger work --- .../MyCompanyName.MyProjectName/App.xaml.cs | 43 +++++++++---------- .../MainWindow.xaml.cs | 12 ------ .../MyCompanyName.MyProjectName.csproj | 2 +- 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs b/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs index 6ab1bd8c86..686cb5cba1 100644 --- a/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs +++ b/templates/wpf/src/MyCompanyName.MyProjectName/App.xaml.cs @@ -1,9 +1,4 @@ using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; using System.Windows; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -22,19 +17,6 @@ namespace MyCompanyName.MyProjectName private readonly IAbpApplicationWithExternalServiceProvider _application; public App() - { - _host = Host - .CreateDefaultBuilder(null) - .UseAutofac() - .UseSerilog() - .ConfigureServices((hostContext, services) => - { - services.AddApplication(); - }).Build(); - _application = _host.Services.GetService(); - } - - protected async override void OnStartup(StartupEventArgs e) { Log.Logger = new LoggerConfiguration() #if DEBUG @@ -47,6 +29,12 @@ namespace MyCompanyName.MyProjectName .WriteTo.Async(c => c.File("Logs/logs.txt")) .CreateLogger(); + _host = CreateHostBuilder(); + _application = _host.Services.GetService(); + } + + protected override async void OnStartup(StartupEventArgs e) + { try { Log.Information("Starting WPF host."); @@ -60,22 +48,31 @@ namespace MyCompanyName.MyProjectName { Log.Fatal(ex, "Host terminated unexpectedly!"); } - finally - { - Log.CloseAndFlush(); - } } - protected async override void OnExit(ExitEventArgs e) + protected override async void OnExit(ExitEventArgs e) { _application.Shutdown(); await _host.StopAsync(); _host.Dispose(); + Log.CloseAndFlush(); } private void Initialize(IServiceProvider serviceProvider) { _application.Initialize(serviceProvider); } + + private IHost CreateHostBuilder() + { + return Host + .CreateDefaultBuilder(null) + .UseAutofac() + .UseSerilog() + .ConfigureServices((hostContext, services) => + { + services.AddApplication(); + }).Build(); + } } } diff --git a/templates/wpf/src/MyCompanyName.MyProjectName/MainWindow.xaml.cs b/templates/wpf/src/MyCompanyName.MyProjectName/MainWindow.xaml.cs index be1004415d..a8244aa270 100644 --- a/templates/wpf/src/MyCompanyName.MyProjectName/MainWindow.xaml.cs +++ b/templates/wpf/src/MyCompanyName.MyProjectName/MainWindow.xaml.cs @@ -1,17 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace MyCompanyName.MyProjectName { diff --git a/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj b/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj index c1a57201f4..75a7074db5 100644 --- a/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj +++ b/templates/wpf/src/MyCompanyName.MyProjectName/MyCompanyName.MyProjectName.csproj @@ -14,7 +14,7 @@ - + From f3b08e63f2ca69d547ee16f5e707e943616e2a67 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 11:12:50 +0300 Subject: [PATCH 075/101] CmsKit - Add missin [Serializable] attribute to EntityNotCommentableException --- .../Volo/CmsKit/Comments/EntityNotCommentableException.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs index 12c3c872fc..ee1a8621bb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/EntityNotCommentableException.cs @@ -8,6 +8,7 @@ using Volo.Abp; namespace Volo.CmsKit.Comments { + [Serializable] public class EntityNotCommentableException : BusinessException { public EntityNotCommentableException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) From 96e84af31b58e6887dd28c734a6319f14a5c85fc Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 11:23:00 +0300 Subject: [PATCH 076/101] CmsKit - Add missing Checks in CommentsManager --- .../Volo/CmsKit/Comments/CommentManager.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs index 59a3664e09..bbc44c4d06 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentManager.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; + +using JetBrains.Annotations; using System; using System.Threading.Tasks; using Volo.Abp; @@ -23,6 +24,9 @@ namespace Volo.CmsKit.Comments [CanBeNull] Guid? repliedCommentId = null) { Check.NotNull(creator, nameof(creator)); + Check.NotNullOrWhiteSpace(entityType, nameof(entityType), CommentConsts.MaxEntityTypeLength); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId), CommentConsts.MaxEntityIdLength); + Check.NotNullOrWhiteSpace(text, nameof(text), CommentConsts.MaxTextLength); if (!await DefinitionStore.IsDefinedAsync(entityType)) { From 06a318fca3199b0d127db3cfcb58492ae3538688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 4 Mar 2021 11:37:02 +0300 Subject: [PATCH 077/101] Use distributed events to handle role delete & rename for permission management. --- .../Identity/IdentityRoleNameChangedEto.cs | 16 +++++ .../Abp/Identity/AbpIdentityDomainModule.cs | 3 + .../Volo/Abp/Identity/IdentityRole.cs | 12 ++++ .../Identity/IdentityRoleNameChangedEvent.cs | 5 +- .../Identity/RoleDeletedEventHandler.cs | 34 +++++------ .../Identity/RoleUpdateEventHandler.cs | 60 ++++++++----------- 6 files changed, 76 insertions(+), 54 deletions(-) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleNameChangedEto.cs diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleNameChangedEto.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleNameChangedEto.cs new file mode 100644 index 0000000000..b8ae9e537b --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleNameChangedEto.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.Identity +{ + [Serializable] + public class IdentityRoleNameChangedEto + { + public Guid Id { get; set; } + + public Guid? TenantId { get; set; } + + public string Name { get; set; } + + public string OldName { get; set; } + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs index 4326d1aeb8..79f5fb647b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs @@ -40,6 +40,9 @@ namespace Volo.Abp.Identity options.EtoMappings.Add(typeof(AbpIdentityDomainModule)); options.EtoMappings.Add(typeof(AbpIdentityDomainModule)); options.EtoMappings.Add(typeof(AbpIdentityDomainModule)); + + options.AutoEventSelectors.Add(); + options.AutoEventSelectors.Add(); }); var identityBuilder = context.Services.AddAbpIdentity(options => diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs index dac173719a..f856ee2277 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs @@ -108,12 +108,24 @@ namespace Volo.Abp.Identity Name = name; AddLocalEvent( +#pragma warning disable 618 new IdentityRoleNameChangedEvent +#pragma warning restore 618 { IdentityRole = this, OldName = oldName } ); + + AddDistributedEvent( + new IdentityRoleNameChangedEto + { + Id = Id, + Name = Name, + OldName = oldName, + TenantId = TenantId + } + ); } public override string ToString() diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleNameChangedEvent.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleNameChangedEvent.cs index f14f0a71ed..86fc5eab3e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleNameChangedEvent.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleNameChangedEvent.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Identity +using System; + +namespace Volo.Abp.Identity { + [Obsolete("Use the distributed event (IdentityRoleNameChangedEto) instead.")] public class IdentityRoleNameChangedEvent { public IdentityRole IdentityRole { get; set; } diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs index b3fd565b24..6b562a3f16 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs @@ -1,26 +1,26 @@ using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; using Volo.Abp.Identity; namespace Volo.Abp.PermissionManagement.Identity { - // public class RoleDeletedEventHandler : - // ILocalEventHandler>, - // ITransientDependency - // { - // protected IPermissionManager PermissionManager { get; } - // - // public RoleDeletedEventHandler(IPermissionManager permissionManager) - // { - // PermissionManager = permissionManager; - // } - // - // public virtual async Task HandleEventAsync(EntityDeletedEventData eventData) - // { - // await PermissionManager.DeleteAsync(RolePermissionValueProvider.ProviderName, eventData.Entity.Name); - // } - // } + public class RoleDeletedEventHandler : + ILocalEventHandler>, + ITransientDependency + { + protected IPermissionManager PermissionManager { get; } + + public RoleDeletedEventHandler(IPermissionManager permissionManager) + { + PermissionManager = permissionManager; + } + + public async Task HandleEventAsync(EntityDeletedEto eventData) + { + await PermissionManager.DeleteAsync(RolePermissionValueProvider.ProviderName, eventData.Entity.Name); + } + } } diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs index 18612bcfad..d2d25ec3e8 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleUpdateEventHandler.cs @@ -1,45 +1,33 @@ using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities.Events; -using Volo.Abp.EventBus; +using Volo.Abp.EventBus.Distributed; using Volo.Abp.Identity; namespace Volo.Abp.PermissionManagement.Identity { - //TODO: This code can not be here! + public class RoleUpdateEventHandler : + IDistributedEventHandler, + ITransientDependency + { + protected IPermissionManager PermissionManager { get; } + protected IPermissionGrantRepository PermissionGrantRepository { get; } + + public RoleUpdateEventHandler( + IPermissionManager permissionManager, + IPermissionGrantRepository permissionGrantRepository) + { + PermissionManager = permissionManager; + PermissionGrantRepository = permissionGrantRepository; + } - // public class RoleUpdateEventHandler : - // ILocalEventHandler, - // ITransientDependency - // { - // protected IIdentityRoleRepository RoleRepository { get; } - // protected IPermissionManager PermissionManager { get; } - // protected IPermissionGrantRepository PermissionGrantRepository { get; } - // - // public RoleUpdateEventHandler( - // IIdentityRoleRepository roleRepository, - // IPermissionManager permissionManager, - // IPermissionGrantRepository permissionGrantRepository) - // { - // RoleRepository = roleRepository; - // PermissionManager = permissionManager; - // PermissionGrantRepository = permissionGrantRepository; - // } - // - // public virtual async Task HandleEventAsync(IdentityRoleNameChangedEvent eventData) - // { - // var role = await RoleRepository.FindAsync(eventData.IdentityRole.Id, false); - // if (role == null) - // { - // return; - // } - // - // var permissionGrantsInRole = await PermissionGrantRepository.GetListAsync(RolePermissionValueProvider.ProviderName, eventData.OldName); - // foreach (var permissionGrant in permissionGrantsInRole) - // { - // await PermissionManager.UpdateProviderKeyAsync(permissionGrant, eventData.IdentityRole.Name); - // } - // } - // } + public async Task HandleEventAsync(IdentityRoleNameChangedEto eventData) + { + var permissionGrantsInRole = await PermissionGrantRepository.GetListAsync(RolePermissionValueProvider.ProviderName, eventData.OldName); + foreach (var permissionGrant in permissionGrantsInRole) + { + await PermissionManager.UpdateProviderKeyAsync(permissionGrant, eventData.Name); + } + } + } } From 833c4c16eae932e084114504fac4f8a0a532a17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 4 Mar 2021 11:56:09 +0300 Subject: [PATCH 078/101] Should invalidate the cache for old permission provider key. --- .../PermissionGrantCacheItemInvalidator.cs | 4 +++- .../PermissionManagement/PermissionManager.cs | 22 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItemInvalidator.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItemInvalidator.cs index 9e73e59b79..585c0a0559 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItemInvalidator.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItemInvalidator.cs @@ -7,7 +7,9 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.PermissionManagement { - public class PermissionGrantCacheItemInvalidator : ILocalEventHandler>, ITransientDependency + public class PermissionGrantCacheItemInvalidator : + ILocalEventHandler>, + ITransientDependency { protected ICurrentTenant CurrentTenant { get; } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs index fc8da0c6c5..1f1e28dfd4 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; @@ -24,6 +25,8 @@ namespace Volo.Abp.PermissionManagement protected IReadOnlyList ManagementProviders => _lazyProviders.Value; protected PermissionManagementOptions Options { get; } + + protected IDistributedCache Cache { get; } private readonly Lazy> _lazyProviders; @@ -33,10 +36,12 @@ namespace Volo.Abp.PermissionManagement IServiceProvider serviceProvider, IGuidGenerator guidGenerator, IOptions options, - ICurrentTenant currentTenant) + ICurrentTenant currentTenant, + IDistributedCache cache) { GuidGenerator = guidGenerator; CurrentTenant = currentTenant; + Cache = cache; PermissionGrantRepository = permissionGrantRepository; PermissionDefinitionManager = permissionDefinitionManager; Options = options.Value; @@ -104,9 +109,21 @@ namespace Volo.Abp.PermissionManagement await provider.SetAsync(permissionName, providerKey, isGranted); } - + public virtual async Task UpdateProviderKeyAsync(PermissionGrant permissionGrant, string providerKey) { + using (CurrentTenant.Change(permissionGrant.TenantId)) + { + //Invalidating the cache for the old key + await Cache.RemoveAsync( + PermissionGrantCacheItem.CalculateCacheKey( + permissionGrant.Name, + permissionGrant.ProviderName, + permissionGrant.ProviderKey + ) + ); + } + permissionGrant.ProviderKey = providerKey; return await PermissionGrantRepository.UpdateAsync(permissionGrant); } @@ -114,7 +131,6 @@ namespace Volo.Abp.PermissionManagement public virtual async Task DeleteAsync(string providerName, string providerKey) { var permissionGrants = await PermissionGrantRepository.GetListAsync(providerName, providerKey); - //TODO: Use DeleteManyAsync method foreach (var permissionGrant in permissionGrants) { await PermissionGrantRepository.DeleteAsync(permissionGrant); From 5f9944f6245179820bb83519b1be090b7d5bca4a Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:10:27 +0300 Subject: [PATCH 079/101] ABP CLI microservice creation should edit tye.yml according to ui type resolves https://github.com/volosoft/volo/issues/5689 --- .../Steps/RemoveProjectFromTyeStep.cs | 54 +++++++++++++++++++ .../Microservice/MicroserviceTemplateBase.cs | 10 ++++ 2 files changed, 64 insertions(+) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs new file mode 100644 index 0000000000..9804ef7c4b --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class RemoveProjectFromTyeStep : ProjectBuildPipelineStep + { + private readonly string _name; + + public RemoveProjectFromTyeStep(string name) + { + _name = name; + } + + public override void Execute(ProjectBuildContext context) + { + var tyeFile = context.Files.FirstOrDefault(f => f.Name == "/tye.yaml"); + + if (tyeFile == null) + { + return; + } + + var lines = tyeFile.Content.SplitToLines(); + var newLines = new List(); + + var nameLine = $"- name:"; + var isOneOfTargetLines = false; + + foreach (var line in lines) + { + if (line.Equals($"{nameLine} {_name}")) + { + isOneOfTargetLines = true; + continue; + } + + if (line.StartsWith(nameLine)) + { + isOneOfTargetLines = false; + } + + if (!isOneOfTargetLines) + { + newLines.Add(line); + } + } + + tyeFile.SetContent(String.Join(Environment.NewLine, newLines)); + } + + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs index 0a56f5272a..1efbe09ff1 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs @@ -36,9 +36,13 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, "/applications/web/src/MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveFolderStep("/applications/web")); + steps.Add(new RemoveProjectFromTyeStep("web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); steps.Add(new RemoveFolderStep("/applications/blazor")); + steps.Add(new RemoveProjectFromTyeStep("blazor")); + steps.Add(new RemoveFolderStep("/angular")); break; @@ -46,9 +50,12 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, "/applications/web/src/MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveFolderStep("/applications/web")); + steps.Add(new RemoveProjectFromTyeStep("web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); steps.Add(new RemoveFolderStep("/applications/blazor")); + steps.Add(new RemoveProjectFromTyeStep("blazor")); break; case UiFramework.Blazor: @@ -56,6 +63,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice "/applications/web/src/MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveFolderStep("/applications/web")); steps.Add(new RemoveFolderStep("/angular")); + steps.Add(new RemoveProjectFromTyeStep("web")); break; case UiFramework.Mvc: @@ -63,6 +71,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); steps.Add(new RemoveFolderStep("/applications/blazor")); + steps.Add(new RemoveProjectFromTyeStep("blazor")); + steps.Add(new RemoveFolderStep("/angular")); break; } From a44f9a1a8c2596efb81f62dd89ebf977fb90d52f Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:17:49 +0300 Subject: [PATCH 080/101] Cli SolutionRenameStep: rename lowercase --- .../Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs index 1ea30fe783..7da16ae8f3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs @@ -90,6 +90,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps RenameHelper.RenameAll(_entries, _projectNamePlaceHolder, _projectName); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToCamelCase(), _projectName.ToCamelCase()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToKebabCase(), _projectName.ToKebabCase()); + RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToLowerInvariant(), _projectName.ToLowerInvariant()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToSnakeCase().ToUpper(), _projectName.ToSnakeCase().ToUpper()); } } From 96f0c03fd84f77798a662227d81a3f7419c30cb3 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:22:10 +0300 Subject: [PATCH 081/101] Update RemoveProjectFromTyeStep.cs --- .../ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs index 9804ef7c4b..1c51e22bc9 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps return; } - var lines = tyeFile.Content.SplitToLines(); + var lines = tyeFile.GetLines(); var newLines = new List(); var nameLine = $"- name:"; From 003eca038f10909a185c4ca9d2faa2e56508556c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:26:59 +0300 Subject: [PATCH 082/101] Revert "Cli SolutionRenameStep: rename lowercase" This reverts commit a44f9a1a8c2596efb81f62dd89ebf977fb90d52f. --- .../Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs index 7da16ae8f3..1ea30fe783 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs @@ -90,7 +90,6 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps RenameHelper.RenameAll(_entries, _projectNamePlaceHolder, _projectName); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToCamelCase(), _projectName.ToCamelCase()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToKebabCase(), _projectName.ToKebabCase()); - RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToLowerInvariant(), _projectName.ToLowerInvariant()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToSnakeCase().ToUpper(), _projectName.ToSnakeCase().ToUpper()); } } From 5bb7cf4bfe242f111df546034190ec524932b3d8 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:37:44 +0300 Subject: [PATCH 083/101] Cli: optimize remover resolves https://github.com/abpframework/abp/issues/7938 --- .../Building/Steps/RemoveCmsKitStep.cs | 8 ++------ .../Steps/RemoveEfCoreDependencyFromPublicStep.cs | 9 +++++++-- .../Steps/RemoveGlobalFeaturesPackageStep.cs | 11 +++++++++-- .../Building/Steps/RemovePublicRedisStep.cs | 14 +++++--------- .../ProjectBuilding/Files/FileEntryExtensions.cs | 10 ++++++++++ 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs index 789f9e47cb..93bb454c4d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs @@ -9,12 +9,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { var commonFiles = context.Files.Where(f => f.Name.EndsWith(".csproj") || - f.Name.EndsWith("Module.cs") || - f.Name.EndsWith("MyProjectNameMigrationsDbContext.cs") || - f.Name.EndsWith("MyProjectNameMigrationsDbContextBase.cs") || - f.Name.EndsWith("MyProjectNameGlobalFeatureConfigurator.cs") || - (f.Name.EndsWith(".cshtml") && f.Name.Contains("MyCompanyName.MyProjectName.Web.Public")) - ); + f.Name.EndsWith(".cs") || + f.Name.EndsWith(".cshtml")); foreach (var file in commonFiles) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs index f9e906c902..1f7b8f4e6f 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs @@ -7,8 +7,13 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { public override void Execute(ProjectBuildContext context) { - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.Web.Public.csproj"))?.RemoveTemplateCodeIfNot("EFCORE"); - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameWebPublicModule.cs"))?.RemoveTemplateCodeIfNot("EFCORE"); + foreach (var file in context.Files) + { + if (file.Name.EndsWith(".cs") || file.Name.EndsWith(".csproj") || file.Name.EndsWith(".json")) + { + file.RemoveTemplateCodeIfNot("EFCORE"); + } + } } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs index 06fd565353..15a84576c6 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs @@ -7,8 +7,15 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { public override void Execute(ProjectBuildContext context) { - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.Domain.Shared.csproj"))?.RemoveTemplateCodeIf("CMS-KIT"); - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameDomainSharedModule.cs"))?.RemoveTemplateCodeIf("CMS-KIT"); + var commonFiles = context.Files.Where(f => + f.Name.EndsWith(".csproj") || + f.Name.EndsWith(".cs") || + f.Name.EndsWith(".cshtml")); + + foreach (var file in commonFiles) + { + file.RemoveTemplateCodeIf("CMS-KIT"); + } } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs index 1299f5b15d..eced4fd3e5 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs @@ -8,16 +8,12 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { public override void Execute(ProjectBuildContext context) { - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.Web.csproj"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameWebModule.cs"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.HttpApi.Host.csproj"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); - context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameHttpApiHostModule.cs"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); - - var appSettingsFiles = context.Files.Where(f => f.Name.EndsWith("appSettings.json", StringComparison.InvariantCultureIgnoreCase)).ToList(); - foreach (var appSettings in appSettingsFiles) + foreach (var file in context.Files) { - appSettings.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + if (file.Name.EndsWith(".cs") || file.Name.EndsWith(".csproj") || file.Name.EndsWith(".json")) + { + file.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + } } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs index 91180206bf..34200d41ac 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs @@ -28,6 +28,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Files public static void RemoveTemplateCodeMarkers(this FileEntry file) { + if (!file.Content.Contains("")) + { + return; + } + file.NormalizeLineEndings(); var lines = file.GetLines(); @@ -59,6 +64,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Files private static void RemoveMarkedTemplateCode(this FileEntry file, string beginMark) { + if (!file.Content.Contains("")) + { + return; + } + file.NormalizeLineEndings(); var lines = file.GetLines(); From 81540b4943891667ee79554565139ebd190a0444 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Thu, 4 Mar 2021 15:37:48 +0300 Subject: [PATCH 084/101] Update en.json --- .../AbpIoLocalization/Admin/Localization/Resources/en.json | 1 + 1 file changed, 1 insertion(+) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 0ada3327df..51d818aad7 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -91,6 +91,7 @@ "UserNotFound": "User not found", "{0}WillBeRemovedFromDevelopers": "{0} Will be removed from developers, do you confirm?", "{0}WillBeRemovedFromOwners": "{0} Will be removed from owners, do you confirm?", + "{0}WillBeRemovedFromMembers": "{0} Will be removed from members, do you confirm?", "Computers": "Computers", "UniqueComputerId": "Unique computer id", "LastSeenDate": "Last seen date", From a0a9f85253613723519dc7085e5582c814c09c63 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 16:00:55 +0300 Subject: [PATCH 085/101] CmsKit - Fix ShortDescription generation for BlogPost --- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js index e1e132e2a0..977c90fde0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/create.js @@ -8,7 +8,7 @@ var $shortDescription = $('#ViewModel_ShortDescription'); var $url = $('#ViewModel_Slug'); var $buttonSubmit = $('#button-blog-post-create'); - var $pageContentInput = $('#ViewModel_Value'); + var $pageContentInput = $('#ViewModel_Content'); var $tagsInput = $('.tag-editor-form input[name=tags]'); var $fileInput = $('#BlogPostCoverImage'); var $tagsWrapper = $('#blog-post-tags-wrapper'); From 3e13a547c349b0fa8a05cc8d3a2e14dc9eb71d9c Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 16:03:35 +0300 Subject: [PATCH 086/101] CmsKit - Fix permission tree --- .../Permissions/CmsKitAdminPermissionDefinitionProvider.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs index a8317b6b6b..284ce15827 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs @@ -52,9 +52,9 @@ namespace Volo.CmsKit.Permissions blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Features, L("Permission:BlogManagement.Features")); var blogPostManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.BlogPosts.Default, L("Permission:BlogPostManagement")); - blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Create, L("Permission:BlogPostManagement.Create")); - blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Update, L("Permission:BlogPostManagement.Update")); - blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Delete, L("Permission:BlogPostManagement.Delete")); + blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Create, L("Permission:BlogPostManagement.Create")); + blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Update, L("Permission:BlogPostManagement.Update")); + blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Delete, L("Permission:BlogPostManagement.Delete")); } } From 0b17b2fb7229d6decb385939449ee97d0ee79efe Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 16:13:50 +0300 Subject: [PATCH 087/101] CmsKit - Routing fix --- .../cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs | 2 +- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js | 2 +- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js | 2 +- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js | 4 ++-- .../src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs index 25dd69cd63..ed162cc360 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs @@ -82,7 +82,7 @@ namespace Volo.CmsKit.Admin.Web options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Create", "/Cms/BlogPosts/Create"); options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update/{Id}"); options.Conventions.AddPageRoute("/CmsKit/Comments/Index", "/Cms/Comments"); - options.Conventions.AddPageRoute("/CmsKit/Comments/Details", "/Cms/Details"); + options.Conventions.AddPageRoute("/CmsKit/Comments/Details", "/Cms/Comments/{Id}"); }); Configure(options => diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js index c4453c1a9c..c2a9c7d364 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Comments/index.js @@ -60,7 +60,7 @@ { text: l('Details'), action: function (data) { - window.location = abp.appPath + 'CmsKit/Comments/Details/' + data.record.id; + location.href = 'Comments/' + data.record.id; } }, { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js index 029ab189cd..5872dad438 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/create.js @@ -19,7 +19,7 @@ success: function (result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = "/CmsKit/Pages/"; + location.href = "../Pages"; } }); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js index 4d4ea4c9e3..828da9c55c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/index.js @@ -30,7 +30,7 @@ text: l('Edit'), visible: abp.auth.isGranted('CmsKit.Pages.Update'), action: function (data) { - location.href = '/CmsKit/Pages/Update/' + data.record.id; + location.href = 'Pages/Update/' + data.record.id; } }, { @@ -76,6 +76,6 @@ $('#AbpContentToolbar button[name=CreatePage]').on('click', function (e) { e.preventDefault(); - window.location.href = "/CmsKit/Pages/Create" + window.location.href = "Pages/Create" }); }); \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js index 1dd4734150..8e8ba3d85d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/update.js @@ -18,7 +18,7 @@ success: function (result) { abp.notify.success(l('SuccessfullySaved')); abp.ui.clearBusy(); - location.href = "/CmsKit/Pages/"; + location.href = "../../Pages"; } }); } From 2b9b56a75bca7adc4242fa411398ba2ce6318aed Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 4 Mar 2021 21:54:25 +0800 Subject: [PATCH 088/101] Add unit tests --- .../Identity/RoleDeletedEventHandler.cs | 7 +- .../Distributed_Role_Change_Events_Test.cs | 105 ++++++++++++++++++ .../Abp/Identity/RoleChangingEvents_Test.cs | 60 ---------- 3 files changed, 109 insertions(+), 63 deletions(-) create mode 100644 modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/Distributed_Role_Change_Events_Test.cs delete mode 100644 modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/RoleChangingEvents_Test.cs diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs index 6b562a3f16..4a25abea50 100644 --- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs +++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs @@ -3,21 +3,22 @@ using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; +using Volo.Abp.EventBus.Distributed; using Volo.Abp.Identity; namespace Volo.Abp.PermissionManagement.Identity { public class RoleDeletedEventHandler : - ILocalEventHandler>, + IDistributedEventHandler>, ITransientDependency { protected IPermissionManager PermissionManager { get; } - + public RoleDeletedEventHandler(IPermissionManager permissionManager) { PermissionManager = permissionManager; } - + public async Task HandleEventAsync(EntityDeletedEto eventData) { await PermissionManager.DeleteAsync(RolePermissionValueProvider.ProviderName, eventData.Entity.Name); diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/Distributed_Role_Change_Events_Test.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/Distributed_Role_Change_Events_Test.cs new file mode 100644 index 0000000000..a57a8baf69 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/Distributed_Role_Change_Events_Test.cs @@ -0,0 +1,105 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Identity; +using Shouldly; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Volo.Abp.Caching; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.PermissionManagement; +using Volo.Abp.PermissionManagement.Identity; +using Volo.Abp.Uow; +using Xunit; + +namespace Volo.Abp.Identity +{ + public class Distributed_Role_Change_Events_Test : AbpIdentityDomainTestBase + { + protected readonly IIdentityRoleRepository RoleRepository; + protected readonly IPermissionGrantRepository PermissionGrantRepository; + protected readonly IdentityRoleManager RoleManager; + protected readonly ILookupNormalizer LookupNormalizer; + protected readonly IUnitOfWorkManager UowManager; + protected readonly IDistributedCache Cache; + + public Distributed_Role_Change_Events_Test() + { + RoleRepository = GetRequiredService(); + ; + PermissionGrantRepository = GetRequiredService(); + ; + RoleManager = GetRequiredService(); + ; + LookupNormalizer = GetRequiredService(); + ; + UowManager = GetRequiredService(); + Cache = GetRequiredService>(); + } + + [Fact] + public void Should_Register_Handler() + { + var x = GetRequiredService>(); + GetRequiredService>() + .Value + .AutoEventSelectors + .ShouldContain(m => m.Name == "Entity:" + typeof(IdentityRole).FullName); + + GetRequiredService>() + .Value + .Handlers + .ShouldContain(h => h == typeof(RoleUpdateEventHandler) || h == typeof(RoleDeletedEventHandler)); + } + + [Fact] + public async Task Role_Updated_Distributed_Event_Test() + { + var role = await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName("moderator")); + + var permissionGrantsInRole = await PermissionGrantRepository.GetListAsync("R", role.Name); + permissionGrantsInRole.ShouldNotBeNull(); + permissionGrantsInRole.Count.ShouldBeGreaterThan(0); + var count = permissionGrantsInRole.Count; + + using (var uow = UowManager.Begin()) + { + var identityResult = await RoleManager.SetRoleNameAsync(role, "TestModerator"); + identityResult.Succeeded.ShouldBeTrue(); + await RoleRepository.UpdateAsync(role); + await uow.CompleteAsync(); + } + + role = await RoleRepository.GetAsync(role.Id); + role.Name.ShouldBe("TestModerator"); + + permissionGrantsInRole = await PermissionGrantRepository.GetListAsync("R", role.Name); + permissionGrantsInRole.Count.ShouldBe(count); + } + + [Fact] + public async Task Role_Deleted_Distributed_Event_Test() + { + var role = await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName("moderator")); + var permissionGrantsInRole = await PermissionGrantRepository.GetListAsync("R", role.Name); + + var caches = permissionGrantsInRole.Select(x => new KeyValuePair( + PermissionGrantCacheItem.CalculateCacheKey(x.Name, x.ProviderName, x.ProviderKey), + new PermissionGrantCacheItem(true))).ToList(); + await Cache.SetManyAsync(caches); + + + using (var uow = UowManager.Begin()) + { + await RoleRepository.DeleteAsync(role); + await uow.CompleteAsync(); + } + + var permissionGrantCaches = await Cache.GetManyAsync(caches.Select(x=>x.Key)); + foreach (var cache in permissionGrantCaches) + { + cache.Value.ShouldBeNull(); + } + } + } +} diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/RoleChangingEvents_Test.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/RoleChangingEvents_Test.cs deleted file mode 100644 index a668b5ff4f..0000000000 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/RoleChangingEvents_Test.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using Shouldly; -using System.Threading.Tasks; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.Guids; -using Volo.Abp.PermissionManagement; -using Volo.Abp.Uow; -using Xunit; - -namespace Volo.Abp.Identity -{ - //TODO: This code can not be here! - //https://github.com/abpframework/abp/commit/847f526041145b62376b760776829d5ce257da1c - // public class RoleChangingEvents_Test : AbpIdentityDomainTestBase - // { - // protected readonly IIdentityRoleRepository RoleRepository; - // protected readonly IPermissionGrantRepository PermissionGrantRepository; - // protected readonly IdentityRoleManager RoleManager; - // protected readonly ILookupNormalizer LookupNormalizer; - // protected readonly IGuidGenerator GuidGenerator; - // protected readonly IUnitOfWorkManager UowManager; - // - // public RoleChangingEvents_Test() - // { - // RoleRepository = GetRequiredService(); ; - // PermissionGrantRepository = GetRequiredService(); ; - // RoleManager = GetRequiredService(); ; - // LookupNormalizer = GetRequiredService(); ; - // GuidGenerator = GetRequiredService(); - // UowManager = GetRequiredService(); - // } - // - // [Fact(Skip = "https://github.com/abpframework/abp/actions/runs/454248191")] - // public async Task Role_Update_Event_Test() - // { - // var role = await RoleRepository - // .FindByNormalizedNameAsync(LookupNormalizer.NormalizeName("moderator")) - // ; - // - // var permissionGrantsInRole = await PermissionGrantRepository.GetListAsync("R", role.Name); - // permissionGrantsInRole.ShouldNotBeNull(); - // permissionGrantsInRole.Count.ShouldBeGreaterThan(0); - // var count = permissionGrantsInRole.Count; - // - // using (var uow = UowManager.Begin()) - // { - // var identityResult = await RoleManager.SetRoleNameAsync(role, "TestModerator"); - // identityResult.Succeeded.ShouldBeTrue(); - // var xx = await RoleRepository.UpdateAsync(role); - // await uow.CompleteAsync(); - // } - // - // role = await RoleRepository.GetAsync(role.Id); - // role.Name.ShouldBe("TestModerator"); - // - // permissionGrantsInRole = await PermissionGrantRepository.GetListAsync("R", role.Name); - // permissionGrantsInRole.Count.ShouldBe(count); - // } - // } -} From e6c02dd8d71ac81a6f8c86a929780340d52df358 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 17:11:11 +0300 Subject: [PATCH 089/101] Update CmsKit npm package --- npm/packs/cms-kit/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/npm/packs/cms-kit/package.json b/npm/packs/cms-kit/package.json index 47f4efcc75..e539cf68c8 100644 --- a/npm/packs/cms-kit/package.json +++ b/npm/packs/cms-kit/package.json @@ -5,7 +5,9 @@ "access": "public" }, "dependencies": { - "@abp/star-rating-svg": "~4.2.1" + "@abp/star-rating-svg": "~4.2.1", + "@abp/tui-editor": "^4.2.1", + "slugify": "^1.4.7" }, "gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431" } From 6fe057ca0b37b1394f31f6e54838f9f7122bcc59 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Mar 2021 17:11:36 +0300 Subject: [PATCH 090/101] Update tui-editor npm package --- npm/packs/tui-editor/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/npm/packs/tui-editor/package.json b/npm/packs/tui-editor/package.json index 968d9d58c8..28176e5742 100644 --- a/npm/packs/tui-editor/package.json +++ b/npm/packs/tui-editor/package.json @@ -12,5 +12,8 @@ "tui-editor": "^1.4.10", "tui-code-snippet": "^2.3.2" }, + "resolutions": { + "jquery": "3.4.1" + }, "gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431" } From 0eae7d569ee258628da9a3145ed4eab888be4a7b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 17:17:45 +0300 Subject: [PATCH 091/101] Cli: RemoveCmsKitStep json files --- .../Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs index 93bb454c4d..a0778d5a4d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs @@ -10,6 +10,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var commonFiles = context.Files.Where(f => f.Name.EndsWith(".csproj") || f.Name.EndsWith(".cs") || + f.Name.EndsWith(".json") || f.Name.EndsWith(".cshtml")); foreach (var file in commonFiles) From c7404550eb774cb1efc8d910c7814c1d95e550b6 Mon Sep 17 00:00:00 2001 From: tanyongzheng Date: Fri, 5 Mar 2021 11:37:34 +0800 Subject: [PATCH 092/101] docs:Update Repositories.md --- docs/zh-Hans/Repositories.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-Hans/Repositories.md b/docs/zh-Hans/Repositories.md index 79186b79da..857df51439 100644 --- a/docs/zh-Hans/Repositories.md +++ b/docs/zh-Hans/Repositories.md @@ -150,7 +150,7 @@ var people = _personRepository * 这里异步方法**不是标准LINQ方法**,它们定义在[Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore)Nuget包中. * 标准模板应用层与领域层**不引用**EF Core 包以实现数据库提供程序独立. -根据你的需求和开发模式,你可以根据以下选项使用异步方法.s +根据你的需求和开发模式,你可以根据以下选项使用异步方法. > 强烈建议使用异步方法! 在执行数据库查询时不要使用同步LINQ方法,以便能够开发可伸缩的应用程序. From ab0253ea415bd3a26c8e2d2fde2f59bb2a1d6cb8 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 5 Mar 2021 15:57:47 +0800 Subject: [PATCH 093/101] Add tui-editor-jquery-patch.js. --- .../UI/Packages/TuiEditor/TuiEditorScriptContributor.cs | 1 + npm/packs/tui-editor/abp.resourcemapping.js | 3 ++- npm/packs/tui-editor/src/tui-editor-jquery-patch.js | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 npm/packs/tui-editor/src/tui-editor-jquery-patch.js diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/TuiEditor/TuiEditorScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/TuiEditor/TuiEditorScriptContributor.cs index e788c612cf..e2e826445f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/TuiEditor/TuiEditorScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/TuiEditor/TuiEditorScriptContributor.cs @@ -16,6 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor { public override void ConfigureBundle(BundleConfigurationContext context) { + context.Files.AddIfNotContains("/libs/tui-editor/tui-editor-jquery-patch.js"); context.Files.AddIfNotContains("/libs/to-mark/to-mark.min.js"); if (context.FileProvider.GetFileInfo("/libs/tui-code-snippet/tui-code-snippet.min.js").Exists) diff --git a/npm/packs/tui-editor/abp.resourcemapping.js b/npm/packs/tui-editor/abp.resourcemapping.js index 53a3e493f7..a1d944d7f1 100644 --- a/npm/packs/tui-editor/abp.resourcemapping.js +++ b/npm/packs/tui-editor/abp.resourcemapping.js @@ -3,6 +3,7 @@ "@node_modules/to-mark/dist/to-mark.min.js": "@libs/to-mark/", "@node_modules/tui-code-snippet/dist/*.*": "@libs/tui-code-snippet/", "@node_modules/squire-rte/build/squire.js": "@libs/squire-rte/", - "@node_modules/tui-editor/dist/*.*": "@libs/tui-editor/" + "@node_modules/tui-editor/dist/*.*": "@libs/tui-editor/", + "@node_modules/@abp/tui-editor/src/*.*": "@libs/tui-editor/" } } \ No newline at end of file diff --git a/npm/packs/tui-editor/src/tui-editor-jquery-patch.js b/npm/packs/tui-editor/src/tui-editor-jquery-patch.js new file mode 100644 index 0000000000..1033d18992 --- /dev/null +++ b/npm/packs/tui-editor/src/tui-editor-jquery-patch.js @@ -0,0 +1,7 @@ +/* + https://jquery.com/upgrade-guide/3.5/#jquery-htmlprefilter-changes +*/ +var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi; +jQuery.htmlPrefilter = function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); +}; From 6b3fdaf68bed96a29ec75f325f64af9290d1de9a Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Mar 2021 11:03:14 +0300 Subject: [PATCH 094/101] Remove custom resolutions section from tui-editor package.json --- npm/packs/tui-editor/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/npm/packs/tui-editor/package.json b/npm/packs/tui-editor/package.json index 28176e5742..968d9d58c8 100644 --- a/npm/packs/tui-editor/package.json +++ b/npm/packs/tui-editor/package.json @@ -12,8 +12,5 @@ "tui-editor": "^1.4.10", "tui-code-snippet": "^2.3.2" }, - "resolutions": { - "jquery": "3.4.1" - }, "gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431" } From 4d9f49d25bb71ae8280e22d1bff3d59d957380d7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 5 Mar 2021 12:02:24 +0300 Subject: [PATCH 095/101] Set random port when a new Microservice is created resolves https://github.com/volosoft/volo/issues/5716 --- .../MicroserviceServiceRandomPortStep.cs | 78 +++++++++++++++++++ .../MicroserviceServiceTemplateBase.cs | 6 ++ 2 files changed, 84 insertions(+) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs new file mode 100644 index 0000000000..88a19b43af --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs @@ -0,0 +1,78 @@ +using System; +using System.IO; +using System.Linq; +using Volo.Abp.Cli.Commands; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class MicroserviceServiceRandomPortStep : ProjectBuildPipelineStep + { + private readonly string _defaultPort = string.Empty; + private string _tyeFileContent = null; + + public MicroserviceServiceRandomPortStep(string defaultPort) + { + _defaultPort = defaultPort; + } + + public override void Execute(ProjectBuildContext context) + { + var newPort = GetNewRandomPort(context); + + var targetFiles = context.Files.Where(f=> f.Name.EndsWith("launchSettings.json") || f.Name.EndsWith("appsettings.json")).ToList(); + + foreach (var file in targetFiles) + { + file.SetContent(file.Content.Replace(_defaultPort, newPort)); + } + } + + private string GetNewRandomPort(ProjectBuildContext context) + { + string newPort; + var rnd = new Random(); + var tryCount = 0; + + do + { + newPort = rnd.Next(44350, 45350).ToString(); + + if (tryCount++ > 2000) + { + break; + } + + } while (PortExistsForAnotherService(context, newPort)); + + return newPort; + } + + private bool PortExistsForAnotherService(ProjectBuildContext context, string newPort) + { + return ReadTyeFileContent(context).SplitToLines().Any(l => l.Contains("port") && l.Contains(newPort)); + } + + private string ReadTyeFileContent(ProjectBuildContext context) + { + if (_tyeFileContent != null) + { + return _tyeFileContent; + } + + var solutionFolderPath = context.BuildArgs.ExtraProperties[NewCommand.Options.OutputFolder.Short] ?? + context.BuildArgs.ExtraProperties[NewCommand.Options.OutputFolder.Long] ?? + Directory.GetCurrentDirectory(); + + var tyeFilePath = Path.Combine(solutionFolderPath, "tye.yaml"); + + if (!File.Exists(tyeFilePath)) + { + return String.Empty; + } + + _tyeFileContent = File.ReadAllText(tyeFilePath); + + return _tyeFileContent; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs index de589336b0..54ec4894b9 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs @@ -31,6 +31,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice var steps = new List(); DeleteUnrelatedUiProject(context, steps); + SetRandomPortForHostProject(context, steps); RandomizeStringEncryption(context, steps); return steps; @@ -54,6 +55,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice } } + private static void SetRandomPortForHostProject(ProjectBuildContext context, List steps) + { + steps.Add(new MicroserviceServiceRandomPortStep("44371")); + } + private static void RandomizeStringEncryption(ProjectBuildContext context, List steps) { steps.Add(new RandomizeStringEncryptionStep()); From b41804e37c227c1c517edd05603eff3500d2160d Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Mar 2021 13:36:32 +0300 Subject: [PATCH 096/101] CmsKit - Fix MediaDescriptor mismatching Id --- .../Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index 45774ca1f2..ab7d841cad 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -35,12 +35,11 @@ namespace Volo.CmsKit.Admin.MediaDescriptors await CheckAnyOfPoliciesAsync(definition.CreatePolicies); - var newId = GuidGenerator.Create(); using (var stream = inputStream.GetStream()) { var newEntity = await MediaDescriptorManager.CreateAsync(inputStream.EntityType, inputStream.Name, inputStream.ContentType, inputStream.ContentLength ?? 0); - await MediaContainer.SaveAsync(newId.ToString(), stream); + await MediaContainer.SaveAsync(newEntity.Id.ToString(), stream); await MediaDescriptorRepository.InsertAsync(newEntity); return ObjectMapper.Map(newEntity); From c177530c5ea46b35bedafc2c1d02f4ff4d86be77 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 5 Mar 2021 13:37:11 +0300 Subject: [PATCH 097/101] Handle abbreviations like XYZ when converting to camel-case. issue #7951 --- .../System/AbpStringExtensions.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs b/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs index f272484611..5fe47112ba 100644 --- a/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs @@ -260,8 +260,9 @@ namespace System /// /// String to convert /// set true to use current culture. Otherwise, invariant culture will be used. + /// set true to if you want to convert 'XYZ' to 'xyz'. /// camelCase of the string - public static string ToCamelCase(this string str, bool useCurrentCulture = false) + public static string ToCamelCase(this string str, bool useCurrentCulture = false, bool handleAbbreviations = false) { if (string.IsNullOrWhiteSpace(str)) { @@ -273,6 +274,11 @@ namespace System return useCurrentCulture ? str.ToLower() : str.ToLowerInvariant(); } + if (handleAbbreviations && IsAllUpperCase(str)) + { + return useCurrentCulture ? str.ToLower() : str.ToLowerInvariant(); + } + return (useCurrentCulture ? char.ToLower(str[0]) : char.ToLowerInvariant(str[0])) + str.Substring(1); } @@ -545,5 +551,18 @@ namespace System return encoding.GetBytes(str); } + + private static bool IsAllUpperCase(string input) + { + for (int i = 0; i < input.Length; i++) + { + if (Char.IsLetter(input[i]) && !Char.IsUpper(input[i])) + { + return false; + } + } + + return true; + } } } From a09a7ac659d08b50080b78e8743287aea01ee3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Mar 2021 14:30:52 +0300 Subject: [PATCH 098/101] Revise title for blog and page. --- .../CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml | 2 +- .../Pages/CmsKit/Shared/Components/Pages/Default.cshtml | 4 +--- .../Pages/Public/CmsKit/Blogs/BlogPost.cshtml | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml index 0ed8987d72..f5c1bdc3a5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml @@ -4,10 +4,10 @@ @inject IStringLocalizer L +

@Model.Title

- @Model.Title @Model.Author?.UserName diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml index ae23d5757f..99d743aed9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml @@ -3,9 +3,7 @@ @model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages.PageViewModel @inject IPageLayout PageLayout -@{ - PageLayout.Content.Title = Model.Title; -} +

@Model.Title

diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml index abff0a475e..8ad6dd9ca3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml @@ -13,10 +13,6 @@ @model Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs.BlogPostModel -@{ - PageLayout.Content.Title = Model.BlogPost.Title; -} - @await Component.InvokeAsync(typeof(DefaultBlogPostViewComponent), new { Model.BlogSlug, From 316fdb63eaf3b55a0c2f93b1dd848220c6759197 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 5 Mar 2021 14:52:40 +0300 Subject: [PATCH 099/101] fix router events service intro --- docs/en/UI/Angular/Router-Events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Router-Events.md b/docs/en/UI/Angular/Router-Events.md index 011d405b22..1d36c3a211 100644 --- a/docs/en/UI/Angular/Router-Events.md +++ b/docs/en/UI/Angular/Router-Events.md @@ -1,6 +1,6 @@ # Router Events Simplified -`RouterEvents` is a utility service to provide an easy implementation for one of the most frequent needs in Angular templates: `TrackByFunction`. Please see [this page in Angular docs](https://angular.io/guide/template-syntax#ngfor-with-trackby) for its purpose. +`RouterEvents` is a utility service for filtering specific router events and reacting to them. Please see [this page in Angular docs](https://angular.io/api/router/Event) for available router events. From 859c4e9a6c32ee51d910715715633709e9e831eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Mar 2021 17:11:51 +0300 Subject: [PATCH 100/101] Resolves #7965: Logging on Service Registration. --- .../ServiceCollectionLoggingExtensions.cs | 12 +++++++++ .../Volo/Abp/AbpApplicationBase.cs | 21 +++++++++++++++ .../InternalServiceCollectionExtensions.cs | 2 ++ .../Volo/Abp/Logging/AbpInitLogEntry.cs | 26 +++++++++++++++++++ .../Volo/Abp/Logging/DefaultInitLogger.cs | 24 +++++++++++++++++ .../Volo/Abp/Logging/IInitLogger.cs | 16 ++++++++++++ .../Volo/Abp/Modularity/AbpModuleHelper.cs | 16 +++++++++--- .../Volo/Abp/Modularity/ModuleLoader.cs | 7 +++-- .../Volo/Abp/Modularity/ModuleManager.cs | 12 --------- .../PlugIns/PlugInSourceExtensions.cs | 5 ++-- .../Modularity/PlugIns/PlugInSourceList.cs | 5 ++-- .../Volo/Abp/Modularity/ModuleLoader_Tests.cs | 8 +++++- 12 files changed, 131 insertions(+), 23 deletions(-) create mode 100644 framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs new file mode 100644 index 0000000000..48921cb99b --- /dev/null +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Logging; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class ServiceCollectionLoggingExtensions + { + public static IInitLogger GetInitLogger(this IServiceCollection services) + { + return services.GetSingletonInstance(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 1e5b251ca0..256a1dd05d 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.Internal; +using Volo.Abp.Logging; using Volo.Abp.Modularity; namespace Volo.Abp @@ -71,11 +73,30 @@ namespace Volo.Abp { using (var scope = ServiceProvider.CreateScope()) { + WriteInitLogs(scope.ServiceProvider); scope.ServiceProvider .GetRequiredService() .InitializeModules(new ApplicationInitializationContext(scope.ServiceProvider)); } } + + protected virtual void WriteInitLogs(IServiceProvider serviceProvider) + { + var logger = serviceProvider.GetService>(); + if (logger == null) + { + return; + } + + var initLogger = serviceProvider.GetRequiredService(); + + foreach (var entry in initLogger.Entries) + { + logger.LogWithLevel(entry.Level, entry.Message, entry.Exception); + } + + initLogger.Entries.Clear(); + } protected virtual IReadOnlyList LoadModules(IServiceCollection services, AbpApplicationCreationOptions options) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs index 83a7ec163e..c116a20080 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.Logging; using Volo.Abp.Modularity; using Volo.Abp.Reflection; @@ -35,6 +36,7 @@ namespace Volo.Abp.Internal services.TryAddSingleton(moduleLoader); services.TryAddSingleton(assemblyFinder); services.TryAddSingleton(typeFinder); + services.TryAddSingleton(new DefaultInitLogger()); services.AddAssemblyOf(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs new file mode 100644 index 0000000000..17a346fa1c --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs @@ -0,0 +1,26 @@ +using System; +using JetBrains.Annotations; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Logging +{ + public class AbpInitLogEntry + { + public LogLevel Level { get; } + + public string Message { get; } + + [CanBeNull] + public Exception Exception { get; } + + public AbpInitLogEntry( + LogLevel level, + string message, + Exception exception) + { + Level = level; + Message = message; + Exception = exception; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs new file mode 100644 index 0000000000..e1f7344f39 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Logging +{ + public class DefaultInitLogger : IInitLogger + { + public List Entries { get; } + + public DefaultInitLogger() + { + Entries = new List(); + } + + public void Log( + LogLevel logLevel, + string message, + Exception exception = null) + { + Entries.Add(new AbpInitLogEntry(logLevel, message, exception)); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs new file mode 100644 index 0000000000..5c549682e9 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Logging +{ + public interface IInitLogger + { + public List Entries { get; } + + void Log( + LogLevel logLevel, + string message, + Exception exception = null); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs index d58483811b..9331014623 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs @@ -2,15 +2,18 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using Microsoft.Extensions.Logging; +using Volo.Abp.Logging; namespace Volo.Abp.Modularity { internal static class AbpModuleHelper { - public static List FindAllModuleTypes(Type startupModuleType) + public static List FindAllModuleTypes(Type startupModuleType, IInitLogger logger) { var moduleTypes = new List(); - AddModuleAndDependenciesResursively(moduleTypes, startupModuleType); + logger.Log(LogLevel.Information, "Loaded ABP modules:"); + AddModuleAndDependenciesResursively(moduleTypes, startupModuleType, logger); return moduleTypes; } @@ -35,7 +38,11 @@ namespace Volo.Abp.Modularity return dependencies; } - private static void AddModuleAndDependenciesResursively(List moduleTypes, Type moduleType) + private static void AddModuleAndDependenciesResursively( + List moduleTypes, + Type moduleType, + IInitLogger logger, + int depth = 0) { AbpModule.CheckAbpModuleType(moduleType); @@ -45,10 +52,11 @@ namespace Volo.Abp.Modularity } moduleTypes.Add(moduleType); + logger.Log(LogLevel.Information, $"{new string(' ', depth * 2)}- {moduleType.FullName}"); foreach (var dependedModuleType in FindDependedModuleTypes(moduleType)) { - AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType); + AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType, logger, depth + 1); } } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs index 7e7e69d457..56ee2f5d71 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Logging; using Volo.Abp.Modularity.PlugIns; namespace Volo.Abp.Modularity @@ -43,14 +44,16 @@ namespace Volo.Abp.Modularity Type startupModuleType, PlugInSourceList plugInSources) { + var initLogger = services.GetInitLogger(); + //All modules starting from the startup module - foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType)) + foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType, initLogger)) { modules.Add(CreateModuleDescriptor(services, moduleType)); } //Plugin modules - foreach (var moduleType in plugInSources.GetAllModules()) + foreach (var moduleType in plugInSources.GetAllModules(initLogger)) { if (modules.Any(m => m.Type == moduleType)) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs index 70b9036150..764acf1289 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs @@ -32,8 +32,6 @@ namespace Volo.Abp.Modularity public void InitializeModules(ApplicationInitializationContext context) { - LogListOfModules(); - foreach (var contributor in _lifecycleContributors) { foreach (var module in _moduleContainer.Modules) @@ -52,16 +50,6 @@ namespace Volo.Abp.Modularity _logger.LogInformation("Initialized all ABP modules."); } - private void LogListOfModules() - { - _logger.LogInformation("Loaded ABP modules:"); - - foreach (var module in _moduleContainer.Modules) - { - _logger.LogInformation("- " + module.Type.FullName); - } - } - public void ShutdownModules(ApplicationShutdownContext context) { var modules = _moduleContainer.Modules.Reverse().ToList(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs index bf44f94605..b041cd160d 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs @@ -1,19 +1,20 @@ using System; using System.Linq; using JetBrains.Annotations; +using Volo.Abp.Logging; namespace Volo.Abp.Modularity.PlugIns { public static class PlugInSourceExtensions { [NotNull] - public static Type[] GetModulesWithAllDependencies([NotNull] this IPlugInSource plugInSource) + public static Type[] GetModulesWithAllDependencies([NotNull] this IPlugInSource plugInSource, IInitLogger logger) { Check.NotNull(plugInSource, nameof(plugInSource)); return plugInSource .GetModules() - .SelectMany(AbpModuleHelper.FindAllModuleTypes) + .SelectMany(type => AbpModuleHelper.FindAllModuleTypes(type, logger)) .Distinct() .ToArray(); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs index 1e96e26e14..1d5509b359 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs @@ -2,16 +2,17 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using Volo.Abp.Logging; namespace Volo.Abp.Modularity.PlugIns { public class PlugInSourceList : List { [NotNull] - internal Type[] GetAllModules() + internal Type[] GetAllModules(IInitLogger logger) { return this - .SelectMany(pluginSource => pluginSource.GetModulesWithAllDependencies()) + .SelectMany(pluginSource => pluginSource.GetModulesWithAllDependencies(logger)) .Distinct() .ToArray(); } diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs index 3541f9b78e..cc0117e184 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Shouldly; +using Volo.Abp.Logging; using Volo.Abp.Modularity.PlugIns; using Xunit; @@ -11,7 +12,12 @@ namespace Volo.Abp.Modularity public void Should_Load_Modules_By_Dependency_Order() { var moduleLoader = new ModuleLoader(); - var modules = moduleLoader.LoadModules(new ServiceCollection(), typeof(MyStartupModule), new PlugInSourceList()); + var modules = moduleLoader.LoadModules( + new ServiceCollection() + .AddSingleton(new DefaultInitLogger()), + typeof(MyStartupModule), + new PlugInSourceList() + ); modules.Length.ShouldBe(2); modules[0].Type.ShouldBe(typeof(IndependentEmptyModule)); modules[1].Type.ShouldBe(typeof(MyStartupModule)); From 00a22cb0bb7ae337722129875a8ff2aa74ea86df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Mar 2021 17:16:05 +0300 Subject: [PATCH 101/101] CmsKitHttpApiModule should not depend on applicatin layers. --- .../src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj | 4 ++-- .../Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj index 64a3dcef21..b23ef3ba0e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj @@ -9,9 +9,9 @@ - + - + diff --git a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs index c4a45bb8cf..219f2d9442 100644 --- a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs @@ -5,8 +5,8 @@ using Volo.CmsKit.Public; namespace Volo.CmsKit { [DependsOn( - typeof(CmsKitAdminApplicationModule), - typeof(CmsKitPublicApplicationModule), + typeof(CmsKitAdminHttpApiModule), + typeof(CmsKitPublicHttpApiModule), typeof(CmsKitApplicationContractsModule) )] public class CmsKitHttpApiModule : AbpModule