Browse Source

merged with dev

pull/16546/head
Mahmut Gundogdu 3 years ago
parent
commit
5c1971e9db
  1. 94
      CODE_OF_CONDUCT.md
  2. 3
      README.md
  3. 12
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  4. 4
      configureawait.props
  5. 6
      docs/en/Community-Articles/2022-11-14-How-to-add-a-custom-grant-type-in-OpenIddict/POST.md
  6. 35
      docs/en/Getting-Started-React-Native.md
  7. 12
      docs/en/Modules/OpenIddict.md
  8. 2
      docs/en/UI/Angular/Card-Component.md
  9. 51
      docs/en/UI/Angular/Checkbox-Component.md
  10. 49
      docs/en/UI/Angular/FormInput-Component.md
  11. BIN
      docs/en/UI/Angular/images/form-checkbox.png
  12. BIN
      docs/en/UI/Angular/images/form-input.png
  13. 4
      docs/en/UI/AspNetCore/Tag-Helpers/Dropdowns.md
  14. BIN
      docs/en/images/rn-options.png
  15. 7
      framework/Volo.Abp.sln
  16. 1
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Extensibility/WebAssemblyLookupApiRequestService.cs
  17. 69
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs
  18. 7
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelper.cs
  19. 16
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelperService.cs
  20. 12
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperResourceService.cs
  21. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js
  22. 78
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Internal/ResponseContentTypeHelper.cs
  23. 21
      framework/src/Volo.Abp.BlazoriseUI/Components/AbpExtensibleDataGrid.razor
  24. 724
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs
  25. 6
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs
  26. 25
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/UpdateDockerImagesStep.cs
  27. 3
      framework/src/Volo.Abp.Ddd.Domain.Shared/FodyWeavers.xml
  28. 30
      framework/src/Volo.Abp.Ddd.Domain.Shared/FodyWeavers.xsd
  29. 22
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo.Abp.Ddd.Domain.Shared.csproj
  30. 14
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/AbpDddDomainSharedModule.cs
  31. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs
  32. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs
  33. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityCreatedEto.cs
  34. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityDeletedEto.cs
  35. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs
  36. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityUpdatedEto.cs
  37. 1
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs
  38. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs
  39. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs
  40. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityEto.cs
  41. 0
      framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs
  42. 1
      framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj
  43. 3
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs
  44. 2
      framework/src/Volo.Abp.EventBus.Abstractions/Volo.Abp.EventBus.Abstractions.csproj
  45. 4
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Abstractions/AbpEventBusAbstractionsModule.cs
  46. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs
  47. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IEventInbox.cs
  48. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IEventOutbox.cs
  49. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IInboxProcessor.cs
  50. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IOutboxSender.cs
  51. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs
  52. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfig.cs
  53. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfigDictionary.cs
  54. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs
  55. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfig.cs
  56. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfigDictionary.cs
  57. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs
  58. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventBus.cs
  59. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs
  60. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventDataWithInheritableGenericArgument.cs
  61. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventHandlerDisposeWrapper.cs
  62. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventHandlerFactory.cs
  63. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventHandlerInvoker.cs
  64. 0
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/ILocalEventBus.cs
  65. 17
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/LocalEventHandlerOrderAttribute.cs
  66. 14
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs
  67. 18
      framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_MultiTenancyMiddlewareErrorPageBuilder_Tests.cs
  68. 56
      framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Order_Test.cs
  69. 2
      latest-versions.json
  70. 2
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
  71. 244
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
  72. 4
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
  73. 280
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
  74. 1489
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20230504070814_Added_BlogUser_Optionals.Designer.cs
  75. 226
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20230504070814_Added_BlogUser_Optionals.cs
  76. 162
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/BloggingTestAppDbContextModelSnapshot.cs
  77. 4
      modules/blogging/app/Volo.BloggingTestApp/package.json
  78. 318
      modules/blogging/app/Volo.BloggingTestApp/yarn.lock
  79. 38
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Members/CustomIdentityBlogUserUpdateDto.cs
  80. 2
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Members/IMemberAppService.cs
  81. 18
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/BlogUserDto.cs
  82. 2
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/IPostAppService.cs
  83. 17
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Members/MemberAppService.cs
  84. 30
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs
  85. 17
      modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/en.json
  86. 22
      modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Users/UserConsts.cs
  87. 2
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Posts/IPostRepository.cs
  88. 22
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/BlogUser.cs
  89. 10
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs
  90. 9
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Posts/EfCorePostRepository.cs
  91. 8
      modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.Generated.cs
  92. 9
      modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.Generated.cs
  93. 7
      modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs
  94. 10
      modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Posts/MongoPostRepository.cs
  95. 667
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml
  96. 9
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml.cs
  97. 28
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/detail.css
  98. 17
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/detail.js
  99. 1
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Shared/Styles/blog.css
  100. 193
      modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml

94
CODE_OF_CONDUCT.md

@ -0,0 +1,94 @@
# Contributor Covenant Code of Conduct
## Preamble
The ABP Framework was created to implement common generic web application features in a common code base. This approach helps developers to decouple line of business application features from their custom business logic. Besides, the ABP Framework helps create MVPs and kick-start your project as quickly as possible. All the contributors try to save valuable time by automating repetitive tasks at the framework level. This code of conduct has been adopted by many [other open source communities](http://contributor-covenant.org/adopters/) and we feel it expresses our values well.
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals but for the overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others’ private information, such as a physical or email address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct and will communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces and when an individual officially represents the community in public spaces. Examples of representing our community include:
- Using an official e-mail address.
- Posting via an official social media account.
- Acting as an appointed representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [info@abp.io](mailto:info@abp.io). All complaints will be reviewed and investigated promptly and fairly. All community leaders must to respect the privacy and security of the reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact:** Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence:** A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact:** A violation through a single incident or series of actions.
**Consequence:** A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period. This includes avoiding interactions in community spaces and external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact:** A serious violation of community standards, including sustained inappropriate behavior.
**Consequence:** A temporary ban from any interaction or public communication with the community for a specified period. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact:** Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence:** A permanent ban from any sort of public interaction within the community.
## Attribution
This document is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla’s code of conduct enforcement ladder](https://github.com/mozilla/diversity).
For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq.
Translations are available at https://www.contributor-covenant.org/translations.

3
README.md

@ -6,7 +6,8 @@
[![NuGet (with prereleases)](https://img.shields.io/nuget/vpre/Volo.Abp.Core.svg?style=flat-square)](https://www.nuget.org/packages/Volo.Abp.Core)
[![MyGet (nightly builds)](https://img.shields.io/myget/abp-nightly/vpre/Volo.Abp.svg?style=flat-square)](https://docs.abp.io/en/abp/latest/Nightly-Builds)
[![NuGet Download](https://img.shields.io/nuget/dt/Volo.Abp.Core.svg?style=flat-square)](https://www.nuget.org/packages/Volo.Abp.Core)
[![Code of Conduct](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](https://github.com/abpframework/abp/blob/dev/CODE_OF_CONDUCT.md)
[![CLA Signed](https://cla-assistant.io/readme/badge/abpframework/abp)](https://cla-assistant.io/abpframework/abp)
[![ABP Discord server](https://img.shields.io/discord/951497912645476422?label=Discord)](https://discord.gg/abp)
ABP Framework is a complete **infrastructure** based on **ASP.NET Core** to create **modern web applications** and **APIs** by following the software development **best practices** and the **latest technologies**. Check out https://abp.io

12
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -539,6 +539,8 @@
"Pricing_Page_Testimonial_5": "ABP Framework is not only a framework, but it is also a guide for project development/management, because it provides DDD, GenericRepository, DI, Microservice, and Modularity training. Even if you are not going to use the framework itself, you can develop yourself with docs.abp.io which is well and professionally prepared (OpenIddict, Redis, Quartz etc.). Because many things are pre-built, it shortens project development time significantly (Such as login page, exception handling, data filtering, seeding, audit logging, localization, auto API controller etc.). As an example from our application, I have used Local Event Bus for stock control. So, I am able to manage order movements by writing stock handler. It is wonderful not to lose time for CreationTime, CreatorId. They are being filled automatically.",
"Pricing_Page_Testimonial_6": "ABP Framework is a good framework but it needs time to understand the different layers, classes, and libraries it used (specially ABP). I spent a lot of time reading the code base, but ABP Commercial save us time to create the project specialty entities (AR) and the repository linked to each of them. I liked also the approach used in ABP is very mature, we know is based on DDD and monolith.",
"Pricing_Page_Testimonial_7": "As a startup we need to iterate quickly and spend minimal time on boilerplate and non-core features.\nOur engineers range from highly experienced to junior engineers, we needed a common understanding and a way to share technical and domain knowledge, ABP allowed us to do this due to their great guides and documentation. \nThere are things we haven't had to worry about since they work out of the box with ABP. \nABP helped us streamline rapid prototyping and development, less than 4 weeks from feature inception to production. With all its premium features included in the license, ABP has given us, \"Startup in a Box\" on the Software Engineering Side.",
"Pricing_Page_Testimonial_8": "I would recommend ABP commercial to all those who want to expand the range of products available to their customers. It's fantastic when need to use a distributed enterprise enviroment (Angualr, WPF, Win&Linux). In addition to their products, we love their support, which makes our job faster and easier. We already know that we have found a great partner for the future who will support us in expanding our business.",
"Pricing_Page_Testimonial_9": "We are a company of 2 employees that's been in business for over 20 years.\nIn terms of our experience with ABP Commercial, we were approached by a client who requested that we develop a new human resources application in a modern environment to replace their 25-year-old Access application. We decided to transition from a desktop solution to a web-based one.\n\nAt the time, we had very little knowledge of web applications and .NET but we stumbled upon ABP Commercial, and with the help of ABP Framework, technical documentation, and ABP Suite, we were able to not only develop the application to the client's specifications but also successfully work within a .NET environment within a year.",
"AbpBookDownloadArea_ClaimYourEBook": "Claim your <span class='gradient-framework'>Mastering ABP Framework</span> E-Book",
"AddMemberModal_Warning_1": "If the <strong>username</strong> you are trying to add doesn't exist in the system, please ask your team member to register on <a href='{0}/Account/Register'>{0}</a> and share the username of his/her account with you.",
"MyOrganizations_Detail_WelcomeMessage": "Welcome to your organization, {0}",
@ -832,6 +834,14 @@
"Volo.AbpIo.Commercial:040001": "API Access Key is incorrect.",
"GetLepton": "Get Lepton Now",
"MyOrganizations_Detail_LicenseStartDate": "License Start Date",
"MyOrganizations_Detail_LicenseExpiryDate": "Expiry Date"
"MyOrganizations_Detail_LicenseExpiryDate": "Expiry Date",
"BlazoriseSupport": "How do I get the Blazorise license key and support from the Blazorise team?",
"BlazoriseSupportExplanation": "Follow the steps below to get support from the Blazorise team and get your Blazorise license key:",
"BlazoriseSupportExplanation1": "Sign up for a new account at <a href=\"https://blazorise.com/support/register\">blazorise.com/support/register</a> with the same email address as your abp.io account. Leave the \"License Key\" entry blank. <strong>It must be the same email address as your email account on abp.io</strong>.",
"BlazoriseSupportExplanation2": "Verify your email address by checking your email box. Check your spam box if you don't see an email in your inbox!",
"BlazoriseSupportExplanation3": "Log into the Blazorise support website at <a href=\"https://blazorise.com/support/login\">blazorise.com/support/login</a>.",
"BlazoriseSupportExplanation4": "If you have an active ABP Commercial license, you will also have a Blazorise PRO license. You can get your Blazorise license key at <a href=\"https://blazorise.com/support/user/manage/license\">blazorise.com/support/user/manage/license</a>.",
"BlazoriseSupportExplanation5": "You can post your questions on the support website and generate a product token for your application.",
"AbpLiveTrainingPackages": "ABP Live Training Packages"
}
}

4
configureawait.props

@ -1,9 +1,9 @@
<Project>
<ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.6.1">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
</Project>

6
docs/en/Community-Articles/2022-11-14-How-to-add-a-custom-grant-type-in-OpenIddict/POST.md

@ -71,7 +71,13 @@ public class MyTokenExtensionGrant : ITokenExtensionGrant
var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user);
claimsPrincipal.SetScopes(principal.GetScopes());
claimsPrincipal.SetResources(await GetResourcesAsync(context, principal.GetScopes()));
//abp version < 7.3
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimDestinationsManager>().SetAsync(principal);
//For abp version >= 7.3
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, principal);
return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, claimsPrincipal);
}

35
docs/en/Getting-Started-React-Native.md

@ -1,11 +1,11 @@
# Getting Started with the React Native
````json
```json
//[doc-params]
{
"Tiered": ["No", "Yes"]
"Tiered": ["No", "Yes"]
}
````
```
ABP platform provide basic [React Native](https://reactnative.dev/) startup template to develop mobile applications **integrated to your ABP based backends**.
@ -20,7 +20,6 @@ Please follow the steps below to prepare your development environment for React
3. **[Optional] Install VS Code:** [VS Code](https://code.visualstudio.com/) is a free, open-source IDE which works seamlessly with TypeScript. Although you can use any IDE including Visual Studio or Rider, VS Code will most likely deliver the best developer experience when it comes to React Native projects.
4. **Install an Emulator:** React Native applications need an Android emulator or an iOS simulator to run on your OS. See the [Android Studio Emulator](https://docs.expo.io/workflow/android-simulator/) or [iOS Simulator](https://docs.expo.io/workflow/ios-simulator/) on expo.io documentation to learn how to set up an emulator.
## How to Start a New React Native Project
You have multiple options to initiate a new React Native project that works with ABP:
@ -56,6 +55,7 @@ Please do the following:
> When you are using OpenIddict, You should remove 'clientSecret' on Environment.js (if exists) and disable "HTTPS-only" settings. (Openiddict has default since Version 6.0)
### How to disable Https-only in Openiddict.
You should add this code on {{ if Tiered == "No" }}`MyProjectNameHttpApiHostModule`{{ else if Tiered == "Yes" }}`MyProjectNameAuthServerModule`{{ end }}.
```csharp
@ -79,26 +79,27 @@ A React Native application running on an Android emulator or a physical phone **
{{ if Tiered == "No"}}
![React Native host project local IP entry](images/rn-host-local-ip.png)
* Open the `appsettings.json` in the `.HttpApi.Host` folder. Replace the `localhost` address on the `SelfUrl` and `Authority` properties with your local IP address.
* Open the `launchSettings.json` in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
- Open the `appsettings.json` file in the `.HttpApi.Host` folder. Replace the `localhost` address on the `SelfUrl` and `Authority` properties with your local IP address.
- Open the `launchSettings.json` file in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
{{ else if Tiered == "Yes" }}
![React Native tiered project local IP entry](images/rn-tiered-local-ip.png)
* Open the `appsettings.json` in the `.AuthServer` folder. Replace the `localhost` address on the `SelfUrl` property with your local IP address.
* Open the `launchSettings.json` in the `.AuthServer/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
* Open the `appsettings.json` in the `.HttpApi.Host` folder. Replace the `localhost` address on the `Authority` property with your local IP address.
* Open the `launchSettings.json` in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
- Open the `appsettings.json` file in the `.AuthServer` folder. Replace the `localhost` address on the `SelfUrl` property with your local IP address.
- Open the `launchSettings.json` file in the `.AuthServer/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
- Open the `appsettings.json` file in the `.HttpApi.Host` folder. Replace the `localhost` address on the `Authority` property with your local IP address.
- Open the `launchSettings.json` file in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
{{ end }}
Run the backend application as described in the [getting started document](Getting-Started.md).
> You should turn off the "Https Restriction" if you're using OpenIddict as a central identity management solution. Because the IOS Simulator doesn't support self-signed certificates and OpenIddict is set to only work with HTTPS by default.
## How to disable the Https-only settings of OpenIddict
Go to MyProjectNameHttpApiHostModule.cs under the host project. Add put these codes under the `PreConfigureServices` function.
Go to MyProjectNameHttpApiHostModule.cs under the host project. And put these codes under the `PreConfigureServices` function.
```csharp
#if DEBUG
@ -109,7 +110,6 @@ Run the backend application as described in the [getting started document](Getti
#endif
```
## How to Configure & Run the React Native Application
1. Make sure the [database migration is complete](./Getting-Started?UI=NG&DB=EF&Tiered=No#create-the-database) and the [API is up and running](./Getting-Started?UI=NG&DB=EF&Tiered=No#run-the-application).
@ -128,21 +128,20 @@ Run the backend application as described in the [getting started document](Getti
{{ end }}
4. Run `yarn start` or `npm start`. Wait Expo CLI to start. Expo CLI opens the management interface on the `http://localhost:19002/` address.
4. Run `yarn start` or `npm start`. Wait for the Expo CLI to print the opitons.
> The React Native application was generated with [Expo](https://expo.io/). Expo is a set of tools built around React Native to help you quickly start an app and, while it has many features.
![expo-interface](images/rn-expo-interface.png)
![expo-cli-options](images/rn-options.png)
In the above management interface, you can start the application with an Android emulator, an iOS simulator or a physical phone by the scan the QR code with the [Expo Client](https://expo.io/tools#client).
In the above image, you can start the application with an Android emulator, an iOS simulator or a physical phone by scanning the QR code with the [Expo Client](https://expo.io/tools#client) or choosing the option.
![React Native login screen on iPhone 11](images/rn-login-iphone.png)
Enter **admin** as the username and **1q2w3E*** as the password to login to the application.
Enter **admin** as the username and **1q2w3E\*** as the password to login to the application.
The application is up and running. You can continue to develop your application based on this startup template.
## See Also
* [React Native project structure](./Startup-Templates/Application#react-native)
- [React Native project structure](./Startup-Templates/Application#react-native)

12
docs/en/Modules/OpenIddict.md

@ -323,16 +323,16 @@ Configure<TokenCleanupOptions>(options =>
[Claims Principal Factory](https://docs.abp.io/en/abp/latest/Authorization#claims-principal-factory) can be used to add/remove claims to the `ClaimsPrincipal`.
The `AbpDefaultOpenIddictClaimDestinationsProvider` service will add `Name`, `Email,` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
The `AbpDefaultOpenIddictClaimsPrincipalHandler` service will add `Name`, `Email,` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
Create a service that inherits from `IAbpOpenIddictClaimDestinationsProvider` and add it to DI to fully control the destinations of claims.
Create a service that inherits from `IAbpOpenIddictClaimsPrincipalHandler` and add it to DI to fully control the destinations of claims.
```cs
public class MyClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvider, ITransientDependency
public class MyClaimDestinationsHandler : IAbpOpenIddictClaimsPrincipalHandler, ITransientDependency
{
public virtual Task SetDestinationsAsync(AbpOpenIddictClaimDestinationsProviderContext context)
public virtual Task HandleAsync(AbpOpenIddictClaimsPrincipalHandlerContext context)
{
foreach (var claim in context.Claims)
foreach (var claim in context.Principal.Claims)
{
if (claim.Type == MyClaims.MyClaimsType)
{
@ -351,7 +351,7 @@ public class MyClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvid
Configure<AbpOpenIddictClaimDestinationsOptions>(options =>
{
options.ClaimDestinationsProvider.Add<MyClaimDestinationsProvider>();
options.ClaimsPrincipalHandlers.Add<MyClaimDestinationsHandler>();
});
```

2
docs/en/UI/Angular/Card-Component.md

@ -29,7 +29,7 @@ ABP Card Component is a part of the `ThemeSharedModule` module. If you've import
// my-feature.module.ts
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { CardDemoComponent } from './chart-demo.component';
import { CardDemoComponent } from './card-demo.component';
@NgModule({
imports: [

51
docs/en/UI/Angular/Checkbox-Component.md

@ -0,0 +1,51 @@
# Checkbox Component
The ABP Checkbox Component is a reusable form input component for the checkbox type.
# Inputs
- `label`
- `labelClass (default form-check-label)`
- `checkboxId`
- `checkboxReadonly`
- `checkboxReadonly (default form-check-input)`
- `checkboxStyle`
# Outputs
- `checkboxBlur`
- `checkboxFocus`
# Usage
The ABP Checkbox component is a part of the `ThemeSharedModule` module. If you've imported that module into your module, there's no need to import it again. If not, then first import it as shown below:
```ts
// my-feature.module.ts
import { ThemeSharedModule } from "@abp/ng.theme.shared";
import { CheckboxDemoComponent } from "./CheckboxDemoComponent.component";
@NgModule({
imports: [
ThemeSharedModule,
// ...
],
declarations: [CheckboxDemoComponent],
// ...
})
export class MyFeatureModule {}
```
Then, the `abp-checkbox` component can be used. See the example below:
```html
<div class="form-check">
<abp-checkbox label="Yes,I Agree" checkboxId="checkbox-input">
</abp-checkbox>
</div>
```
See the checkbox input result below:
![abp-checkbox](./images/form-checkbox.png)

49
docs/en/UI/Angular/FormInput-Component.md

@ -0,0 +1,49 @@
# Form Input Component
The ABP FormInput Component is a reusable form input component for the text type.
# Inputs
* `label`
* `labelClass (default form-label)`
* `inputPlaceholder`
* `inputReadonly`
* `inputClass (default form-control)`
# Outputs
* `formBlur`
* `formFocus`
# Usage
The ABP FormInput component is a part of the `ThemeSharedModule` module. If you've imported that module into your module, there's no need to import it again. If not, then first import it as shown below:
```ts
import { ThemeSharedModule } from "@abp/ng.theme.shared";
import { FormInputDemoComponent } from "./FomrInputDemoComponent.component";
@NgModule({
imports: [
ThemeSharedModule,
// ...
],
declarations: [FormInputDemoComponent],
})
export class MyFeatureModule {}
```
Then, the `abp-form-input` component can be used. See the example below:
```html
<div class="row">
<div class="col-4">
<abp-form-input
label="AbpAccount::UserNameOrEmailAddress"
inputId="login-input-user-name-or-email-address"
></abp-form-input>
</div>
</div>
```
See the form input result below:
![abp-form-input](./images/form-input.png)

BIN
docs/en/UI/Angular/images/form-checkbox.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
docs/en/UI/Angular/images/form-input.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

4
docs/en/UI/AspNetCore/Tag-Helpers/Dropdowns.md

@ -70,8 +70,8 @@ Basic usage:
A value indicates which direction `abp-dropdown-menu` items will be aligned to. Should be one of the following values:
* `Left` (default value)
* `Right`
* `Start` (default value)
* `End`
### Additional content

BIN
docs/en/images/rn-options.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

7
framework/Volo.Abp.sln

@ -437,6 +437,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Compone
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Ldap.Abstractions", "src\Volo.Abp.Ldap.Abstractions\Volo.Abp.Ldap.Abstractions.csproj", "{0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ddd.Domain.Shared", "src\Volo.Abp.Ddd.Domain.Shared\Volo.Abp.Ddd.Domain.Shared.csproj", "{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1303,6 +1305,10 @@ Global
{0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71}.Release|Any CPU.Build.0 = Release|Any CPU
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1523,6 +1529,7 @@ Global
{E9492F9F-47E0-45A6-A51D-9949FEAA8543} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{8764DFAF-D13D-449A-9A5E-5D7F0B2D7FEF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{0F80E95C-41E6-4F23-94FF-FC9D0B8D5D71} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{0858571B-CE73-4AD6-BD06-EC9F0714D8E9} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

1
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Extensibility/WebAssemblyLookupApiRequestService.cs

@ -3,7 +3,6 @@ using System.Globalization;
using System.Net.Http;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using Fody;
using Volo.Abp.AspNetCore.Components.Web.Extensibility;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;

69
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyOptions.cs

@ -1,14 +1,23 @@
using System;
using System.Globalization;
using System.Net;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using Volo.Abp.Http;
using Volo.Abp.Json;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy;
@ -58,14 +67,70 @@ public class AbpAspNetCoreMultiTenancyOptions
}
}
context.Response.Headers.Add("Abp-Tenant-Resolve-Error", HtmlEncoder.Default.Encode(exception.Message));
if (isCookieAuthentication && context.Request.Method.Equals("Get", StringComparison.OrdinalIgnoreCase) && !context.Request.IsAjax())
{
context.Response.Headers.Add("Abp-Tenant-Resolve-Error", HtmlEncoder.Default.Encode(exception.Message));
context.Response.Redirect(context.Request.GetEncodedUrl());
}
else if (context.Request.IsAjax())
{
var error = new RemoteServiceErrorResponse(new RemoteServiceErrorInfo(exception.Message, exception is BusinessException businessException ? businessException.Details : string.Empty));
var jsonSerializerOptions = context.RequestServices.GetRequiredService<IOptions<JsonOptions>>().Value.SerializerOptions;
ResponseContentTypeHelper.ResolveContentTypeAndEncoding(
null,
context.Response.ContentType,
(new MediaTypeHeaderValue("application/json")
{
Encoding = Encoding.UTF8
}.ToString(), Encoding.UTF8),
MediaType.GetEncoding,
out var resolvedContentType,
out var resolvedContentTypeEncoding);
context.Response.ContentType = resolvedContentType;
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
var responseStream = context.Response.Body;
if (resolvedContentTypeEncoding.CodePage == Encoding.UTF8.CodePage)
{
try
{
await JsonSerializer.SerializeAsync(responseStream, error, error.GetType(), jsonSerializerOptions, context.RequestAborted);
await responseStream.FlushAsync(context.RequestAborted);
}
catch (OperationCanceledException) when (context.RequestAborted.IsCancellationRequested) { }
}
else
{
var transcodingStream = Encoding.CreateTranscodingStream(context.Response.Body, resolvedContentTypeEncoding, Encoding.UTF8, leaveOpen: true);
ExceptionDispatchInfo exceptionDispatchInfo = null;
try
{
await JsonSerializer.SerializeAsync(transcodingStream, error, error.GetType(), jsonSerializerOptions, context.RequestAborted);
await transcodingStream.FlushAsync(context.RequestAborted);
}
catch (OperationCanceledException) when (context.RequestAborted.IsCancellationRequested) { }
catch (Exception ex)
{
exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex);
}
finally
{
try
{
await transcodingStream.DisposeAsync();
}
catch when (exceptionDispatchInfo != null)
{
}
exceptionDispatchInfo?.Throw();
}
}
}
else
{
context.Response.Headers.Add("Abp-Tenant-Resolve-Error", HtmlEncoder.Default.Encode(exception.Message));
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Response.ContentType = "text/html";

7
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelper.cs

@ -9,7 +9,7 @@ public abstract class
where TTagHelper : AbpDatePickerBaseTagHelper<TTagHelper>
{
private readonly IAbpDatePickerOptions _abpDatePickerOptionsImplementation;
private IAbpDatePickerOptions _abpDatePickerOptionsImplementation;
public string Label { get; set; }
@ -47,6 +47,11 @@ public abstract class
{
_abpDatePickerOptionsImplementation = new AbpDatePickerOptions();
}
public void SetDatePickerOptions(IAbpDatePickerOptions options)
{
_abpDatePickerOptionsImplementation = options;
}
public string PickerId {
get => _abpDatePickerOptionsImplementation.PickerId;

16
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelperService.cs

@ -84,6 +84,11 @@ public abstract class AbpDatePickerBaseTagHelperService<TTagHelper> : AbpTagHelp
AddReadOnlyAttribute(TagHelperOutput);
AddPlaceholderAttribute(TagHelperOutput);
AddInfoTextId(TagHelperOutput);
var optionsAttribute = GetAttributeAndModelExpression<DatePickerOptionsAttribute>(out var modelExpression);
if (optionsAttribute != null)
{
TagHelper.SetDatePickerOptions(optionsAttribute.GetDatePickerOptions(modelExpression.ModelExplorer));
}
// Open and close button
var openButtonContent = TagHelper.OpenButton
@ -426,15 +431,6 @@ public abstract class AbpDatePickerBaseTagHelperService<TTagHelper> : AbpTagHelp
attrList.Add(attr);
}
var optionsAttribute = GetAttributeAndModelExpression<DatePickerOptionsAttribute>(out var modelExpression);
if (optionsAttribute != null)
{
foreach (var attr in ConvertDatePickerOptionsToAttributeList(optionsAttribute.GetDatePickerOptions(modelExpression.ModelExplorer)))
{
attrList.Add(attr);
}
}
AddBaseTagAttributes(attrList);
return attrList;
@ -591,7 +587,7 @@ public abstract class AbpDatePickerBaseTagHelperService<TTagHelper> : AbpTagHelp
abpButtonTagHelper.ButtonType = AbpButtonType.Outline_Secondary;
abpButtonTagHelper.Icon = icon;
abpButtonTagHelper.Disabled = TagHelper.IsDisabled;
abpButtonTagHelper.Disabled = TagHelper.IsDisabled || GetAttribute<DisabledInput>() != null;
if (!visible)
{

12
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperResourceService.cs

@ -3,14 +3,13 @@ using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.VirtualFileSystem;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers;
@ -68,7 +67,9 @@ public abstract class AbpTagHelperResourceService : ITransientDependency
if (file == null || !file.Exists)
{
throw new AbpException($"Could not find the bundle file '{bundleFile}' for the bundle '{bundleName}'!");
Logger.LogError($"Could not find the bundle file '{bundleFile}' for the bundle '{bundleName}'!");
AddErrorScript(viewContext, tagHelper, context, output, bundleFile, bundleName);
continue;
}
if (file.Length > 0)
@ -87,6 +88,11 @@ public abstract class AbpTagHelperResourceService : ITransientDependency
protected abstract void AddHtmlTag(ViewContext viewContext, TagHelper tagHelper, TagHelperContext context, TagHelperOutput output, string file);
protected virtual void AddErrorScript(ViewContext viewContext, TagHelper tagHelper, TagHelperContext context, TagHelperOutput output, string file, string bundleName)
{
output.Content.AppendHtml($"<script>console.log(\"%cCould not find the bundle file '{file}' for the bundle '{bundleName}'!\", 'background: yellow; font-size:20px;');</script>{Environment.NewLine}");
}
protected virtual string GenerateBundleName(List<BundleTagHelperItem> bundleItems)
{
return bundleItems.JoinAsString("|").ToMd5();

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js

@ -643,8 +643,9 @@
var momentEndDate = getMoment(endDate, options);
if (momentStartDate.isValid()) {
picker.setStartDate(momentStartDate);
picker.setEndDate(momentEndDate);
}
if (momentEndDate.isValid()) {
if (momentEndDate.isValid() && !singleDatePicker) {
picker.setEndDate(momentEndDate);
}
});
@ -761,6 +762,7 @@
abp.dom.initializers.initializeForms(args.$el.findWithSelf('form'), true);
abp.dom.initializers.initializeScript(args.$el);
abp.dom.initializers.initializeAutocompleteSelects(args.$el.findWithSelf('.auto-complete-select'));
abp.dom.initializers.initializeDateRangePickers(args.$el);
});
abp.dom.onNodeRemoved(function (args) {
@ -772,6 +774,7 @@
abp.event.on('abp.configurationInitialized', function () {
abp.libs.bootstrapDatepicker.normalizeLanguageConfig();
});
$(function () {
abp.dom.initializers.initializeToolTips($('[data-toggle="tooltip"]'));
@ -782,7 +785,6 @@
abp.dom.initializers.initializeForms($('form'));
abp.dom.initializers.initializeAutocompleteSelects($('.auto-complete-select'));
$('[data-auto-focus="true"]').first().findWithSelf('input,select').focus();
});
})(jQuery);

78
framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Internal/ResponseContentTypeHelper.cs

@ -0,0 +1,78 @@
using System;
using System.Net.Mime;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Internal;
/// <summary>
/// https://github.com/dotnet/aspnetcore/blob/release/7.0/src/Shared/ResponseContentTypeHelper.cs
/// </summary>
public static class ResponseContentTypeHelper
{
/// <summary>
/// Gets the content type and encoding that need to be used for the response.
/// The priority for selecting the content type is:
/// 1. ContentType property set on the action result
/// 2. <see cref="ContentType"/> property set on <see cref="HttpResponse"/>
/// 3. Default content type set on the action result
/// </summary>
/// <remarks>
/// The user supplied content type is not modified and is used as is. For example, if user
/// sets the content type to be "text/plain" without any encoding, then the default content type's
/// encoding is used to write the response and the ContentType header is set to be "text/plain" without any
/// "charset" information.
/// </remarks>
public static void ResolveContentTypeAndEncoding(
string? actionResultContentType,
string? httpResponseContentType,
(string defaultContentType, Encoding defaultEncoding) @default,
Func<string, Encoding> getEncoding,
out string resolvedContentType,
out Encoding resolvedContentTypeEncoding)
{
var (defaultContentType, defaultContentTypeEncoding) = @default;
// 1. User sets the ContentType property on the action result
if (actionResultContentType != null)
{
resolvedContentType = actionResultContentType;
var actionResultEncoding = getEncoding(actionResultContentType);
resolvedContentTypeEncoding = actionResultEncoding ?? defaultContentTypeEncoding;
return;
}
// 2. User sets the ContentType property on the http response directly
if (!string.IsNullOrEmpty(httpResponseContentType))
{
var mediaTypeEncoding = getEncoding(httpResponseContentType);
if (mediaTypeEncoding != null)
{
resolvedContentType = httpResponseContentType;
resolvedContentTypeEncoding = mediaTypeEncoding;
}
else
{
resolvedContentType = httpResponseContentType;
resolvedContentTypeEncoding = defaultContentTypeEncoding;
}
return;
}
// 3. Fall-back to the default content type
resolvedContentType = defaultContentType;
resolvedContentTypeEncoding = defaultContentTypeEncoding;
}
public static Encoding GetEncoding(string mediaType)
{
if (MediaTypeHeaderValue.TryParse(mediaType, out var parsed))
{
return parsed.Encoding;
}
return default;
}
}

21
framework/src/Volo.Abp.BlazoriseUI/Components/AbpExtensibleDataGrid.razor

@ -72,11 +72,22 @@
{
@if (column.Component != null)
{
<DataGridColumn TItem="TItem" Field="@typeof(TItem).GetProperties().First().Name" Caption="@column.Title">
<DisplayTemplate>
@RenderCustomTableColumnComponent(column.Component, context)
</DisplayTemplate>
</DataGridColumn>
@if (column.ValueConverter == null)
{
<DataGridColumn TItem="TItem" Field="@column.Data" Caption="@column.Title" Sortable="@column.Sortable" DisplayFormat="@column.DisplayFormat" DisplayFormatProvider="@column.DisplayFormatProvider" >
<DisplayTemplate>
@RenderCustomTableColumnComponent(column.Component, context)
</DisplayTemplate>
</DataGridColumn>
}
else
{
<DataGridColumn TItem="TItem" Field="@column.Data" Caption="@column.Title" Sortable="@column.Sortable">
<DisplayTemplate>
@RenderCustomTableColumnComponent(column.Component, context)
</DisplayTemplate>
</DataGridColumn>
}
}
else
{

724
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeThemeStep.cs

@ -10,6 +10,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps;
public class ChangeThemeStep : ProjectBuildPipelineStep
{
private const string Basic = "Basic";
private const string LeptonXLite = "LeptonXLite";
private const string LeptonX = "LeptonX";
private const string Lepton = "Lepton";
public override void Execute(ProjectBuildContext context)
{
if (!context.BuildArgs.Theme.HasValue)
@ -28,50 +33,65 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
}
protected void ChangeToBasicTheme(ProjectBuildContext context)
protected virtual void ChangeToBasicTheme(ProjectBuildContext context)
{
var defaultThemeName = context.BuildArgs.TemplateName is AppTemplate.TemplateName or AppNoLayersTemplate.TemplateName
? "LeptonXLite"
: "LeptonX";
#region MVC Projects
? LeptonXLite : LeptonX;
ChangeThemeToBasicForMvcProjects(context, defaultThemeName);
ChangeThemeToBasicForBlazorProjects(context, defaultThemeName);
ChangeThemeToBasicForBlazorServerProjects(context, defaultThemeName);
ChangeThemeForAngularProjects(context, defaultThemeName, Basic, GetAngularPackageName(context.BuildArgs.Theme!.Value), GetAngularPackageName(Theme.Basic));
}
#endregion
protected virtual void ChangeToLeptonTheme(ProjectBuildContext context)
{
//common
RenameFolders(context, oldFolderName: LeptonX , newFolderName: Lepton);
AddLeptonThemeManagementReferenceToProjects(context);
#region MyCompanyName.MyProjectName.Blazor
ChangeThemeToLeptonForMvcProjects(context);
ChangeThemeToLeptonForBlazorProjects(context);
ChangeThemeToLeptonForBlazorServerProjects(context);
ChangeThemeForAngularProjects(context, oldThemeName: LeptonX, Lepton, GetAngularPackageName(Theme.LeptonX), GetAngularPackageName(Theme.Lepton));
ConfigureLeptonManagementPackagesForNoLayersMvc(context, "/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.csproj", new[] { "Web", "HttpApi", "Application" });
ChangeThemeToLeptonForNoLayersBlazorServerProjects(context);
ChangeThemeToLeptonForMauiBlazorProjects(context);
}
private static string GetAngularPackageName(Theme theme)
{
return theme switch
{
Theme.LeptonX => "@volosoft/abp.ng.theme.lepton-x",
Theme.LeptonXLite => "@abp/ng.theme.lepton-x",
Theme.Basic => "@abp/ng.theme.basic",
_ => string.Empty
};
}
private static void ChangeThemeToBasicForBlazorProjects(ProjectBuildContext context, string defaultThemeName)
{
ReplacePackageReferenceWithProjectReference(
context,
"/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj",
$"Volo.Abp.AspNetCore.Components.WebAssembly.{defaultThemeName}Theme",
@"..\..\..\..\..\modules\basic-theme\src\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme\Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.csproj"
);
ChangeNamespaceAndKeyword(
context,
"/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs",
$"Volo.Abp.AspNetCore.Components.WebAssembly.{defaultThemeName}Theme",
"Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme",
$"AbpAspNetCoreComponentsWebAssembly{defaultThemeName}ThemeModule",
"AbpAspNetCoreComponentsWebAssemblyBasicThemeModule"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs",
$"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Themes.{defaultThemeName}",
"Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic",
$"AbpAspNetCoreComponentsWebAssembly{defaultThemeName}ThemeModule",
"AbpAspNetCoreComponentsWebAssemblyBasicThemeModule"
$"{defaultThemeName}Theme.Components",
"BasicTheme.Themes.Basic"
);
ChangeNamespace(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs",
$"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Components",
"Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic"
defaultThemeName,
Basic
);
ReplacePackageReferenceWithProjectReference(
@ -81,209 +101,94 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
@"..\..\..\..\..\modules\basic-theme\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj"
);
ChangeNamespaceAndKeyword(
context,
"/MyCompanyName.MyProjectName.Host/MyProjectNameHostModule.cs",
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling",
$"{defaultThemeName}ThemeBundles.Styles.Global",
"BasicThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.Host/MyProjectNameHostModule.cs",
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic",
$"AbpAspNetCoreMvcUi{defaultThemeName}ThemeModule",
"AbpAspNetCoreMvcUiBasicThemeModule"
defaultThemeName,
Basic
);
}
#endregion
#region Blazor.Server Projects
ChangeThemeToBasicForBlazorProjects(context, defaultThemeName);
#endregion
#region Angular
var angularPackageName = context.BuildArgs.TemplateName is AppTemplate.TemplateName or AppNoLayersTemplate.TemplateName
? "@abp/ng.theme.lepton-x"
: "@volosoft/abp.ng.theme.lepton-x";
private static void ChangeThemeForAngularProjects(ProjectBuildContext context, string oldThemeName, string newThemeName, string oldPackageName, string newPackageName)
{
if (context.BuildArgs.UiFramework != UiFramework.Angular)
{
return;
}
ReplaceImportPackage(
context,
"/angular/src/app/app.module.ts",
angularPackageName,
"@abp/ng.theme.basic"
oldPackageName,
newPackageName
);
RemoveLinesByStatement(
context,
"/angular/src/app/app.module.ts",
"SideMenuLayoutModule"
);
ReplaceMethodNames(
ReplaceAllKeywords(
context,
"/angular/src/app/app.module.ts",
"ThemeLeptonXModule",
"ThemeBasicModule"
);
RemoveLinesByStatement(
context,
"/angular/angular.json",
"node_modules/bootstrap-icons/font/bootstrap-icons.css"
$"Theme{oldThemeName}Module",
$"Theme{newThemeName}Module"
);
if(defaultThemeName == "LeptonX")
if (oldThemeName != LeptonX)
{
ReplaceMethodNames(
context,
"/angular/src/app/app.module.ts",
"HttpErrorComponent, ",
""
);
ChangeModuleImportBetweenStatements(
context,
"/angular/src/app/app.module.ts",
"ThemeSharedModule.forRoot",
"AccountAdminConfigModule.forRoot",
"ThemeSharedModule.forRoot(),"
);
return;
}
#endregion
ReplaceAllKeywords(
context,
"/angular/src/app/app.module.ts",
"HttpErrorComponent, ",
""
);
ChangeModuleImportBetweenStatements(
context,
"/angular/src/app/app.module.ts",
"ThemeSharedModule.forRoot",
"AccountAdminConfigModule.forRoot",
"ThemeSharedModule.forRoot(),"
);
}
protected void ChangeToLeptonTheme(ProjectBuildContext context)
private static void ChangeThemeToLeptonForBlazorProjects(ProjectBuildContext context)
{
#region Common
RenameLeptonXFolders(context, folderName: "Lepton");
AddLeptonThemeManagementReferenceToProjects(context);
#endregion
#region MVC Projects
ChangeThemeToLeptonForMvcProjects(context);
#endregion
#region MyCompanyName.MyProjectName.Blazor
ReplacePackageReferenceWithProjectReference(
context,
"/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj",
"Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme",
@"..\..\..\..\..\lepton-theme\src\Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme\Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme.csproj"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs",
"Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components",
"Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components",
"AbpAspNetCoreComponentsWebAssemblyLeptonXThemeModule",
"AbpAspNetCoreComponentsWebAssemblyLeptonThemeModule"
LeptonX,
Lepton
);
ChangeNamespace(
context,
"/MyCompanyName.MyProjectName.Blazor/MyProjectNameBlazorModule.cs",
"Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme",
"Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme"
);
ReplacePackageReferenceWithProjectReference(
context,
"/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX",
@"..\..\..\..\..\lepton-theme\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton\Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.csproj"
);
ChangeNamespaceAndKeyword(
context,
"/MyCompanyName.MyProjectName.Host/MyProjectNameHostModule.cs",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Bundling",
"LeptonXThemeBundles.Styles.Global",
"LeptonThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.Host/MyProjectNameHostModule.cs",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton",
"AbpAspNetCoreMvcUiLeptonXThemeModule",
"AbpAspNetCoreMvcUiLeptonThemeModule"
);
#endregion
#region MyCompanyName.MyProjectName.Blazor.Server && MyCompanyName.MyProjectName.Blazor.Server.Tiered
ChangeThemeToLeptonForBlazorServerProjects(context);
#endregion
#region Angular
ReplaceImportPackage(
context,
"/angular/src/app/app.module.ts",
"@volosoft/abp.ng.theme.lepton-x",
"@volo/abp.ng.theme.lepton"
);
RemoveLinesByStatement(
context,
"/angular/src/app/app.module.ts",
"SideMenuLayoutModule"
);
ReplaceMethodNames(
context,
"/angular/src/app/app.module.ts",
"ThemeLeptonXModule",
"ThemeLeptonModule"
);
RemoveLinesByStatement(
context,
"/angular/angular.json",
"node_modules/bootstrap-icons/font/bootstrap-icons.css"
LeptonX,
Lepton
);
#endregion
#region MyCompanyName.MyProjectName.Mvc && MyCompanyName.MyProjectName.Mvc.Mongo
var projectNames = new[] {"Web", "HttpApi", "Application"};
ConfigureLeptonManagementPackagesForNoLayersMvc(context, @"/MyCompanyName.MyProjectName.Mvc/MyCompanyName.MyProjectName.csproj", projectNames);
#endregion
#region MyCompanyName.MyProjectName.Blazor.Server && MyCompanyName.MyProjectName.Blazor.Server.Mongo - (app-nolayers)
ChangeThemeToLeptonForNoLayersBlazorServerProjects(context);
#endregion
#region MyCompanyName.MyProjectName.MauiBlazor
ChangeThemeToLeptonForMauiBlazorProjects(context);
#endregion
}
private void ConfigureLeptonManagementPackagesForNoLayersMvc(ProjectBuildContext context, string targetProjectPath, string[] projectNames)
private static void ConfigureLeptonManagementPackagesForNoLayersMvc(ProjectBuildContext context, string targetProjectPath, IEnumerable<string> projectNames)
{
var file = context.Files.FirstOrDefault(f => !f.Name.Contains("Test") && f.Name.Contains(targetProjectPath) && f.Name.Contains(".csproj"));
if (file == null)
@ -304,7 +209,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
}
private void ChangeThemeToLeptonForMvcProjects(ProjectBuildContext context)
private static void ChangeThemeToLeptonForMvcProjects(ProjectBuildContext context)
{
var projectNames = new[]
{
@ -333,23 +238,12 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX",
@"..\..\..\..\..\lepton-theme\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton\Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.csproj"
);
ChangeNamespaceAndKeyword(
context,
moduleFile.Name,
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Bundling",
"LeptonXThemeBundles.Styles.Global",
"LeptonThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
moduleFile.Name,
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton",
"AbpAspNetCoreMvcUiLeptonXThemeModule",
"AbpAspNetCoreMvcUiLeptonThemeModule"
LeptonX,
Lepton
);
RemoveLinesByStatement(
@ -360,7 +254,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
}
private void AddLeptonThemeManagementReferenceToProjects(ProjectBuildContext context)
private static void AddLeptonThemeManagementReferenceToProjects(ProjectBuildContext context)
{
var projects = new Dictionary<string, string>
{
@ -396,7 +290,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
}
private void AddUiProjectToProjects(Dictionary<string, string> projects, ProjectBuildContext context)
private static void AddUiProjectToProjects(Dictionary<string, string> projects, ProjectBuildContext context)
{
if (projects.IsNullOrEmpty())
{
@ -418,7 +312,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
}
private void AddLeptonThemeManagementReference(ProjectBuildContext context, KeyValuePair<string, string> projectInfo)
private static void AddLeptonThemeManagementReference(ProjectBuildContext context, KeyValuePair<string, string> projectInfo)
{
var reference = $@"..\..\..\..\..\lepton-theme\src\Volo.Abp.LeptonTheme.Management.{projectInfo.Key}\Volo.Abp.LeptonTheme.Management.{projectInfo.Key}.csproj";
var projectFile = context.Files.FirstOrDefault(f => !f.Name.Contains("Test") && f.Name.Contains(projectInfo.Value) && f.Name.Contains(".csproj"));
@ -439,7 +333,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
underManagementFolder: projectInfo.Key != "HttpApi");
}
private void AddModuleDependency(FileEntry moduleFile, string projectName, string dependency, bool underManagementFolder = true)
private static void AddModuleDependency(FileEntry moduleFile, string projectName, string dependency, bool underManagementFolder = true)
{
var projectNames = new[] { "Blazor", "Blazor.Server", "Blazor.WebAssembly" };
@ -460,11 +354,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
moduleFile.SetLines(lines);
}
protected void ReplacePackageReferenceWithProjectReference(
ProjectBuildContext context,
string targetProjectFilePath,
string packageReference,
string projectReference)
private static void ReplacePackageReferenceWithProjectReference(ProjectBuildContext context, string targetProjectFilePath, string packageReference, string projectReference)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(targetProjectFilePath));
if (file == null)
@ -485,97 +375,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
file.SetLines(lines);
}
protected void ChangeNamespaceAndKeyword(
ProjectBuildContext context,
string targetModuleFilePath,
string oldNamespace,
string newNamespace,
string oldKeyword,
string newKeyword)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(targetModuleFilePath));
if (file == null)
{
return;
}
file.NormalizeLineEndings();
var lines = file.GetLines();
for (var i = 0; i < lines.Length; i++)
{
if (lines[i].Contains($"using {oldNamespace}"))
{
lines[i] = lines[i].Replace($"using {oldNamespace}", $"using {newNamespace}");
}
else if (lines[i].Contains(oldKeyword))
{
lines[i] = lines[i].Replace(oldKeyword, newKeyword);
}
}
file.SetLines(lines);
}
protected void ChangeNamespace(
ProjectBuildContext context,
string targetModuleFilePath,
string oldNamespace,
string newNamespace)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(targetModuleFilePath));
if (file == null)
{
return;
}
file.NormalizeLineEndings();
var lines = file.GetLines();
for (var i = 0; i < lines.Length; i++)
{
if (lines[i].Contains($"using {oldNamespace}"))
{
lines[i] = lines[i].Replace($"using {oldNamespace}", $"using {newNamespace}");
}
}
file.SetLines(lines);
}
protected void ChangeKeyword(
ProjectBuildContext context,
string targetModuleFilePath,
string oldKeyword,
string newKeyword)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(targetModuleFilePath));
if (file == null)
{
return;
}
file.NormalizeLineEndings();
var lines = file.GetLines();
for (var i = 0; i < lines.Length; i++)
{
if (lines[i].Contains(oldKeyword))
{
lines[i] = lines[i].Replace(oldKeyword, newKeyword);
}
}
file.SetLines(lines);
}
protected void ReplaceImportPackage(
ProjectBuildContext context,
string filePath,
string oldImportPackage,
string newImportPackage)
private static void ReplaceImportPackage(ProjectBuildContext context, string filePath, string oldImportPackage, string newImportPackage)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(filePath));
if (file == null)
@ -584,6 +384,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
file.NormalizeLineEndings();
var lines = file.GetLines();
var lineIndex = lines.FindIndex(line => line.Contains($"from '{oldImportPackage}'"));
if (lineIndex == -1)
@ -595,10 +396,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
file.SetLines(lines);
}
protected void RemoveLinesByStatement(
ProjectBuildContext context,
string filePath,
string statement)
private static void RemoveLinesByStatement(ProjectBuildContext context, string filePath, string statement)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(filePath));
if (file == null)
@ -620,12 +418,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
file.SetLines(lines.Where(x => x != null));
}
private void ChangeModuleImportBetweenStatements(
ProjectBuildContext context,
string filePath,
string firstStatement,
string lastStatement,
string newStatement)
private static void ChangeModuleImportBetweenStatements(ProjectBuildContext context, string filePath, string firstStatement, string lastStatement, string newStatement)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(filePath));
if (file == null)
@ -651,36 +444,9 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
lines[i] = null;
}
file.SetLines(lines.Where(x => x != null));
}
protected void ReplaceMethodNames(
ProjectBuildContext context,
string filePath,
string oldMethodName,
string newMethodName)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(filePath));
if (file == null)
{
return;
}
file.NormalizeLineEndings();
var lines = file.GetLines();
for (var i = 0; i < lines.Length; i++)
{
if (lines[i].Contains(oldMethodName))
{
lines[i] = lines[i].Replace(oldMethodName, newMethodName);
}
}
file.SetLines(lines);
}
private static void AddProjectReference(FileEntry file, string reference)
{
if (!file.Name.Contains(".csproj"))
@ -746,7 +512,7 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
splittedProjectFileName = splittedProjectFileName.Take(splittedProjectFileName.Length - 1).ToArray();
var fileName = splittedProjectFileName?.Last();
var fileName = splittedProjectFileName.Last();
if (fileName == null)
{
return null;
@ -765,16 +531,40 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
return moduleName.Replace(".", "");
}
private static void RenameLeptonXFolders(ProjectBuildContext context, string folderName)
private static void RenameFolders(ProjectBuildContext context, string oldFolderName, string newFolderName)
{
var leptonXFiles = context.Files.Where(x => x.Name.Contains("LeptonX") && x.IsDirectory);
foreach (var file in leptonXFiles)
foreach (var file in context.Files.Where(x => x.Name.Contains(oldFolderName) && x.IsDirectory))
{
new MoveFolderStep(file.Name, file.Name.Replace("LeptonX", folderName)).Execute(context);
new MoveFolderStep(file.Name, file.Name.Replace(oldFolderName, newFolderName)).Execute(context);
}
}
private void ChangeThemeToBasicForMvcProjects(ProjectBuildContext context, string defaultThemeName)
private static void ReplaceAllKeywords(ProjectBuildContext context, string targetModuleFilePath, string oldKeyword, string newKeyword)
{
var file = context.Files.FirstOrDefault(x => x.Name.Contains(targetModuleFilePath));
if (file == null)
{
return;
}
file.NormalizeLineEndings();
var lines = file.GetLines();
for (var i = 0; i < lines.Length; i++)
{
if (!lines[i].Contains(oldKeyword))
{
continue;;
}
lines[i] = lines[i].Replace(oldKeyword, newKeyword);
}
file.SetLines(lines);
}
private static void ChangeThemeToBasicForMvcProjects(ProjectBuildContext context, string defaultThemeName)
{
var projects = new Dictionary<string, string>
{
@ -794,28 +584,17 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}",
@"..\..\..\..\..\modules\basic-theme\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName{project.Key}/{project.Value}.cs",
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic",
$"AbpAspNetCoreMvcUi{defaultThemeName}ThemeModule",
"AbpAspNetCoreMvcUiBasicThemeModule"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName{project.Key}/{project.Value}.cs",
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling",
$"{defaultThemeName}ThemeBundles.Styles.Global",
"BasicThemeBundles.Styles.Global"
defaultThemeName,
Basic
);
}
}
private void ChangeThemeToBasicForBlazorProjects(ProjectBuildContext context, string defaultThemeName)
private static void ChangeThemeToBasicForBlazorServerProjects(ProjectBuildContext context, string defaultThemeName)
{
var projects = new Dictionary<string, string>
{
@ -840,73 +619,34 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}",
@"..\..\..\..\..\modules\basic-theme\src\Volo.Abp.AspNetCore.Components.Server.BasicTheme\Volo.Abp.AspNetCore.Components.Server.BasicTheme.csproj"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/{project.Value}.cs",
$"Volo.Abp.AspNetCore.Components.Server.{defaultThemeName}Theme",
"Volo.Abp.AspNetCore.Components.Server.BasicTheme",
$"AbpAspNetCoreComponentsServer{defaultThemeName}ThemeModule",
"AbpAspNetCoreComponentsServerBasicThemeModule"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/{project.Value}.cs",
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic",
$"AbpAspNetCoreMvcUi{defaultThemeName}ThemeModule",
"AbpAspNetCoreMvcUiBasicThemeModule"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/{project.Value}.cs",
$"Volo.Abp.AspNetCore.Components.Server.{defaultThemeName}Theme.Bundling",
"Volo.Abp.AspNetCore.Components.Server.BasicTheme.Bundling",
$"{defaultThemeName}ThemeBundles.Styles.Global",
"BasicThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/{project.Value}.cs",
$"Volo.Abp.AspNetCore.Mvc.UI.Theme.{defaultThemeName}.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling",
$"Blazor{defaultThemeName}ThemeBundles.Styles.Global",
"BlazorBasicThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/Pages/_Host.cshtml",
$"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Components",
"Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic",
$"Blazor{defaultThemeName}ThemeBundles.Styles.Global",
"BlazorBasicThemeBundles.Styles.Global"
$"{defaultThemeName}Theme.Components",
Basic
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/Pages/_Host.cshtml",
$"Volo.Abp.AspNetCore.Components.Server.{defaultThemeName}Theme.Bundling",
"Volo.Abp.AspNetCore.Components.Server.BasicTheme.Bundling",
$"Blazor{defaultThemeName}ThemeBundles.Scripts.Global",
"BlazorBasicThemeBundles.Scripts.Global"
$"/MyCompanyName.MyProjectName.{project.Key}/{project.Value}.cs",
defaultThemeName,
Basic
);
ChangeNamespace(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{project.Key}/Pages/_Host.cshtml",
$"Volo.Abp.AspNetCore.Components.Web.{defaultThemeName}Theme.Themes.{defaultThemeName}",
"Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic"
defaultThemeName,
Basic
);
}
}
private void ChangeThemeToLeptonForBlazorServerProjects(ProjectBuildContext context)
private static void ChangeThemeToLeptonForBlazorServerProjects(ProjectBuildContext context)
{
var projectNames = new[] {"Blazor", "Blazor.Server.Tiered"};
var projectNames = new[] { "Blazor", "Blazor.Server.Tiered" };
foreach (var projectName in projectNames)
{
ReplacePackageReferenceWithProjectReference(
@ -922,59 +662,19 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme",
@"..\..\..\..\..\lepton-theme\src\Volo.Abp.AspNetCore.Components.Server.LeptonTheme\Volo.Abp.AspNetCore.Components.Server.LeptonTheme.csproj"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameBlazorModule.cs",
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme",
"Volo.Abp.AspNetCore.Components.Server.LeptonTheme",
"AbpAspNetCoreComponentsServerLeptonXThemeModule",
"AbpAspNetCoreComponentsServerLeptonThemeModule"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameBlazorModule.cs",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton",
"AbpAspNetCoreMvcUiLeptonXThemeModule",
"AbpAspNetCoreMvcUiLeptonThemeModule"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameBlazorModule.cs",
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.Bundling",
"Volo.Abp.AspNetCore.Components.Server.LeptonTheme.Bundling",
"LeptonXThemeBundles.Styles.Global",
"LeptonThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameBlazorModule.cs",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Bundling",
"BlazorLeptonXThemeBundles.Styles.Global",
"BlazorLeptonThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/Pages/_Host.cshtml",
"Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components",
"Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components",
"BlazorLeptonXThemeBundles.Styles.Global",
"BlazorLeptonThemeBundles.Styles.Global"
LeptonX,
Lepton
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{projectName}/Pages/_Host.cshtml",
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.Bundling",
"Volo.Abp.AspNetCore.Components.Server.LeptonTheme.Bundling",
"BlazorLeptonXThemeBundles.Scripts.Global",
"BlazorLeptonThemeBundles.Scripts.Global"
LeptonX,
Lepton
);
RemoveLinesByStatement(
@ -985,11 +685,11 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
}
}
private void ChangeThemeToLeptonForNoLayersBlazorServerProjects(ProjectBuildContext context)
private static void ChangeThemeToLeptonForNoLayersBlazorServerProjects(ProjectBuildContext context)
{
var blazorServerProjects = new[] { "Blazor.Server", "HttpApi", "Application" };
var projectNames = new[] { "Blazor.Server", "Blazor.Server.Mongo" };
foreach (var projectName in projectNames)
{
ReplacePackageReferenceWithProjectReference(
@ -1006,67 +706,29 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
@"..\..\..\..\lepton-theme\src\Volo.Abp.AspNetCore.Components.Server.LeptonTheme\Volo.Abp.AspNetCore.Components.Server.LeptonTheme.csproj"
);
ConfigureLeptonManagementPackagesForNoLayersMvc(context,
$@"/MyCompanyName.MyProjectName.{projectName}/MyCompanyName.MyProjectName.{projectName}.csproj",
blazorServerProjects);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameModule.cs",
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme",
"Volo.Abp.AspNetCore.Components.Server.LeptonTheme",
"AbpAspNetCoreComponentsServerLeptonXThemeModule",
"AbpAspNetCoreComponentsServerLeptonThemeModule"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameModule.cs",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton",
"AbpAspNetCoreMvcUiLeptonXThemeModule",
"AbpAspNetCoreMvcUiLeptonThemeModule"
);
ChangeNamespaceAndKeyword(
ConfigureLeptonManagementPackagesForNoLayersMvc(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameModule.cs",
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.Bundling",
"Volo.Abp.AspNetCore.Components.Server.LeptonTheme.Bundling",
"LeptonXThemeBundles.Styles.Global",
"LeptonThemeBundles.Styles.Global"
$@"/MyCompanyName.MyProjectName.{projectName}/MyCompanyName.MyProjectName.{projectName}.csproj",
blazorServerProjects
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{projectName}/MyProjectNameModule.cs",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling",
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Bundling",
"BlazorLeptonXThemeBundles.Styles.Global",
"BlazorLeptonThemeBundles.Styles.Global"
);
ChangeNamespaceAndKeyword(
context,
$"/MyCompanyName.MyProjectName.{projectName}/Pages/_Host.cshtml",
"Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components",
"Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components",
"BlazorLeptonXThemeBundles.Styles.Global",
"BlazorLeptonThemeBundles.Styles.Global"
LeptonX,
Lepton
);
ChangeNamespaceAndKeyword(
ReplaceAllKeywords(
context,
$"/MyCompanyName.MyProjectName.{projectName}/Pages/_Host.cshtml",
"Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.Bundling",
"Volo.Abp.AspNetCore.Components.Server.LeptonTheme.Bundling",
"BlazorLeptonXThemeBundles.Scripts.Global",
"BlazorLeptonThemeBundles.Scripts.Global"
LeptonX,
Lepton
);
}
}
private void ChangeThemeToLeptonForMauiBlazorProjects(ProjectBuildContext context)
private static void ChangeThemeToLeptonForMauiBlazorProjects(ProjectBuildContext context)
{
ReplacePackageReferenceWithProjectReference(
context,
@ -1074,44 +736,42 @@ public class ChangeThemeStep : ProjectBuildPipelineStep
"Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonXTheme",
@"..\..\..\..\..\lepton-theme\src\Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonTheme\Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonTheme.csproj"
);
ChangeNamespaceAndKeyword(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/MyProjectNameMauiBlazorModule.cs",
"Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonXTheme",
"Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonTheme",
"AbpAspNetCoreComponentsMauiBlazorLeptonXThemeModule",
"AbpAspNetCoreComponentsMauiBlazorLeptonThemeModule"
);
ChangeKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/MainPage.xaml",
"clr-namespace:Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components;assembly=Volo.Abp.AspNetCore.Components.Web.LeptonXTheme",
"clr-namespace:Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components;assembly=Volo.Abp.AspNetCore.Components.Web.LeptonTheme");
ChangeKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/MainPage.xaml",
"leptonXTheme",
"leptonTheme");
ChangeKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/Pages/Account/Login.razor",
"Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonXTheme.Components.AccountLayout",
"Volo.Abp.AspNetCore.Components.MauiBlazor.LeptonTheme.Components.AccountLayout");
ChangeKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/Pages/Account/RedirectToLogout.razor",
"LeptonXResource",
"LeptonThemeManagementResource");
ChangeKeyword(
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/Pages/Account/RedirectToLogout.razor",
"Volo.Abp.LeptonX.Shared.Localization",
"Volo.Abp.LeptonTheme.Management.Localization");
ReplaceAllKeywords(
context,
"/MyCompanyName.MyProjectName.MauiBlazor/MyProjectNameMauiBlazorModule.cs",
LeptonX,
Lepton
);
}
}
}

6
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs

@ -25,6 +25,7 @@ public abstract class MicroserviceTemplateBase : TemplateInfo
RandomizeStringEncryption(context, steps);
RandomizeAuthServerPassPhrase(context, steps);
UpdateNuGetConfig(context, steps);
UpdateDockerImages(context, steps);
ConfigureTheme(context, steps);
return steps;
@ -221,4 +222,9 @@ public abstract class MicroserviceTemplateBase : TemplateInfo
{
steps.Add(new RandomizeAuthServerPassPhraseStep());
}
private static void UpdateDockerImages(ProjectBuildContext context, List<ProjectBuildPipelineStep> steps)
{
steps.Add(new UpdateDockerImagesStep("/etc/docker/docker-compose.infrastructure.yml"));
}
}

25
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/UpdateDockerImagesStep.cs

@ -0,0 +1,25 @@
using System.Linq;
using System.Runtime.InteropServices;
using Volo.Abp.Cli.ProjectBuilding.Building;
using Volo.Abp.Cli.ProjectBuilding.Files;
namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice;
public class UpdateDockerImagesStep : ProjectBuildPipelineStep
{
private readonly string _ymlFilePath;
public UpdateDockerImagesStep(string ymlFilePath)
{
_ymlFilePath = ymlFilePath;
}
public override void Execute(ProjectBuildContext context)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.OSArchitecture == Architecture.Arm64)
{
var file = context.Files.FirstOrDefault(f => f.Name == _ymlFilePath);
file?.ReplaceText("mcr.microsoft.com/mssql/server:2019-latest", "mcr.microsoft.com/azure-sql-edge");
}
}
}

3
framework/src/Volo.Abp.Ddd.Domain.Shared/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
framework/src/Volo.Abp.Ddd.Domain.Shared/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

22
framework/src/Volo.Abp.Ddd.Domain.Shared/Volo.Abp.Ddd.Domain.Shared.csproj

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net7.0</TargetFrameworks>
<AssemblyName>Volo.Abp.Ddd.Domain.Shared</AssemblyName>
<PackageId>Volo.Abp.Ddd.Domain.Shared</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.EventBus.Abstractions\Volo.Abp.EventBus.Abstractions.csproj" />
</ItemGroup>
</Project>

14
framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/AbpDddDomainSharedModule.cs

@ -0,0 +1,14 @@
using Volo.Abp.EventBus.Abstractions;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Domain;
[DependsOn(
typeof(AbpMultiTenancyModule),
typeof(AbpEventBusAbstractionsModule)
)]
public class AbpDddDomainSharedModule : AbpModule
{
}

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityCreatedEto.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityCreatedEto.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityDeletedEto.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityDeletedEto.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityEto.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityUpdatedEto.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EntityUpdatedEto.cs

1
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using Volo.Abp.EventBus.Distributed;
namespace Volo.Abp.Domain.Entities.Events.Distributed;

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IEntityEto.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityEto.cs

0
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs → framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/IEntityToEtoMapper.cs

1
framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj

@ -15,6 +15,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Ddd.Domain.Shared\Volo.Abp.Ddd.Domain.Shared.csproj" />
<ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" />
<ProjectReference Include="..\Volo.Abp.Caching\Volo.Abp.Caching.csproj" />
<ProjectReference Include="..\Volo.Abp.Data\Volo.Abp.Data.csproj" />

3
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs

@ -22,7 +22,8 @@ namespace Volo.Abp.Domain;
typeof(AbpObjectMappingModule),
typeof(AbpExceptionHandlingModule),
typeof(AbpSpecificationsModule),
typeof(AbpCachingModule)
typeof(AbpCachingModule),
typeof(AbpDddDomainSharedModule)
)]
public class AbpDddDomainModule : AbpModule
{

2
framework/src/Volo.Abp.EventBus.Abstractions/Volo.Abp.EventBus.Abstractions.csproj

@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj" />
</ItemGroup>
</Project>

4
framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Abstractions/AbpEventBusAbstractionsModule.cs

@ -1,7 +1,11 @@
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.EventBus.Abstractions;
[DependsOn(
typeof(AbpObjectExtendingModule)
)]
public class AbpEventBusAbstractionsModule : AbpModule
{

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventInbox.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IEventInbox.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IEventOutbox.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IInboxProcessor.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IInboxProcessor.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IOutboxSender.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IOutboxSender.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxConfig.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfig.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxConfigDictionary.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfigDictionary.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfig.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfig.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfigDictionary.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfigDictionary.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutgoingEventInfo.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventBus.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataWithInheritableGenericArgument.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventDataWithInheritableGenericArgument.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandlerDisposeWrapper.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventHandlerDisposeWrapper.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandlerFactory.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventHandlerFactory.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandlerInvoker.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/IEventHandlerInvoker.cs

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs → framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/ILocalEventBus.cs

17
framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/LocalEventHandlerOrderAttribute.cs

@ -0,0 +1,17 @@
using System;
namespace Volo.Abp.EventBus.Local;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class LocalEventHandlerOrderAttribute : Attribute
{
/// <summary>
/// Handlers execute in ascending numeric value of the Order property.
/// </summary>
public int Order { get; set; }
public LocalEventHandlerOrderAttribute(int order)
{
Order = order;
}
}

14
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs

@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Reflection;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
@ -138,14 +139,19 @@ public class LocalEventBus : EventBusBase, ILocalEventBus, ISingletonDependency
protected override IEnumerable<EventTypeWithEventHandlerFactories> GetHandlerFactories(Type eventType)
{
var handlerFactoryList = new List<EventTypeWithEventHandlerFactories>();
var handlerFactoryList = new List<Tuple<IEventHandlerFactory, Type, int>>();
foreach (var handlerFactory in HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key)))
{
handlerFactoryList.Add(new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value));
foreach (var factory in handlerFactory.Value)
{
handlerFactoryList.Add(new Tuple<IEventHandlerFactory, Type, int>(
factory,
handlerFactory.Key,
ReflectionHelper.GetAttributesOfMemberOrDeclaringType<LocalEventHandlerOrderAttribute>(factory.GetHandler().EventHandler.GetType()).FirstOrDefault()?.Order ?? 0));
}
}
return handlerFactoryList.ToArray();
return handlerFactoryList.OrderBy(x => x.Item3).Select(x => new EventTypeWithEventHandlerFactories(x.Item2, new List<IEventHandlerFactory> {x.Item1})).ToArray();
}
private List<IEventHandlerFactory> GetOrCreateHandlerFactories(Type eventType)

18
framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_MultiTenancyMiddlewareErrorPageBuilder_Tests.cs

@ -1,9 +1,10 @@
using System.Collections.Generic;
using System.Net;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Shouldly;
using Volo.Abp.Http;
using Xunit;
namespace Volo.Abp.AspNetCore.MultiTenancy;
@ -23,4 +24,17 @@ public class AspNetCoreMultiTenancy_MultiTenancyMiddlewareErrorPageBuilder_Tests
var result = await GetResponseAsStringAsync($"http://abp.io?{_options.TenantKey}=<script>alert(hi)</script>", HttpStatusCode.NotFound);
result.ShouldNotContain("<script>alert(hi)</script>");
}
[Fact]
public async Task MultiTenancyMiddlewareErrorPageBuilder_Ajax_Test()
{
using (var response = await GetResponseAsync($"http://abp.io?{_options.TenantKey}=abpio", HttpStatusCode.NotFound, xmlHttpRequest: true))
{
var result = await response.Content.ReadAsStringAsync();
var error = JsonSerializer.Deserialize<RemoteServiceErrorResponse>(result, new JsonSerializerOptions {PropertyNamingPolicy = JsonNamingPolicy.CamelCase});
error.Error.ShouldNotBeNull();
error.Error.Message.ShouldBe("Tenant not found!");
error.Error.Details.ShouldBe("There is no tenant with the tenant id or name: abpio");
}
}
}

56
framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Order_Test.cs

@ -0,0 +1,56 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Events;
using Xunit;
namespace Volo.Abp.EventBus.Local;
public class EventBus_Order_Test : EventBusTestBase
{
public static string HandlerExecuteOrder { get; set; }
[Fact]
public async Task Handler_Should_Execute_By_Order()
{
HandlerExecuteOrder = "";
await LocalEventBus.PublishAsync(new MyOrderEventHandlerEventData());
HandlerExecuteOrder.ShouldBe("321");
}
public class MyOrderEventHandlerEventData
{
}
public class MyOrderEventHandler : ILocalEventHandler<MyOrderEventHandlerEventData>, ITransientDependency
{
public Task HandleEventAsync(MyOrderEventHandlerEventData eventData)
{
HandlerExecuteOrder += "1";
return Task.CompletedTask;
}
}
[LocalEventHandlerOrder(-2)]
public class MyOrderEventHandler2 : ILocalEventHandler<MyOrderEventHandlerEventData>, ITransientDependency
{
public Task HandleEventAsync(MyOrderEventHandlerEventData eventData)
{
HandlerExecuteOrder += "2";
return Task.CompletedTask;
}
}
[LocalEventHandlerOrder(-3)]
public class MyOrderEventHandler3 : ILocalEventHandler<MyOrderEventHandlerEventData>, ITransientDependency
{
public Task HandleEventAsync(MyOrderEventHandlerEventData eventData)
{
HandlerExecuteOrder += "3";
return Task.CompletedTask;
}
}
}

2
latest-versions.json

@ -1,6 +1,6 @@
[
{
"version": "7.2.1",
"version": "7.2.2",
"releaseDate": "",
"type": "stable",
"message": ""

2
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json

@ -3,7 +3,7 @@
"name": "asp.net",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.shared": "~7.2.1",
"@abp/aspnetcore.mvc.ui.theme.shared": "~7.2.2",
"highlight.js": "^9.13.1"
},
"devDependencies": {}

244
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock

@ -2,32 +2,32 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.1.tgz#68903cb3fafca670d603e658f20e435734e3d738"
integrity sha512-B7gGe8qAjvMsLfqxFVdvGFfMylV3NQzthXT/BMoq1MtgMdLKrrpeu6Oz3mIr68IuFlA38edqlm8Scy+iknD+Xg==
dependencies:
"@abp/aspnetcore.mvc.ui" "~7.2.1"
"@abp/bootstrap" "~7.2.1"
"@abp/bootstrap-datepicker" "~7.2.1"
"@abp/bootstrap-daterangepicker" "~7.2.1"
"@abp/datatables.net-bs5" "~7.2.1"
"@abp/font-awesome" "~7.2.1"
"@abp/jquery-form" "~7.2.1"
"@abp/jquery-validation-unobtrusive" "~7.2.1"
"@abp/lodash" "~7.2.1"
"@abp/luxon" "~7.2.1"
"@abp/malihu-custom-scrollbar-plugin" "~7.2.1"
"@abp/moment" "~7.2.1"
"@abp/select2" "~7.2.1"
"@abp/sweetalert2" "~7.2.1"
"@abp/timeago" "~7.2.1"
"@abp/toastr" "~7.2.1"
"@abp/aspnetcore.mvc.ui@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.1.tgz#b4ae5dcdb90983673092dbfee93c16f21cbb21fe"
integrity sha512-edBAWEKQnUdH8jgY+QDECs3BFu0qIXbMV/AiTH9j64uo4ADQ6rgJ6Uq7xy6YtxJ0uImFkgLXDd9LYQEPvU43Bg==
"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.2.tgz#ef5feee85db6f0168bc9b2c1fb058992be6c6d55"
integrity sha512-XayukLpXEQj3VEw0YDqfCOR7QfU1nEe6aGtc9CfG9cGXMIDZFs6lxI0fbRdRR89m7T5POtDlrhr81yTkzSd1SA==
dependencies:
"@abp/aspnetcore.mvc.ui" "~7.2.2"
"@abp/bootstrap" "~7.2.2"
"@abp/bootstrap-datepicker" "~7.2.2"
"@abp/bootstrap-daterangepicker" "~7.2.2"
"@abp/datatables.net-bs5" "~7.2.2"
"@abp/font-awesome" "~7.2.2"
"@abp/jquery-form" "~7.2.2"
"@abp/jquery-validation-unobtrusive" "~7.2.2"
"@abp/lodash" "~7.2.2"
"@abp/luxon" "~7.2.2"
"@abp/malihu-custom-scrollbar-plugin" "~7.2.2"
"@abp/moment" "~7.2.2"
"@abp/select2" "~7.2.2"
"@abp/sweetalert2" "~7.2.2"
"@abp/timeago" "~7.2.2"
"@abp/toastr" "~7.2.2"
"@abp/aspnetcore.mvc.ui@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.2.tgz#cc0ca317bf71fcc3c25dcc4bfd6e4521219a2b05"
integrity sha512-frRTtiGeXDuZbMxBAAPFlWMDoSHkTP0iPE2dAV7YC28W/lHrf6bJsS2CoB2dHmUjp5IB2LSQnaQuR7ihXRtx0A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@ -36,158 +36,158 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
"@abp/bootstrap-datepicker@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.1.tgz#eca6c1138074ce222ff6c474bc51f4fbe05882c3"
integrity sha512-DUBEz8wzsWJlEfQ7CZJYemLE/wNYyY7LtWRBRjNFndS8P2xo3FP4xuh0mnovSZ3AXPy7oAAKg0zayFzf3XS4aw==
"@abp/bootstrap-datepicker@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.2.tgz#2b88db99296d0905f04731b5e2d95955e6a79717"
integrity sha512-JEDv3DJprgOf8T///Wzxg/CTKapvfcvfPOeTULhs0M039Sk3xLRBv/HG9YgxexjLh8zVWKfd5T5oiWj07KMC8A==
dependencies:
bootstrap-datepicker "^1.9.0"
"@abp/bootstrap-daterangepicker@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.1.tgz#ad236d026c3596e71a6a2088e5332e00d62c8ff7"
integrity sha512-WF/3qQobtvizWGmycgkzHMIjHJoLYAnCsi+vJPzv+VqvGstnQOgkz/rlfcu7uAp9y5H4OWdSAbkOj9eELNfxlA==
"@abp/bootstrap-daterangepicker@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.2.tgz#ef4a8837ebf35ac715af06cdfa7584751447cd80"
integrity sha512-o/uFPBhNFDzGpyE9xIU4U5hqZMmeXqRSWwLdMFEt4AmOCTPXndC9eIZRpZs9fYmsNsQIA6S0kXuUxMTSOmR/Jw==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.1.tgz#94d8186af2f1a1ed4d558756ffa18fd43f26e318"
integrity sha512-nU3mBK0VVgkDJqu5CBOHAD1FNvKSO6wnfX5wSB+IYDIfAV9wsmiTIMx6YO8psjMOd4flEmlKLALK6p17i79jhw==
"@abp/bootstrap@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.2.tgz#9fc80c6110d519d4bd53aba4f70e6c9afa227793"
integrity sha512-Eg7i+4VL62ex1C/7IaU1m8hEY4zy+QqdqeQtvb+ogKjLSM/SCE8ck+WC2749UOaso9yf7s9Eb4QMkVQ/MSMwrw==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
bootstrap "^5.1.3"
"@abp/core@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.1.tgz#5685d615482daa032ab24f49aeb7fff3f50af898"
integrity sha512-N99Ee/rbtXFaV3vdGfv6Mbj1Zav73oBGGNbzmAiQaO/g1hda6ndzSC9WzRJkJ7MaJKTPNJx1ExBNEcNMw1P2UA==
"@abp/core@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.2.tgz#b5d403289181094ecd92cb8d963292ba8d7afe67"
integrity sha512-4laOq4dsya/oUCbmz6JvZdiEXADFVgXdfncS//EZWJJvDVzasfO0Sf71qkj233aYQ6PmClSZarZJSottzdr8vw==
dependencies:
"@abp/utils" "~7.2.1"
"@abp/utils" "~7.2.2"
"@abp/datatables.net-bs5@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.1.tgz#0474e874729a51a7e87f2ebfa931ecd8e6fe3eed"
integrity sha512-7AvNK0mYHWcdbQJAH6/PV9yjz/FbJlVHWP7mOREd6DIkg+Q8Ihmqjn8bnJyhN2UeRMTz9EZU2nO+E9oAllYlog==
"@abp/datatables.net-bs5@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.2.tgz#7a8aa9173a219d28949cde69037b9d601e4c75fd"
integrity sha512-vrqcuvMksITTtRF35xk0+cPOnr+oO7nPGFN5zHVXHYf2pZP2/GqPcBo4s9arwaJ3bQ49slQV+fdugSULUFIeFQ==
dependencies:
"@abp/datatables.net" "~7.2.1"
"@abp/datatables.net" "~7.2.2"
datatables.net-bs5 "^1.11.4"
"@abp/datatables.net@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.1.tgz#30aeec4c37cc76e5c4dff78dee433c0b42599e41"
integrity sha512-AM6LonrGTOA2VyRme5rT/DcVX0TF2WxSRiM7vpTajq4A16O8yceos/XXop4QEGjGCPGbRqUuWQsIAxXRpcwYJQ==
"@abp/datatables.net@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.2.tgz#3c4c7cad18bd87085d6042f63a9de88908e8dfe0"
integrity sha512-8Fyqd+iUFwy5MH8RVnfwNhcFMys3JgzxBh6ipNnCSI+O+haeauC5anYpEVCZesdBqSsOnv0seL7jvgPKK6ThKQ==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
datatables.net "^1.11.4"
"@abp/font-awesome@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.1.tgz#58751a48e7a648edb075d5a424c4ed9c6448e8e5"
integrity sha512-jIYHdXtijkd0b823Gd8pDqXmJ8luA0n4NqnF6MuZtQaz95CY8o0SNc7iGSJep3Gfi9XVVUVkXqWE2Gc82uyaNA==
"@abp/font-awesome@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.2.tgz#24047769ba81762720e6ff0a9dc59074e7decc97"
integrity sha512-YIaNNs9PIUNKa72tI5AOlvFXZ5KB7ZkPSxtYzEQgjeAiLFSn9F6j2lxTSwEZeoa53fQ8qChnUcdLv+5b/FrpoQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
"@fortawesome/fontawesome-free" "^5.15.4"
"@abp/jquery-form@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.1.tgz#b09398cfb0abef4255a5bb1853c67ef9bfa76f49"
integrity sha512-Jqgog1AJHsCP3lLhUkCXMUzzk2XhAW9pje5dwSdKqE0/bg2OOGo1L3LKUFeEk9dWuMVRkrLRmfdcGRt1SRb4rQ==
"@abp/jquery-form@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.2.tgz#f9f8d75072f8090b03c89471afb9565cb2fc55b9"
integrity sha512-OHj3w4eUwivDymETk7RHxAE25pOOB/IiHB1/w/3axDgAdWaWERWnXnCZFfi+QV+8dmrXySzUecicOxXoL12NEA==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.1.tgz#a62f85c7226d71588d1aa732739b3434c43f40e9"
integrity sha512-pEleVw7js8SpIRX73U5ccrfvc0H7Lxfa761wH9WglQOgC0Z1dAkJWbqr/6zKuUi3sVECYgFK8RcVm8/oPRGMzw==
"@abp/jquery-validation-unobtrusive@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.2.tgz#0dbb9fa0970d65cd56447fdc17828fd3f4147534"
integrity sha512-3CUdINe6BXzPuDP08lWDdYON+mBVHHP37Xyt8AKqD3Qk0TMoBy2QYz4pdxS2ifn97p1f51J/jP701vNJtNVtMQ==
dependencies:
"@abp/jquery-validation" "~7.2.1"
"@abp/jquery-validation" "~7.2.2"
jquery-validation-unobtrusive "^3.2.12"
"@abp/jquery-validation@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.1.tgz#e8506f0513d26ae3550cb9410ce500e20065d9cb"
integrity sha512-QuCQV2UhKUXwOgYfwKMdu959lWSTOPR83wDTbuTAYd9nsOpCHmhDMApVT0hv44Jv+/ZmE360mkpogzkb0abxLg==
"@abp/jquery-validation@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.2.tgz#9683b25e83ac3dec1a7533c25455c42e73d81630"
integrity sha512-78NL177q1G1AOzUOhqmeAKc/3X/TgK1p+0SqWob9G83ADs7ZK5DV/uR73fs35KNYcnQI9aPwl2XzJ4hPHUZ+Qw==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
jquery-validation "^1.19.3"
"@abp/jquery@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.1.tgz#4ac9cd9ba4710f8dccaa145c17cef00e147efe6f"
integrity sha512-W2qE9LP6BCp1bdOMiup4MuB/R7Plj9se+1Sct1EeF1AnpNXv4IvVr5aGEy0/gKeeHvOrHB4wKIXcBhURFSAY1w==
"@abp/jquery@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.2.tgz#b4034ab5e193ad111ed8a2c36df97b97ecc13aaf"
integrity sha512-Uz75FDBU8R0cu5ATeudy6Ho7Fv1pg2brcQlJ+kYUxXoRmeX2j5H8+vhQGkNpMmtg7xyb4BS7tZyEtuDS9mlvpQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
jquery "~3.6.0"
"@abp/lodash@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.1.tgz#36d60374a9fc2130c1f7bd264902d78221fa3b5b"
integrity sha512-XFZrxijDLhKqtL4LL3x9C/TvnJs/MIjmNwJ7+Ieg26fo2IFqYg2+hIieCUqGzn66IBwUAoRR0Cqa66erxijDlA==
"@abp/lodash@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.2.tgz#c391d06726800807df4f25e51a28f3e6cb03de5d"
integrity sha512-Mbe/wdqfBoHbf19dEUy2IMLek7P6a2PWQsVygoyb5phb+hGm0Qy5h4g0IhFiRRWChXnjRQeDnZINdXHl8RMzuQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
lodash "^4.17.21"
"@abp/luxon@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.1.tgz#eb31dd7242be766f995954924e0127f2b58e4516"
integrity sha512-lSzulfTa4RPOcp80wmDUQFN9BatTASgYnYfu9RK9U/Fi2nV5KvqzUvRkB/XTitupLaoTJfV5h8Cpf47QMgiLSw==
"@abp/luxon@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.2.tgz#0d99a16bf34288deeae835753e6bab92efd6f060"
integrity sha512-rnz4ljwArJCwf7riFDJrIjZW0bJUXlodeM7IGWCD0Mj7r5t0n+FX9ngcJfKf+zC7ICYMaPCsz+QeUX6ycTZdOw==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
luxon "^2.3.0"
"@abp/malihu-custom-scrollbar-plugin@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.1.tgz#d3b8aa15774a34f0abe704e416b00d8be76d3346"
integrity sha512-xqsjMQJez25mFwNRTUdHTQl78tYJ9+NEmEYLjpo+qRbs2hBExZQO67gTuO6TKvPRBCVgMiIcdpuegtoFhZLl5g==
"@abp/malihu-custom-scrollbar-plugin@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.2.tgz#a843d02519ff193633c41845312c9f7741606eb7"
integrity sha512-kw9364TJuc/z7uCKZsmHDyv7gsdR8jxp+jTvkubemLuFH6fHgbL5Q77jWp5AcjI03lskaWK0Rnjsa9Ahqt/chA==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.1.tgz#07bcaeb408b0025f2e8c2a7b259f5f27e05f8d25"
integrity sha512-L7EvEKEyl9RsPnSVbPwL3QC3xcKqkaLtZo75wTws2o5hXHs4f4mkADdnpfjCYFFZ+H0vMYjxzKYNI8rHm/ZU0g==
"@abp/moment@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.2.tgz#353495c3ad2d393b3a50fbe24a731a569f6f001d"
integrity sha512-bdlfPH2uKxv1JdxGi4xAKOsN+LFQk7yV28WuAm05c16GH4YnOVHTUXZXEMNSt1cRz0GQesWwqpDrtZrKyLkptw==
dependencies:
moment "^2.9.0"
"@abp/select2@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.1.tgz#c2d9494d09395691792ede04bf3d7173ebd35a95"
integrity sha512-AW1ylrPQv+WeT3HdQQqy09uvxSeWPzxLhVEylL+HIGFn3TwMCVo2DtgnxSYde4WCpDMRlYzkWlUBX5y9UzhArw==
"@abp/select2@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.2.tgz#f5e2fbc377c7a482b59e9f177c3a9f1f73d7f94f"
integrity sha512-mZqcNZ7Te7JzePUFKowjZWO90TH/9rlvkm4tx5q8PMYkV9Pk/aGbw5Gi7nGJHLEcy1g1fI0N5aL/UQzckeC99w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
select2 "^4.0.13"
"@abp/sweetalert2@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.1.tgz#ab11b3ef48ca55687a8afb0f8fca0b9e696d10a3"
integrity sha512-qGMQE7I3bnCN0xwliBP+y+1m5nx7mOYc2yuTozNLdNpmNgT0TAkjyvufn99JQBPoFju+VjMEjS5R005RbvLuVQ==
"@abp/sweetalert2@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.2.tgz#9cd0fc631dcf9989a2189217b7b5f3437cb4f376"
integrity sha512-KMBaMyk9iUqzceGfxR1dGx+wZylOz4f7mN9Owj7Jn9MjMGZoFUoyJ96PFD4rLy2m/8g3Jn70dbmnynpF1P8x+w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
sweetalert2 "^11.3.6"
"@abp/timeago@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.1.tgz#0fad3c1d7b0678ca63a47f9ba6f5702a162f6857"
integrity sha512-1M6WWQ/kPdndMPhgJ5/I22NjxLgmHM4b4sLaKATIH5D4EM7aii22RiM5cSBVAKoJZjJ8S3R28g78zS01xKrSnw==
"@abp/timeago@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.2.tgz#a0fac76f78d679892c0a5653d3a68044529245fa"
integrity sha512-3qLRrDQ1qC+E8YbsPiFxGf7ZzIlbKS3ObE2ixULKoarjJE8yDnHV2vfkSX1kYGsiN50yasUUG88U+JHLbhyx8w==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
timeago "^1.6.7"
"@abp/toastr@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.1.tgz#6ddc793e0a66e2b1f9dd192530ad46aacfd60cb2"
integrity sha512-BkLohyVJxLx0aJ6WJ2iBRV8y20JWfgoRCpzGUCcAhAp+BBF9FVhVxxZo0loFjprFprvLjJK91Z0bErJW6BWvFQ==
"@abp/toastr@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.2.tgz#30e8039ceeff66bdd7c438c3c6cd583deeb71965"
integrity sha512-Jmmkcv2B3fdGbDJaBXeqRtctQXx8cTEb+PgyqtVRG/M0Wy7hhbMYn0U+t3KflGpZzH+AN5ReAdNbjXpM3wgFmA==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
toastr "^2.1.4"
"@abp/utils@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.1.tgz#a0d5a6de02cb1b68d096399bb03771a8bb9b03b5"
integrity sha512-1QAdnFH9RD03w5mqNCz2G4mCuEPRgAJNLvFAEu9RTkL6EhOsCCQSG5mzA4cTWNDvVlNcUF8uyroXmlUvuzpYHg==
"@abp/utils@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.2.tgz#6054baa822d52f08452e8405c7a391aaedee7de0"
integrity sha512-VB9ijoPvB2tHInc1XrcvTvEzYANh+V1BliyScNTG9tr09q2pvn5jHp8Jixtu7GewCy8dh7cyueqhbnuozxedjg==
dependencies:
just-compare "^1.3.0"

4
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json

@ -3,8 +3,8 @@
"name": "asp.net",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~7.2.1",
"@abp/prismjs": "~7.2.1"
"@abp/aspnetcore.mvc.ui.theme.basic": "~7.2.2",
"@abp/prismjs": "~7.2.2"
},
"devDependencies": {}
}

280
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock

@ -2,39 +2,39 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-7.2.1.tgz#34a948ef593442995bf663fd5c0d3ab4fd7390e8"
integrity sha512-AxtugI8e8n6BDklLV/z9oZQzmpF3oEhIVyr1dxv55hIBe8GcOZHA/9CqKHY/OpSwch7ka0EEPrHawCvylcNAdQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.1"
"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.1.tgz#68903cb3fafca670d603e658f20e435734e3d738"
integrity sha512-B7gGe8qAjvMsLfqxFVdvGFfMylV3NQzthXT/BMoq1MtgMdLKrrpeu6Oz3mIr68IuFlA38edqlm8Scy+iknD+Xg==
dependencies:
"@abp/aspnetcore.mvc.ui" "~7.2.1"
"@abp/bootstrap" "~7.2.1"
"@abp/bootstrap-datepicker" "~7.2.1"
"@abp/bootstrap-daterangepicker" "~7.2.1"
"@abp/datatables.net-bs5" "~7.2.1"
"@abp/font-awesome" "~7.2.1"
"@abp/jquery-form" "~7.2.1"
"@abp/jquery-validation-unobtrusive" "~7.2.1"
"@abp/lodash" "~7.2.1"
"@abp/luxon" "~7.2.1"
"@abp/malihu-custom-scrollbar-plugin" "~7.2.1"
"@abp/moment" "~7.2.1"
"@abp/select2" "~7.2.1"
"@abp/sweetalert2" "~7.2.1"
"@abp/timeago" "~7.2.1"
"@abp/toastr" "~7.2.1"
"@abp/aspnetcore.mvc.ui@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.1.tgz#b4ae5dcdb90983673092dbfee93c16f21cbb21fe"
integrity sha512-edBAWEKQnUdH8jgY+QDECs3BFu0qIXbMV/AiTH9j64uo4ADQ6rgJ6Uq7xy6YtxJ0uImFkgLXDd9LYQEPvU43Bg==
"@abp/aspnetcore.mvc.ui.theme.basic@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-7.2.2.tgz#6cc7f3390429413ac916f0bb450025371a64e48a"
integrity sha512-6CjJ/7DGPI9q192YYuJomq9ul0lUeOvZWZM1BJ7PSV/K8rAJotIGUoLtFttv+786zxyy/sCfaJGcObg6Kij8Bg==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.2"
"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.2.tgz#ef5feee85db6f0168bc9b2c1fb058992be6c6d55"
integrity sha512-XayukLpXEQj3VEw0YDqfCOR7QfU1nEe6aGtc9CfG9cGXMIDZFs6lxI0fbRdRR89m7T5POtDlrhr81yTkzSd1SA==
dependencies:
"@abp/aspnetcore.mvc.ui" "~7.2.2"
"@abp/bootstrap" "~7.2.2"
"@abp/bootstrap-datepicker" "~7.2.2"
"@abp/bootstrap-daterangepicker" "~7.2.2"
"@abp/datatables.net-bs5" "~7.2.2"
"@abp/font-awesome" "~7.2.2"
"@abp/jquery-form" "~7.2.2"
"@abp/jquery-validation-unobtrusive" "~7.2.2"
"@abp/lodash" "~7.2.2"
"@abp/luxon" "~7.2.2"
"@abp/malihu-custom-scrollbar-plugin" "~7.2.2"
"@abp/moment" "~7.2.2"
"@abp/select2" "~7.2.2"
"@abp/sweetalert2" "~7.2.2"
"@abp/timeago" "~7.2.2"
"@abp/toastr" "~7.2.2"
"@abp/aspnetcore.mvc.ui@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.2.tgz#cc0ca317bf71fcc3c25dcc4bfd6e4521219a2b05"
integrity sha512-frRTtiGeXDuZbMxBAAPFlWMDoSHkTP0iPE2dAV7YC28W/lHrf6bJsS2CoB2dHmUjp5IB2LSQnaQuR7ihXRtx0A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@ -43,175 +43,175 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
"@abp/bootstrap-datepicker@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.1.tgz#eca6c1138074ce222ff6c474bc51f4fbe05882c3"
integrity sha512-DUBEz8wzsWJlEfQ7CZJYemLE/wNYyY7LtWRBRjNFndS8P2xo3FP4xuh0mnovSZ3AXPy7oAAKg0zayFzf3XS4aw==
"@abp/bootstrap-datepicker@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.2.tgz#2b88db99296d0905f04731b5e2d95955e6a79717"
integrity sha512-JEDv3DJprgOf8T///Wzxg/CTKapvfcvfPOeTULhs0M039Sk3xLRBv/HG9YgxexjLh8zVWKfd5T5oiWj07KMC8A==
dependencies:
bootstrap-datepicker "^1.9.0"
"@abp/bootstrap-daterangepicker@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.1.tgz#ad236d026c3596e71a6a2088e5332e00d62c8ff7"
integrity sha512-WF/3qQobtvizWGmycgkzHMIjHJoLYAnCsi+vJPzv+VqvGstnQOgkz/rlfcu7uAp9y5H4OWdSAbkOj9eELNfxlA==
"@abp/bootstrap-daterangepicker@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.2.tgz#ef4a8837ebf35ac715af06cdfa7584751447cd80"
integrity sha512-o/uFPBhNFDzGpyE9xIU4U5hqZMmeXqRSWwLdMFEt4AmOCTPXndC9eIZRpZs9fYmsNsQIA6S0kXuUxMTSOmR/Jw==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.1.tgz#94d8186af2f1a1ed4d558756ffa18fd43f26e318"
integrity sha512-nU3mBK0VVgkDJqu5CBOHAD1FNvKSO6wnfX5wSB+IYDIfAV9wsmiTIMx6YO8psjMOd4flEmlKLALK6p17i79jhw==
"@abp/bootstrap@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.2.tgz#9fc80c6110d519d4bd53aba4f70e6c9afa227793"
integrity sha512-Eg7i+4VL62ex1C/7IaU1m8hEY4zy+QqdqeQtvb+ogKjLSM/SCE8ck+WC2749UOaso9yf7s9Eb4QMkVQ/MSMwrw==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
bootstrap "^5.1.3"
"@abp/clipboard@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-7.2.1.tgz#dab262b84aa956eeb3a145461b662c5ae851b4a8"
integrity sha512-72C3QMEMMtXzjv6GTJJiILSJ1ScBidcKdahrRLlomo4TgCIEgg1+oYL3Q0uyrlB5I0mUqBaf+qYlxXue8JdRAQ==
"@abp/clipboard@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-7.2.2.tgz#e8130fc671b1c3dc85517a8f8bae1bb4c6fac64f"
integrity sha512-QiFMsawpo3e6ZV3OKe0F21vXHRv2X1WZoivQ4yYordM7QtLZG0bdftIGA1jPcKbWoSOc8wfFZszzXuceeI8U5w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
clipboard "^2.0.8"
"@abp/core@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.1.tgz#5685d615482daa032ab24f49aeb7fff3f50af898"
integrity sha512-N99Ee/rbtXFaV3vdGfv6Mbj1Zav73oBGGNbzmAiQaO/g1hda6ndzSC9WzRJkJ7MaJKTPNJx1ExBNEcNMw1P2UA==
"@abp/core@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.2.tgz#b5d403289181094ecd92cb8d963292ba8d7afe67"
integrity sha512-4laOq4dsya/oUCbmz6JvZdiEXADFVgXdfncS//EZWJJvDVzasfO0Sf71qkj233aYQ6PmClSZarZJSottzdr8vw==
dependencies:
"@abp/utils" "~7.2.1"
"@abp/utils" "~7.2.2"
"@abp/datatables.net-bs5@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.1.tgz#0474e874729a51a7e87f2ebfa931ecd8e6fe3eed"
integrity sha512-7AvNK0mYHWcdbQJAH6/PV9yjz/FbJlVHWP7mOREd6DIkg+Q8Ihmqjn8bnJyhN2UeRMTz9EZU2nO+E9oAllYlog==
"@abp/datatables.net-bs5@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.2.tgz#7a8aa9173a219d28949cde69037b9d601e4c75fd"
integrity sha512-vrqcuvMksITTtRF35xk0+cPOnr+oO7nPGFN5zHVXHYf2pZP2/GqPcBo4s9arwaJ3bQ49slQV+fdugSULUFIeFQ==
dependencies:
"@abp/datatables.net" "~7.2.1"
"@abp/datatables.net" "~7.2.2"
datatables.net-bs5 "^1.11.4"
"@abp/datatables.net@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.1.tgz#30aeec4c37cc76e5c4dff78dee433c0b42599e41"
integrity sha512-AM6LonrGTOA2VyRme5rT/DcVX0TF2WxSRiM7vpTajq4A16O8yceos/XXop4QEGjGCPGbRqUuWQsIAxXRpcwYJQ==
"@abp/datatables.net@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.2.tgz#3c4c7cad18bd87085d6042f63a9de88908e8dfe0"
integrity sha512-8Fyqd+iUFwy5MH8RVnfwNhcFMys3JgzxBh6ipNnCSI+O+haeauC5anYpEVCZesdBqSsOnv0seL7jvgPKK6ThKQ==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
datatables.net "^1.11.4"
"@abp/font-awesome@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.1.tgz#58751a48e7a648edb075d5a424c4ed9c6448e8e5"
integrity sha512-jIYHdXtijkd0b823Gd8pDqXmJ8luA0n4NqnF6MuZtQaz95CY8o0SNc7iGSJep3Gfi9XVVUVkXqWE2Gc82uyaNA==
"@abp/font-awesome@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.2.tgz#24047769ba81762720e6ff0a9dc59074e7decc97"
integrity sha512-YIaNNs9PIUNKa72tI5AOlvFXZ5KB7ZkPSxtYzEQgjeAiLFSn9F6j2lxTSwEZeoa53fQ8qChnUcdLv+5b/FrpoQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
"@fortawesome/fontawesome-free" "^5.15.4"
"@abp/jquery-form@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.1.tgz#b09398cfb0abef4255a5bb1853c67ef9bfa76f49"
integrity sha512-Jqgog1AJHsCP3lLhUkCXMUzzk2XhAW9pje5dwSdKqE0/bg2OOGo1L3LKUFeEk9dWuMVRkrLRmfdcGRt1SRb4rQ==
"@abp/jquery-form@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.2.tgz#f9f8d75072f8090b03c89471afb9565cb2fc55b9"
integrity sha512-OHj3w4eUwivDymETk7RHxAE25pOOB/IiHB1/w/3axDgAdWaWERWnXnCZFfi+QV+8dmrXySzUecicOxXoL12NEA==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.1.tgz#a62f85c7226d71588d1aa732739b3434c43f40e9"
integrity sha512-pEleVw7js8SpIRX73U5ccrfvc0H7Lxfa761wH9WglQOgC0Z1dAkJWbqr/6zKuUi3sVECYgFK8RcVm8/oPRGMzw==
"@abp/jquery-validation-unobtrusive@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.2.tgz#0dbb9fa0970d65cd56447fdc17828fd3f4147534"
integrity sha512-3CUdINe6BXzPuDP08lWDdYON+mBVHHP37Xyt8AKqD3Qk0TMoBy2QYz4pdxS2ifn97p1f51J/jP701vNJtNVtMQ==
dependencies:
"@abp/jquery-validation" "~7.2.1"
"@abp/jquery-validation" "~7.2.2"
jquery-validation-unobtrusive "^3.2.12"
"@abp/jquery-validation@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.1.tgz#e8506f0513d26ae3550cb9410ce500e20065d9cb"
integrity sha512-QuCQV2UhKUXwOgYfwKMdu959lWSTOPR83wDTbuTAYd9nsOpCHmhDMApVT0hv44Jv+/ZmE360mkpogzkb0abxLg==
"@abp/jquery-validation@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.2.tgz#9683b25e83ac3dec1a7533c25455c42e73d81630"
integrity sha512-78NL177q1G1AOzUOhqmeAKc/3X/TgK1p+0SqWob9G83ADs7ZK5DV/uR73fs35KNYcnQI9aPwl2XzJ4hPHUZ+Qw==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
jquery-validation "^1.19.3"
"@abp/jquery@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.1.tgz#4ac9cd9ba4710f8dccaa145c17cef00e147efe6f"
integrity sha512-W2qE9LP6BCp1bdOMiup4MuB/R7Plj9se+1Sct1EeF1AnpNXv4IvVr5aGEy0/gKeeHvOrHB4wKIXcBhURFSAY1w==
"@abp/jquery@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.2.tgz#b4034ab5e193ad111ed8a2c36df97b97ecc13aaf"
integrity sha512-Uz75FDBU8R0cu5ATeudy6Ho7Fv1pg2brcQlJ+kYUxXoRmeX2j5H8+vhQGkNpMmtg7xyb4BS7tZyEtuDS9mlvpQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
jquery "~3.6.0"
"@abp/lodash@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.1.tgz#36d60374a9fc2130c1f7bd264902d78221fa3b5b"
integrity sha512-XFZrxijDLhKqtL4LL3x9C/TvnJs/MIjmNwJ7+Ieg26fo2IFqYg2+hIieCUqGzn66IBwUAoRR0Cqa66erxijDlA==
"@abp/lodash@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.2.tgz#c391d06726800807df4f25e51a28f3e6cb03de5d"
integrity sha512-Mbe/wdqfBoHbf19dEUy2IMLek7P6a2PWQsVygoyb5phb+hGm0Qy5h4g0IhFiRRWChXnjRQeDnZINdXHl8RMzuQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
lodash "^4.17.21"
"@abp/luxon@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.1.tgz#eb31dd7242be766f995954924e0127f2b58e4516"
integrity sha512-lSzulfTa4RPOcp80wmDUQFN9BatTASgYnYfu9RK9U/Fi2nV5KvqzUvRkB/XTitupLaoTJfV5h8Cpf47QMgiLSw==
"@abp/luxon@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.2.tgz#0d99a16bf34288deeae835753e6bab92efd6f060"
integrity sha512-rnz4ljwArJCwf7riFDJrIjZW0bJUXlodeM7IGWCD0Mj7r5t0n+FX9ngcJfKf+zC7ICYMaPCsz+QeUX6ycTZdOw==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
luxon "^2.3.0"
"@abp/malihu-custom-scrollbar-plugin@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.1.tgz#d3b8aa15774a34f0abe704e416b00d8be76d3346"
integrity sha512-xqsjMQJez25mFwNRTUdHTQl78tYJ9+NEmEYLjpo+qRbs2hBExZQO67gTuO6TKvPRBCVgMiIcdpuegtoFhZLl5g==
"@abp/malihu-custom-scrollbar-plugin@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.2.tgz#a843d02519ff193633c41845312c9f7741606eb7"
integrity sha512-kw9364TJuc/z7uCKZsmHDyv7gsdR8jxp+jTvkubemLuFH6fHgbL5Q77jWp5AcjI03lskaWK0Rnjsa9Ahqt/chA==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.1.tgz#07bcaeb408b0025f2e8c2a7b259f5f27e05f8d25"
integrity sha512-L7EvEKEyl9RsPnSVbPwL3QC3xcKqkaLtZo75wTws2o5hXHs4f4mkADdnpfjCYFFZ+H0vMYjxzKYNI8rHm/ZU0g==
"@abp/moment@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.2.tgz#353495c3ad2d393b3a50fbe24a731a569f6f001d"
integrity sha512-bdlfPH2uKxv1JdxGi4xAKOsN+LFQk7yV28WuAm05c16GH4YnOVHTUXZXEMNSt1cRz0GQesWwqpDrtZrKyLkptw==
dependencies:
moment "^2.9.0"
"@abp/prismjs@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-7.2.1.tgz#322ea0c1368df89a8649af2ecf9660ae9c3eb12a"
integrity sha512-918o/Gev6f5tm6U0cO6S7Teygzre1x+HpzGH5WJdNx14/ZQ6wNrcsIMIjd84R6noUPVt83/eZ27N+RQtvntQLg==
"@abp/prismjs@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-7.2.2.tgz#3b8d2fa48728f55c37917e901da9d453afce1a3e"
integrity sha512-qOjcdoZ2h5o/dJ3QCSxtT3XIB4nd1qjwKSgly1fEYlXBaf/iU1JdsAX+yvAw77UfCZ6NxpAmd/tREJP9FSrQeA==
dependencies:
"@abp/clipboard" "~7.2.1"
"@abp/core" "~7.2.1"
"@abp/clipboard" "~7.2.2"
"@abp/core" "~7.2.2"
prismjs "^1.26.0"
"@abp/select2@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.1.tgz#c2d9494d09395691792ede04bf3d7173ebd35a95"
integrity sha512-AW1ylrPQv+WeT3HdQQqy09uvxSeWPzxLhVEylL+HIGFn3TwMCVo2DtgnxSYde4WCpDMRlYzkWlUBX5y9UzhArw==
"@abp/select2@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.2.tgz#f5e2fbc377c7a482b59e9f177c3a9f1f73d7f94f"
integrity sha512-mZqcNZ7Te7JzePUFKowjZWO90TH/9rlvkm4tx5q8PMYkV9Pk/aGbw5Gi7nGJHLEcy1g1fI0N5aL/UQzckeC99w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
select2 "^4.0.13"
"@abp/sweetalert2@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.1.tgz#ab11b3ef48ca55687a8afb0f8fca0b9e696d10a3"
integrity sha512-qGMQE7I3bnCN0xwliBP+y+1m5nx7mOYc2yuTozNLdNpmNgT0TAkjyvufn99JQBPoFju+VjMEjS5R005RbvLuVQ==
"@abp/sweetalert2@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.2.tgz#9cd0fc631dcf9989a2189217b7b5f3437cb4f376"
integrity sha512-KMBaMyk9iUqzceGfxR1dGx+wZylOz4f7mN9Owj7Jn9MjMGZoFUoyJ96PFD4rLy2m/8g3Jn70dbmnynpF1P8x+w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
sweetalert2 "^11.3.6"
"@abp/timeago@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.1.tgz#0fad3c1d7b0678ca63a47f9ba6f5702a162f6857"
integrity sha512-1M6WWQ/kPdndMPhgJ5/I22NjxLgmHM4b4sLaKATIH5D4EM7aii22RiM5cSBVAKoJZjJ8S3R28g78zS01xKrSnw==
"@abp/timeago@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.2.tgz#a0fac76f78d679892c0a5653d3a68044529245fa"
integrity sha512-3qLRrDQ1qC+E8YbsPiFxGf7ZzIlbKS3ObE2ixULKoarjJE8yDnHV2vfkSX1kYGsiN50yasUUG88U+JHLbhyx8w==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
timeago "^1.6.7"
"@abp/toastr@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.1.tgz#6ddc793e0a66e2b1f9dd192530ad46aacfd60cb2"
integrity sha512-BkLohyVJxLx0aJ6WJ2iBRV8y20JWfgoRCpzGUCcAhAp+BBF9FVhVxxZo0loFjprFprvLjJK91Z0bErJW6BWvFQ==
"@abp/toastr@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.2.tgz#30e8039ceeff66bdd7c438c3c6cd583deeb71965"
integrity sha512-Jmmkcv2B3fdGbDJaBXeqRtctQXx8cTEb+PgyqtVRG/M0Wy7hhbMYn0U+t3KflGpZzH+AN5ReAdNbjXpM3wgFmA==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
toastr "^2.1.4"
"@abp/utils@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.1.tgz#a0d5a6de02cb1b68d096399bb03771a8bb9b03b5"
integrity sha512-1QAdnFH9RD03w5mqNCz2G4mCuEPRgAJNLvFAEu9RTkL6EhOsCCQSG5mzA4cTWNDvVlNcUF8uyroXmlUvuzpYHg==
"@abp/utils@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.2.tgz#6054baa822d52f08452e8405c7a391aaedee7de0"
integrity sha512-VB9ijoPvB2tHInc1XrcvTvEzYANh+V1BliyScNTG9tr09q2pvn5jHp8Jixtu7GewCy8dh7cyueqhbnuozxedjg==
dependencies:
just-compare "^1.3.0"

1489
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20230504070814_Added_BlogUser_Optionals.Designer.cs

File diff suppressed because it is too large

226
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20230504070814_Added_BlogUser_Optionals.cs

@ -0,0 +1,226 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
{
/// <inheritdoc />
public partial class AddedBlogUserOptionals : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Biography",
table: "BlgUsers",
type: "nvarchar(1000)",
maxLength: 1000,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Company",
table: "BlgUsers",
type: "nvarchar(128)",
maxLength: 128,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Github",
table: "BlgUsers",
type: "nvarchar(64)",
maxLength: 64,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "JobTitle",
table: "BlgUsers",
type: "nvarchar(32)",
maxLength: 32,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Linkedin",
table: "BlgUsers",
type: "nvarchar(64)",
maxLength: 64,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Twitter",
table: "BlgUsers",
type: "nvarchar(64)",
maxLength: 64,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "WebSite",
table: "BlgUsers",
type: "nvarchar(256)",
maxLength: 256,
nullable: true);
migrationBuilder.AddColumn<int>(
name: "EntityVersion",
table: "AbpUsers",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<DateTimeOffset>(
name: "LastPasswordChangeTime",
table: "AbpUsers",
type: "datetimeoffset",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "ShouldChangePasswordOnNextLogin",
table: "AbpUsers",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<int>(
name: "EntityVersion",
table: "AbpRoles",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "EntityVersion",
table: "AbpOrganizationUnits",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateTable(
name: "AbpPermissionGroups",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpPermissionGroups", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpPermissions",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
GroupName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
ParentName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
IsEnabled = table.Column<bool>(type: "bit", nullable: false),
MultiTenancySide = table.Column<byte>(type: "tinyint", nullable: false),
Providers = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
StateCheckers = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpPermissions", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpUserDelegations",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
SourceUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TargetUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
StartTime = table.Column<DateTime>(type: "datetime2", nullable: false),
EndTime = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpUserDelegations", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_AbpPermissionGroups_Name",
table: "AbpPermissionGroups",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AbpPermissions_GroupName",
table: "AbpPermissions",
column: "GroupName");
migrationBuilder.CreateIndex(
name: "IX_AbpPermissions_Name",
table: "AbpPermissions",
column: "Name",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpPermissionGroups");
migrationBuilder.DropTable(
name: "AbpPermissions");
migrationBuilder.DropTable(
name: "AbpUserDelegations");
migrationBuilder.DropColumn(
name: "Biography",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "Company",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "Github",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "JobTitle",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "Linkedin",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "Twitter",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "WebSite",
table: "BlgUsers");
migrationBuilder.DropColumn(
name: "EntityVersion",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "LastPasswordChangeTime",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "ShouldChangePasswordOnNextLogin",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "EntityVersion",
table: "AbpRoles");
migrationBuilder.DropColumn(
name: "EntityVersion",
table: "AbpOrganizationUnits");
}
}
}

162
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/BloggingTestAppDbContextModelSnapshot.cs

@ -19,10 +19,10 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("ProductVersion", "7.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b =>
{
@ -183,6 +183,9 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
@ -369,6 +372,9 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasDefaultValue(false)
.HasColumnName("EmailConfirmed");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
@ -397,6 +403,9 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<DateTimeOffset?>("LastPasswordChangeTime")
.HasColumnType("datetimeoffset");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
@ -445,6 +454,9 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasColumnType("nvarchar(256)")
.HasColumnName("SecurityStamp");
b.Property<bool>("ShouldChangePasswordOnNextLogin")
.HasColumnType("bit");
b.Property<string>("Surname")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
@ -507,6 +519,33 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
b.ToTable("AbpUserClaims", (string)null);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("EndTime")
.HasColumnType("datetime2");
b.Property<Guid>("SourceUserId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.Property<Guid>("TargetUserId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.ToTable("AbpUserDelegations", (string)null);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.Property<Guid>("UserId")
@ -647,6 +686,9 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasColumnType("nvarchar(128)")
.HasColumnName("DisplayName");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
@ -708,6 +750,59 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
b.ToTable("AbpOrganizationUnitRoles", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("GroupName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<bool>("IsEnabled")
.HasColumnType("bit");
b.Property<byte>("MultiTenancySide")
.HasColumnType("tinyint");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ParentName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Providers")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("StateCheckers")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("GroupName");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpPermissions", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
@ -742,6 +837,34 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
b.ToTable("AbpPermissionGrants", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpPermissionGroups", (string)null);
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
@ -1099,6 +1222,16 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Biography")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)")
.HasColumnName("Biography");
b.Property<string>("Company")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("Company");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
@ -1121,10 +1254,25 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("Github")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("Github");
b.Property<bool>("IsActive")
.HasColumnType("bit")
.HasColumnName("IsActive");
b.Property<string>("JobTitle")
.HasMaxLength(32)
.HasColumnType("nvarchar(32)")
.HasColumnName("JobTitle");
b.Property<string>("Linkedin")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("Linkedin");
b.Property<string>("Name")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
@ -1150,12 +1298,22 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Twitter")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("Twitter");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("UserName");
b.Property<string>("WebSite")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("WebSite");
b.HasKey("Id");
b.ToTable("BlgUsers", (string)null);

4
modules/blogging/app/Volo.BloggingTestApp/package.json

@ -3,7 +3,7 @@
"name": "volo.blogtestapp",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~7.2.1",
"@abp/blogging": "~7.2.1"
"@abp/aspnetcore.mvc.ui.theme.basic": "~7.2.2",
"@abp/blogging": "~7.2.2"
}
}

318
modules/blogging/app/Volo.BloggingTestApp/yarn.lock

@ -2,39 +2,39 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-7.2.1.tgz#34a948ef593442995bf663fd5c0d3ab4fd7390e8"
integrity sha512-AxtugI8e8n6BDklLV/z9oZQzmpF3oEhIVyr1dxv55hIBe8GcOZHA/9CqKHY/OpSwch7ka0EEPrHawCvylcNAdQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.1"
"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.1.tgz#68903cb3fafca670d603e658f20e435734e3d738"
integrity sha512-B7gGe8qAjvMsLfqxFVdvGFfMylV3NQzthXT/BMoq1MtgMdLKrrpeu6Oz3mIr68IuFlA38edqlm8Scy+iknD+Xg==
dependencies:
"@abp/aspnetcore.mvc.ui" "~7.2.1"
"@abp/bootstrap" "~7.2.1"
"@abp/bootstrap-datepicker" "~7.2.1"
"@abp/bootstrap-daterangepicker" "~7.2.1"
"@abp/datatables.net-bs5" "~7.2.1"
"@abp/font-awesome" "~7.2.1"
"@abp/jquery-form" "~7.2.1"
"@abp/jquery-validation-unobtrusive" "~7.2.1"
"@abp/lodash" "~7.2.1"
"@abp/luxon" "~7.2.1"
"@abp/malihu-custom-scrollbar-plugin" "~7.2.1"
"@abp/moment" "~7.2.1"
"@abp/select2" "~7.2.1"
"@abp/sweetalert2" "~7.2.1"
"@abp/timeago" "~7.2.1"
"@abp/toastr" "~7.2.1"
"@abp/aspnetcore.mvc.ui@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.1.tgz#b4ae5dcdb90983673092dbfee93c16f21cbb21fe"
integrity sha512-edBAWEKQnUdH8jgY+QDECs3BFu0qIXbMV/AiTH9j64uo4ADQ6rgJ6Uq7xy6YtxJ0uImFkgLXDd9LYQEPvU43Bg==
"@abp/aspnetcore.mvc.ui.theme.basic@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-7.2.2.tgz#6cc7f3390429413ac916f0bb450025371a64e48a"
integrity sha512-6CjJ/7DGPI9q192YYuJomq9ul0lUeOvZWZM1BJ7PSV/K8rAJotIGUoLtFttv+786zxyy/sCfaJGcObg6Kij8Bg==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.2"
"@abp/aspnetcore.mvc.ui.theme.shared@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-7.2.2.tgz#ef5feee85db6f0168bc9b2c1fb058992be6c6d55"
integrity sha512-XayukLpXEQj3VEw0YDqfCOR7QfU1nEe6aGtc9CfG9cGXMIDZFs6lxI0fbRdRR89m7T5POtDlrhr81yTkzSd1SA==
dependencies:
"@abp/aspnetcore.mvc.ui" "~7.2.2"
"@abp/bootstrap" "~7.2.2"
"@abp/bootstrap-datepicker" "~7.2.2"
"@abp/bootstrap-daterangepicker" "~7.2.2"
"@abp/datatables.net-bs5" "~7.2.2"
"@abp/font-awesome" "~7.2.2"
"@abp/jquery-form" "~7.2.2"
"@abp/jquery-validation-unobtrusive" "~7.2.2"
"@abp/lodash" "~7.2.2"
"@abp/luxon" "~7.2.2"
"@abp/malihu-custom-scrollbar-plugin" "~7.2.2"
"@abp/moment" "~7.2.2"
"@abp/select2" "~7.2.2"
"@abp/sweetalert2" "~7.2.2"
"@abp/timeago" "~7.2.2"
"@abp/toastr" "~7.2.2"
"@abp/aspnetcore.mvc.ui@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-7.2.2.tgz#cc0ca317bf71fcc3c25dcc4bfd6e4521219a2b05"
integrity sha512-frRTtiGeXDuZbMxBAAPFlWMDoSHkTP0iPE2dAV7YC28W/lHrf6bJsS2CoB2dHmUjp5IB2LSQnaQuR7ihXRtx0A==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@ -43,201 +43,201 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
"@abp/blogging@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-7.2.1.tgz#225d9a3314244c864a03e987e53e7797e04a0f27"
integrity sha512-sbtKkPau5VmLBA0iW9R6ICF2bxAD6nBm60qC9EGFdNa8KxGdWCwcxiWlxMAf3YQawYxE7UHXJpaIVJy3Si+qzA==
"@abp/blogging@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-7.2.2.tgz#d862220b56de1a6527e6b28f67001278d2ef90ec"
integrity sha512-50/iEC6B6Hy0W9lnC9bYW2RjUzB2VCMA/x/kVT9nOmdDaOdqwg/qc3NleNdHBkVoeH5BzhjXW6oAXc3+8TXEzA==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.1"
"@abp/owl.carousel" "~7.2.1"
"@abp/prismjs" "~7.2.1"
"@abp/tui-editor" "~7.2.1"
"@abp/aspnetcore.mvc.ui.theme.shared" "~7.2.2"
"@abp/owl.carousel" "~7.2.2"
"@abp/prismjs" "~7.2.2"
"@abp/tui-editor" "~7.2.2"
"@abp/bootstrap-datepicker@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.1.tgz#eca6c1138074ce222ff6c474bc51f4fbe05882c3"
integrity sha512-DUBEz8wzsWJlEfQ7CZJYemLE/wNYyY7LtWRBRjNFndS8P2xo3FP4xuh0mnovSZ3AXPy7oAAKg0zayFzf3XS4aw==
"@abp/bootstrap-datepicker@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-7.2.2.tgz#2b88db99296d0905f04731b5e2d95955e6a79717"
integrity sha512-JEDv3DJprgOf8T///Wzxg/CTKapvfcvfPOeTULhs0M039Sk3xLRBv/HG9YgxexjLh8zVWKfd5T5oiWj07KMC8A==
dependencies:
bootstrap-datepicker "^1.9.0"
"@abp/bootstrap-daterangepicker@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.1.tgz#ad236d026c3596e71a6a2088e5332e00d62c8ff7"
integrity sha512-WF/3qQobtvizWGmycgkzHMIjHJoLYAnCsi+vJPzv+VqvGstnQOgkz/rlfcu7uAp9y5H4OWdSAbkOj9eELNfxlA==
"@abp/bootstrap-daterangepicker@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-7.2.2.tgz#ef4a8837ebf35ac715af06cdfa7584751447cd80"
integrity sha512-o/uFPBhNFDzGpyE9xIU4U5hqZMmeXqRSWwLdMFEt4AmOCTPXndC9eIZRpZs9fYmsNsQIA6S0kXuUxMTSOmR/Jw==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.1.tgz#94d8186af2f1a1ed4d558756ffa18fd43f26e318"
integrity sha512-nU3mBK0VVgkDJqu5CBOHAD1FNvKSO6wnfX5wSB+IYDIfAV9wsmiTIMx6YO8psjMOd4flEmlKLALK6p17i79jhw==
"@abp/bootstrap@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-7.2.2.tgz#9fc80c6110d519d4bd53aba4f70e6c9afa227793"
integrity sha512-Eg7i+4VL62ex1C/7IaU1m8hEY4zy+QqdqeQtvb+ogKjLSM/SCE8ck+WC2749UOaso9yf7s9Eb4QMkVQ/MSMwrw==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
bootstrap "^5.1.3"
"@abp/clipboard@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-7.2.1.tgz#dab262b84aa956eeb3a145461b662c5ae851b4a8"
integrity sha512-72C3QMEMMtXzjv6GTJJiILSJ1ScBidcKdahrRLlomo4TgCIEgg1+oYL3Q0uyrlB5I0mUqBaf+qYlxXue8JdRAQ==
"@abp/clipboard@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-7.2.2.tgz#e8130fc671b1c3dc85517a8f8bae1bb4c6fac64f"
integrity sha512-QiFMsawpo3e6ZV3OKe0F21vXHRv2X1WZoivQ4yYordM7QtLZG0bdftIGA1jPcKbWoSOc8wfFZszzXuceeI8U5w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
clipboard "^2.0.8"
"@abp/core@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.1.tgz#5685d615482daa032ab24f49aeb7fff3f50af898"
integrity sha512-N99Ee/rbtXFaV3vdGfv6Mbj1Zav73oBGGNbzmAiQaO/g1hda6ndzSC9WzRJkJ7MaJKTPNJx1ExBNEcNMw1P2UA==
"@abp/core@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-7.2.2.tgz#b5d403289181094ecd92cb8d963292ba8d7afe67"
integrity sha512-4laOq4dsya/oUCbmz6JvZdiEXADFVgXdfncS//EZWJJvDVzasfO0Sf71qkj233aYQ6PmClSZarZJSottzdr8vw==
dependencies:
"@abp/utils" "~7.2.1"
"@abp/utils" "~7.2.2"
"@abp/datatables.net-bs5@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.1.tgz#0474e874729a51a7e87f2ebfa931ecd8e6fe3eed"
integrity sha512-7AvNK0mYHWcdbQJAH6/PV9yjz/FbJlVHWP7mOREd6DIkg+Q8Ihmqjn8bnJyhN2UeRMTz9EZU2nO+E9oAllYlog==
"@abp/datatables.net-bs5@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-7.2.2.tgz#7a8aa9173a219d28949cde69037b9d601e4c75fd"
integrity sha512-vrqcuvMksITTtRF35xk0+cPOnr+oO7nPGFN5zHVXHYf2pZP2/GqPcBo4s9arwaJ3bQ49slQV+fdugSULUFIeFQ==
dependencies:
"@abp/datatables.net" "~7.2.1"
"@abp/datatables.net" "~7.2.2"
datatables.net-bs5 "^1.11.4"
"@abp/datatables.net@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.1.tgz#30aeec4c37cc76e5c4dff78dee433c0b42599e41"
integrity sha512-AM6LonrGTOA2VyRme5rT/DcVX0TF2WxSRiM7vpTajq4A16O8yceos/XXop4QEGjGCPGbRqUuWQsIAxXRpcwYJQ==
"@abp/datatables.net@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-7.2.2.tgz#3c4c7cad18bd87085d6042f63a9de88908e8dfe0"
integrity sha512-8Fyqd+iUFwy5MH8RVnfwNhcFMys3JgzxBh6ipNnCSI+O+haeauC5anYpEVCZesdBqSsOnv0seL7jvgPKK6ThKQ==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
datatables.net "^1.11.4"
"@abp/font-awesome@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.1.tgz#58751a48e7a648edb075d5a424c4ed9c6448e8e5"
integrity sha512-jIYHdXtijkd0b823Gd8pDqXmJ8luA0n4NqnF6MuZtQaz95CY8o0SNc7iGSJep3Gfi9XVVUVkXqWE2Gc82uyaNA==
"@abp/font-awesome@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-7.2.2.tgz#24047769ba81762720e6ff0a9dc59074e7decc97"
integrity sha512-YIaNNs9PIUNKa72tI5AOlvFXZ5KB7ZkPSxtYzEQgjeAiLFSn9F6j2lxTSwEZeoa53fQ8qChnUcdLv+5b/FrpoQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
"@fortawesome/fontawesome-free" "^5.15.4"
"@abp/jquery-form@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.1.tgz#b09398cfb0abef4255a5bb1853c67ef9bfa76f49"
integrity sha512-Jqgog1AJHsCP3lLhUkCXMUzzk2XhAW9pje5dwSdKqE0/bg2OOGo1L3LKUFeEk9dWuMVRkrLRmfdcGRt1SRb4rQ==
"@abp/jquery-form@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-7.2.2.tgz#f9f8d75072f8090b03c89471afb9565cb2fc55b9"
integrity sha512-OHj3w4eUwivDymETk7RHxAE25pOOB/IiHB1/w/3axDgAdWaWERWnXnCZFfi+QV+8dmrXySzUecicOxXoL12NEA==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.1.tgz#a62f85c7226d71588d1aa732739b3434c43f40e9"
integrity sha512-pEleVw7js8SpIRX73U5ccrfvc0H7Lxfa761wH9WglQOgC0Z1dAkJWbqr/6zKuUi3sVECYgFK8RcVm8/oPRGMzw==
"@abp/jquery-validation-unobtrusive@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-7.2.2.tgz#0dbb9fa0970d65cd56447fdc17828fd3f4147534"
integrity sha512-3CUdINe6BXzPuDP08lWDdYON+mBVHHP37Xyt8AKqD3Qk0TMoBy2QYz4pdxS2ifn97p1f51J/jP701vNJtNVtMQ==
dependencies:
"@abp/jquery-validation" "~7.2.1"
"@abp/jquery-validation" "~7.2.2"
jquery-validation-unobtrusive "^3.2.12"
"@abp/jquery-validation@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.1.tgz#e8506f0513d26ae3550cb9410ce500e20065d9cb"
integrity sha512-QuCQV2UhKUXwOgYfwKMdu959lWSTOPR83wDTbuTAYd9nsOpCHmhDMApVT0hv44Jv+/ZmE360mkpogzkb0abxLg==
"@abp/jquery-validation@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-7.2.2.tgz#9683b25e83ac3dec1a7533c25455c42e73d81630"
integrity sha512-78NL177q1G1AOzUOhqmeAKc/3X/TgK1p+0SqWob9G83ADs7ZK5DV/uR73fs35KNYcnQI9aPwl2XzJ4hPHUZ+Qw==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
jquery-validation "^1.19.3"
"@abp/jquery@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.1.tgz#4ac9cd9ba4710f8dccaa145c17cef00e147efe6f"
integrity sha512-W2qE9LP6BCp1bdOMiup4MuB/R7Plj9se+1Sct1EeF1AnpNXv4IvVr5aGEy0/gKeeHvOrHB4wKIXcBhURFSAY1w==
"@abp/jquery@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-7.2.2.tgz#b4034ab5e193ad111ed8a2c36df97b97ecc13aaf"
integrity sha512-Uz75FDBU8R0cu5ATeudy6Ho7Fv1pg2brcQlJ+kYUxXoRmeX2j5H8+vhQGkNpMmtg7xyb4BS7tZyEtuDS9mlvpQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
jquery "~3.6.0"
"@abp/lodash@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.1.tgz#36d60374a9fc2130c1f7bd264902d78221fa3b5b"
integrity sha512-XFZrxijDLhKqtL4LL3x9C/TvnJs/MIjmNwJ7+Ieg26fo2IFqYg2+hIieCUqGzn66IBwUAoRR0Cqa66erxijDlA==
"@abp/lodash@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-7.2.2.tgz#c391d06726800807df4f25e51a28f3e6cb03de5d"
integrity sha512-Mbe/wdqfBoHbf19dEUy2IMLek7P6a2PWQsVygoyb5phb+hGm0Qy5h4g0IhFiRRWChXnjRQeDnZINdXHl8RMzuQ==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
lodash "^4.17.21"
"@abp/luxon@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.1.tgz#eb31dd7242be766f995954924e0127f2b58e4516"
integrity sha512-lSzulfTa4RPOcp80wmDUQFN9BatTASgYnYfu9RK9U/Fi2nV5KvqzUvRkB/XTitupLaoTJfV5h8Cpf47QMgiLSw==
"@abp/luxon@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-7.2.2.tgz#0d99a16bf34288deeae835753e6bab92efd6f060"
integrity sha512-rnz4ljwArJCwf7riFDJrIjZW0bJUXlodeM7IGWCD0Mj7r5t0n+FX9ngcJfKf+zC7ICYMaPCsz+QeUX6ycTZdOw==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
luxon "^2.3.0"
"@abp/malihu-custom-scrollbar-plugin@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.1.tgz#d3b8aa15774a34f0abe704e416b00d8be76d3346"
integrity sha512-xqsjMQJez25mFwNRTUdHTQl78tYJ9+NEmEYLjpo+qRbs2hBExZQO67gTuO6TKvPRBCVgMiIcdpuegtoFhZLl5g==
"@abp/malihu-custom-scrollbar-plugin@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-7.2.2.tgz#a843d02519ff193633c41845312c9f7741606eb7"
integrity sha512-kw9364TJuc/z7uCKZsmHDyv7gsdR8jxp+jTvkubemLuFH6fHgbL5Q77jWp5AcjI03lskaWK0Rnjsa9Ahqt/chA==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.1.tgz#07bcaeb408b0025f2e8c2a7b259f5f27e05f8d25"
integrity sha512-L7EvEKEyl9RsPnSVbPwL3QC3xcKqkaLtZo75wTws2o5hXHs4f4mkADdnpfjCYFFZ+H0vMYjxzKYNI8rHm/ZU0g==
"@abp/moment@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-7.2.2.tgz#353495c3ad2d393b3a50fbe24a731a569f6f001d"
integrity sha512-bdlfPH2uKxv1JdxGi4xAKOsN+LFQk7yV28WuAm05c16GH4YnOVHTUXZXEMNSt1cRz0GQesWwqpDrtZrKyLkptw==
dependencies:
moment "^2.9.0"
"@abp/owl.carousel@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-7.2.1.tgz#50ff8709fc25a6774695d6a7c0b77f300aeb4dc9"
integrity sha512-fxl4ig/oJxiNX+UqFM40yjEoe8P7kvubMqmhO1GVnZWoZrNDsNVnFVhMpps47c58WPQ1iRSYJivdmxXTUG5EUw==
"@abp/owl.carousel@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-7.2.2.tgz#6ec2eb05d8c72d7debe98de0e7f8b9a3beb91d0c"
integrity sha512-uPVeB03ugsFHMg4Lnlf0szryUHu90MNItDTLdoaMFyIl68K2qmPdQI+CF5vL7Jr9r1M6Y0zGQ8eOvDu13hpQAA==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
owl.carousel "^2.3.4"
"@abp/prismjs@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-7.2.1.tgz#322ea0c1368df89a8649af2ecf9660ae9c3eb12a"
integrity sha512-918o/Gev6f5tm6U0cO6S7Teygzre1x+HpzGH5WJdNx14/ZQ6wNrcsIMIjd84R6noUPVt83/eZ27N+RQtvntQLg==
"@abp/prismjs@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-7.2.2.tgz#3b8d2fa48728f55c37917e901da9d453afce1a3e"
integrity sha512-qOjcdoZ2h5o/dJ3QCSxtT3XIB4nd1qjwKSgly1fEYlXBaf/iU1JdsAX+yvAw77UfCZ6NxpAmd/tREJP9FSrQeA==
dependencies:
"@abp/clipboard" "~7.2.1"
"@abp/core" "~7.2.1"
"@abp/clipboard" "~7.2.2"
"@abp/core" "~7.2.2"
prismjs "^1.26.0"
"@abp/select2@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.1.tgz#c2d9494d09395691792ede04bf3d7173ebd35a95"
integrity sha512-AW1ylrPQv+WeT3HdQQqy09uvxSeWPzxLhVEylL+HIGFn3TwMCVo2DtgnxSYde4WCpDMRlYzkWlUBX5y9UzhArw==
"@abp/select2@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-7.2.2.tgz#f5e2fbc377c7a482b59e9f177c3a9f1f73d7f94f"
integrity sha512-mZqcNZ7Te7JzePUFKowjZWO90TH/9rlvkm4tx5q8PMYkV9Pk/aGbw5Gi7nGJHLEcy1g1fI0N5aL/UQzckeC99w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
select2 "^4.0.13"
"@abp/sweetalert2@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.1.tgz#ab11b3ef48ca55687a8afb0f8fca0b9e696d10a3"
integrity sha512-qGMQE7I3bnCN0xwliBP+y+1m5nx7mOYc2yuTozNLdNpmNgT0TAkjyvufn99JQBPoFju+VjMEjS5R005RbvLuVQ==
"@abp/sweetalert2@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-7.2.2.tgz#9cd0fc631dcf9989a2189217b7b5f3437cb4f376"
integrity sha512-KMBaMyk9iUqzceGfxR1dGx+wZylOz4f7mN9Owj7Jn9MjMGZoFUoyJ96PFD4rLy2m/8g3Jn70dbmnynpF1P8x+w==
dependencies:
"@abp/core" "~7.2.1"
"@abp/core" "~7.2.2"
sweetalert2 "^11.3.6"
"@abp/timeago@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.1.tgz#0fad3c1d7b0678ca63a47f9ba6f5702a162f6857"
integrity sha512-1M6WWQ/kPdndMPhgJ5/I22NjxLgmHM4b4sLaKATIH5D4EM7aii22RiM5cSBVAKoJZjJ8S3R28g78zS01xKrSnw==
"@abp/timeago@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-7.2.2.tgz#a0fac76f78d679892c0a5653d3a68044529245fa"
integrity sha512-3qLRrDQ1qC+E8YbsPiFxGf7ZzIlbKS3ObE2ixULKoarjJE8yDnHV2vfkSX1kYGsiN50yasUUG88U+JHLbhyx8w==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
timeago "^1.6.7"
"@abp/toastr@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.1.tgz#6ddc793e0a66e2b1f9dd192530ad46aacfd60cb2"
integrity sha512-BkLohyVJxLx0aJ6WJ2iBRV8y20JWfgoRCpzGUCcAhAp+BBF9FVhVxxZo0loFjprFprvLjJK91Z0bErJW6BWvFQ==
"@abp/toastr@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-7.2.2.tgz#30e8039ceeff66bdd7c438c3c6cd583deeb71965"
integrity sha512-Jmmkcv2B3fdGbDJaBXeqRtctQXx8cTEb+PgyqtVRG/M0Wy7hhbMYn0U+t3KflGpZzH+AN5ReAdNbjXpM3wgFmA==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/jquery" "~7.2.2"
toastr "^2.1.4"
"@abp/tui-editor@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-7.2.1.tgz#c123431ef3ee9c665bfcf412ada4ef73dc1ec53d"
integrity sha512-f/LzTdSE0eilE29Npm22SxN4v8beL4O58ZqKE5OHLdL8i3pJfZO5DHe9dzTxalymc9j5i0DCZSzpLKsACp5JnQ==
"@abp/tui-editor@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-7.2.2.tgz#1b7ad823bd56b854b727d2846142066f61a6edf8"
integrity sha512-4uuupAWEAXoLHpnk9wrmjAYiba3wYiBSLapewK3WTMZt6tLtugQ0rWS+7DNerMplR+ZwEObAN2UvNCUI6I+lBw==
dependencies:
"@abp/jquery" "~7.2.1"
"@abp/prismjs" "~7.2.1"
"@abp/jquery" "~7.2.2"
"@abp/prismjs" "~7.2.2"
"@abp/utils@~7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.1.tgz#a0d5a6de02cb1b68d096399bb03771a8bb9b03b5"
integrity sha512-1QAdnFH9RD03w5mqNCz2G4mCuEPRgAJNLvFAEu9RTkL6EhOsCCQSG5mzA4cTWNDvVlNcUF8uyroXmlUvuzpYHg==
"@abp/utils@~7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-7.2.2.tgz#6054baa822d52f08452e8405c7a391aaedee7de0"
integrity sha512-VB9ijoPvB2tHInc1XrcvTvEzYANh+V1BliyScNTG9tr09q2pvn5jHp8Jixtu7GewCy8dh7cyueqhbnuozxedjg==
dependencies:
just-compare "^1.3.0"

38
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Members/CustomIdentityBlogUserUpdateDto.cs

@ -0,0 +1,38 @@
using System.ComponentModel.DataAnnotations;
using Volo.Blogging.Users;
namespace Volo.Blogging.Members;
public class CustomIdentityBlogUserUpdateDto
{
[StringLength(UserConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(UserConsts.MaxSurnameLength)]
public string Surname { get; set; }
[RegularExpression(@"^((?!\s).)*$", ErrorMessage= "PersonalSiteUrlValidationMessage")]
[StringLength(UserConsts.MaxWebSiteLength)]
public string WebSite { get; set; }
[RegularExpression(@"^((?!\s).)*$", ErrorMessage= "TwitterUserNameValidationMessage")]
[StringLength(UserConsts.MaxTwitterLength)]
public string Twitter { get; set; }
[RegularExpression(@"^((?!\s).)*$", ErrorMessage= "GitHubUserNameValidationMessage")]
[StringLength(UserConsts.MaxGithubLength)]
public string Github { get; set; }
[RegularExpression(@"^((?!\s).)*$", ErrorMessage= "LinkedinUrlValidationMessage")]
[StringLength(UserConsts.MaxLinkedinLength)]
public string Linkedin { get; set; }
[StringLength(UserConsts.MaxCompanyLength)]
public string Company { get; set; }
[StringLength(UserConsts.MaxJobTitleLength)]
public string JobTitle { get; set; }
[StringLength(UserConsts.MaxBiographyLength)]
public string Biography { get; set; }
}

2
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Members/IMemberAppService.cs

@ -7,4 +7,6 @@ namespace Volo.Blogging.Members;
public interface IMemberAppService : IApplicationService
{
Task<BlogUserDto> FindAsync(string username);
Task UpdateUserProfileAsync(CustomIdentityBlogUserUpdateDto input);
}

18
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/BlogUserDto.cs

@ -8,6 +8,10 @@ namespace Volo.Blogging.Posts
{
public Guid? TenantId { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
@ -17,7 +21,21 @@ namespace Volo.Blogging.Posts
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public string WebSite { get; set; }
public string Twitter { get; set; }
public string Github { get; set; }
public string Linkedin { get; set; }
public string Company { get; set; }
public string JobTitle { get; set; }
public string Biography { get; set; }
public Dictionary<string, object> ExtraProperties { get; set; }
}
}

2
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/IPostAppService.cs

@ -23,5 +23,7 @@ namespace Volo.Blogging.Posts
Task<PostWithDetailsDto> UpdateAsync(Guid id, UpdatePostDto input);
Task<List<PostWithDetailsDto>> GetListByUserIdAsync(Guid userId);
Task<List<PostWithDetailsDto>> GetLatestBlogPostsAsync(Guid blogId, int count);
}
}

17
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Members/MemberAppService.cs

@ -26,4 +26,21 @@ public class MemberAppService : BloggingAppServiceBase, IMemberAppService
return ObjectMapper.Map<BlogUser, BlogUserDto>(user);
}
public async Task UpdateUserProfileAsync(CustomIdentityBlogUserUpdateDto input)
{
var user = await _userRepository.GetAsync(CurrentUser.Id.Value);
user.Name = input.Name;
user.Surname = input.Surname;
user.WebSite = input.WebSite;
user.Twitter = input.Twitter;
user.Github = input.Github;
user.Linkedin = input.Linkedin;
user.Company = input.Company;
user.JobTitle = input.JobTitle;
user.Biography = input.Biography;
await _userRepository.UpdateAsync(user);
}
}

30
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs

@ -195,6 +195,36 @@ namespace Volo.Blogging.Posts
return ObjectMapper.Map<List<Post>, List<PostWithDetailsDto>>(posts);
}
public async Task<List<PostWithDetailsDto>> GetLatestBlogPostsAsync(Guid blogId, int count)
{
var posts = await PostRepository.GetLatestBlogPostsAsync(blogId, count);
var userDictionary = new Dictionary<Guid, BlogUserDto>();
var postDtos = new List<PostWithDetailsDto>(ObjectMapper.Map<List<Post>, List<PostWithDetailsDto>>(posts));
foreach (var postDto in postDtos)
{
if (!postDto.CreatorId.HasValue)
{
continue;
}
if (userDictionary.TryGetValue(postDto.CreatorId.Value, out var creatorUserDto))
{
postDto.Writer = creatorUserDto;
continue;
}
var creatorUser = await UserLookupService.FindByIdAsync(postDto.CreatorId.Value);
if (creatorUser != null)
{
postDto.Writer = ObjectMapper.Map<BlogUser, BlogUserDto>(creatorUser);
userDictionary[creatorUser.Id] = postDto.Writer;
}
}
return new List<PostWithDetailsDto>(postDtos);
}
[Authorize(BloggingPermissions.Posts.Create)]
public async Task<PostWithDetailsDto> CreateAsync(CreatePostDto input)
{

17
modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/en.json

@ -61,6 +61,21 @@
"FileUploadInfo": "Drag, drop, or paste a copied image.",
"PostDescriptionHint": "* Will be rendered in the article link preview, supports HTML",
"ReadMore": "Continue Reading",
"MemberNotPublishedPostYet": "No posts yet!"
"MemberNotPublishedPostYet": "No posts yet!",
"UpdateUserWebSiteInfo": "Example: https://johndoe.com",
"UpdateUserTwitterInfo": "Example: johndoe",
"UpdateUserGithubInfo": "Example: johndoe",
"UpdateUserLinkedinInfo": "Example: https://www.linkedin.com/...",
"UpdateUserCompanyInfo": "Example: Volosoft",
"UpdateUserJobTitleInfo": "Example: Software Developer",
"WebSite": "Web Site",
"UserName": "Username",
"FullURL": "Full URL",
"JobTitle": "Job Title",
"PersonalWebsite": "PERSONAL WEBSITE",
"EditProfile": "Edit Profile",
"MoreFromBlog": "More From Blog",
"MoreFromUser": "More From {0}",
"BlogPosts": "Posts"
}
}

22
modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Users/UserConsts.cs

@ -0,0 +1,22 @@
namespace Volo.Blogging.Users;
public class UserConsts
{
public const int MaxNameLength = 64;
public const int MaxSurnameLength = 64;
public const int MaxBiographyLength = 1000;
public const int MaxWebSiteLength = 256;
public const int MaxTwitterLength = 128;
public const int MaxGithubLength = 256;
public const int MaxLinkedinLength = 256;
public const int MaxCompanyLength = 256;
public const int MaxJobTitleLength = 128;
}

2
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Posts/IPostRepository.cs

@ -17,5 +17,7 @@ namespace Volo.Blogging.Posts
Task<List<Post>> GetOrderedList(Guid blogId,bool descending = false, CancellationToken cancellationToken = default);
Task<List<Post>> GetListByUserIdAsync(Guid userId, CancellationToken cancellationToken = default);
Task<List<Post>> GetLatestBlogPostsAsync(Guid blogId, int count, CancellationToken cancellationToken = default);
}
}

22
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/BlogUser.cs

@ -1,4 +1,5 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Users;
@ -23,6 +24,27 @@ namespace Volo.Blogging.Users
public virtual string PhoneNumber { get; protected set; }
public virtual bool PhoneNumberConfirmed { get; protected set; }
[CanBeNull]
public virtual string WebSite { get; set; }
[CanBeNull]
public virtual string Twitter { get; set; }
[CanBeNull]
public virtual string Github { get; set; }
[CanBeNull]
public virtual string Linkedin { get; set; }
[CanBeNull]
public virtual string Company { get; set; }
[CanBeNull]
public virtual string JobTitle { get; set; }
[CanBeNull]
public virtual string Biography { get; set; }
protected BlogUser()
{

10
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs

@ -26,8 +26,16 @@ namespace Volo.Blogging.EntityFrameworkCore
builder.Entity<BlogUser>(b =>
{
b.ToTable(AbpBloggingDbProperties.DbTablePrefix + "Users", AbpBloggingDbProperties.DbSchema);
b.ConfigureByConvention();
b.Property<string>(nameof(BlogUser.Biography)).HasMaxLength(UserConsts.MaxBiographyLength).HasColumnName(nameof(BlogUser.Biography));
b.Property<string>(nameof(BlogUser.WebSite)).HasMaxLength(UserConsts.MaxWebSiteLength).HasColumnName(nameof(BlogUser.WebSite));
b.Property<string>(nameof(BlogUser.Twitter)).HasMaxLength(UserConsts.MaxTwitterLength).HasColumnName(nameof(BlogUser.Twitter));
b.Property<string>(nameof(BlogUser.Github)).HasMaxLength(UserConsts.MaxGithubLength).HasColumnName(nameof(BlogUser.Github));
b.Property<string>(nameof(BlogUser.Linkedin)).HasMaxLength(UserConsts.MaxLinkedinLength).HasColumnName(nameof(BlogUser.Linkedin));
b.Property<string>(nameof(BlogUser.Company)).HasMaxLength(UserConsts.MaxCompanyLength).HasColumnName(nameof(BlogUser.Company));
b.Property<string>(nameof(BlogUser.JobTitle)).HasMaxLength(UserConsts.MaxJobTitleLength).HasColumnName(nameof(BlogUser.JobTitle));
b.ConfigureAbpUser();
b.ApplyObjectExtensionMappings();

9
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Posts/EfCorePostRepository.cs

@ -70,6 +70,15 @@ namespace Volo.Blogging.Posts
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<Post>> GetLatestBlogPostsAsync(Guid blogId, int count, CancellationToken cancellationToken = default)
{
var query = (await GetDbSetAsync()).Where(p => p.BlogId == blogId)
.OrderByDescending(p => p.CreationTime)
.Take(count);
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
public override async Task<IQueryable<Post>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();

8
modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/MembersClientProxy.Generated.cs

@ -25,4 +25,12 @@ public partial class MembersClientProxy : ClientProxyBase<IMemberAppService>, IM
{ typeof(string), username }
});
}
public Task UpdateUserProfileAsync(CustomIdentityBlogUserUpdateDto input)
{
return RequestAsync(nameof(UpdateUserProfileAsync), new ClientProxyRequestTypeValue
{
{ typeof(CustomIdentityBlogUserUpdateDto), input }
});
}
}

9
modules/blogging/src/Volo.Blogging.HttpApi.Client/ClientProxies/PostsClientProxy.Generated.cs

@ -74,6 +74,15 @@ public partial class PostsClientProxy : ClientProxyBase<IPostAppService>, IPostA
});
}
public Task<List<PostWithDetailsDto>> GetLatestBlogPostsAsync(Guid blogId, int count)
{
return RequestAsync<List<PostWithDetailsDto>>(nameof(GetLatestBlogPostsAsync), new ClientProxyRequestTypeValue
{
{ typeof(Guid), blogId },
{ typeof(int), count }
});
}
public virtual async Task DeleteAsync(Guid id)
{
await RequestAsync(nameof(DeleteAsync), new ClientProxyRequestTypeValue

7
modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/PostsController.cs

@ -69,6 +69,13 @@ namespace Volo.Blogging
return _postAppService.GetListByUserIdAsync(userId);
}
[HttpGet]
[Route("{blogId}/latest/{count}")]
public Task<List<PostWithDetailsDto>> GetLatestBlogPostsAsync(Guid blogId, int count)
{
return _postAppService.GetLatestBlogPostsAsync(blogId, count);
}
[HttpDelete]
[Route("{id}")]
public Task DeleteAsync(Guid id)

10
modules/blogging/src/Volo.Blogging.MongoDB/Volo/Blogging/Posts/MongoPostRepository.cs

@ -4,6 +4,7 @@ using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Nito.AsyncEx;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
@ -66,5 +67,14 @@ namespace Volo.Blogging.Posts
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<Post>> GetLatestBlogPostsAsync(Guid blogId, int count, CancellationToken cancellationToken = default)
{
var query = (await GetMongoQueryableAsync(cancellationToken)).Where(x => x.BlogId == blogId)
.OrderByDescending(x => x.CreationTime)
.Take(count);
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
}
}

667
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml

@ -1,4 +1,5 @@
@page
@using System.Globalization
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Http.Extensions
@using Microsoft.Extensions.Options
@ -11,6 +12,7 @@
@inject IAuthorizationService Authorization
@inject IOptionsSnapshot<BloggingTwitterOptions> twitterOptions
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Volo.Blogging.Localization
@using Volo.Blogging.Pages.Blog
@inject IHtmlLocalizer<BloggingResource> L
@ -45,318 +47,453 @@
<abp-style-bundle name="@typeof(DetailModel).FullName">
<abp-script type="@typeof(PrismjsStyleBundleContributor)" />
<abp-style src="/Pages/Blogs/Shared/Styles/blog.css" />
<abp-style src="/Pages/Blogs/Posts/detail.css" />
</abp-style-bundle>
}
<div class="vs-blog vs-blog-detail">
<abp-input asp-for="FocusCommentId" class="m-0" />
<div class="container">
<div class="row">
<div class="col-12 col-md-8 col-lg-7 mx-auto">
<section class="hero-section">
<div class="hero-articles">
<div class="hero-content">
<h1 class="mb-3" id="PostTitle">@Model.Post.Title</h1>
<abp-input asp-for="FocusCommentId" class="m-0"/>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-8 col-lg-8 mx-auto">
<section class="hero-section">
<div class="hero-articles">
<div class="hero-content">
<h1 class="mb-3" id="PostTitle">@Model.Post.Title</h1>
<div class="article-owner">
<div class="article-infos">
<div class="user-card mt-3 mb-4">
<div class="row">
<div class="col-auto pe-1">
@if (Model.Post.Writer != null)
{
<a href="/Members/@Model.Post.Writer.UserName" aria-label="Go to user profile">
<img gravatar-email="@Model.Post.Writer.Email" default-image="Identicon" class="article-avatar" alt="User Avatar"/>
</a>
}
</div>
<div class="col ps-1">
@if (Model.Post.Writer != null)
{
<h5 class="mt-2 mb-1">
<a href="/Members/@Model.Post.Writer.UserName">
@(Model.Post.Writer.UserName)
</a>
<span>@BloggingPageHelper.ConvertDatetimeToTimeAgo(Model.Post.CreationTime)</span>
</h5>
}
<div class="article-owner">
<div class="article-infos">
<div class="user-card mt-3 mb-4">
<div class="row">
<div class="col-auto pe-1">
@if (Model.Post.Writer != null)
{
<a href="/Members/@Model.Post.Writer.UserName" aria-label="Go to user profile">
<img gravatar-email="@Model.Post.Writer.Email" default-image="Identicon" class="article-avatar" alt="User Avatar" />
</a>
}
</div>
<div class="col ps-1">
@if (Model.Post.Writer != null)
{
<h5 class="mt-2 mb-1">
<a href="/Members/@Model.Post.Writer.UserName">
@(Model.Post.Writer.UserName)
</a>
<span>@BloggingPageHelper.ConvertDatetimeToTimeAgo(Model.Post.CreationTime)</span>
</h5>
}
<i class="fa fa-eye"></i> @L["WiewsWithCount", @Model.Post.ReadCount]
<span class="vs-seperator">|</span>
<i class="fa fa-comment"></i> @L["CommentWithCount", @Model.CommentCount]
<i class="fa fa-eye"></i> @L["WiewsWithCount", @Model.Post.ReadCount]
<span class="vs-seperator">|</span>
<i class="fa fa-comment"></i> @L["CommentWithCount", @Model.CommentCount]
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Update))
{
<span class="seperator">|</span>
<a asp-page="./Edit" asp-route-postId="@Model.Post.Id" asp-route-blogShortName="@Model.BlogShortName">
<i class="fa fa-pencil"></i> @L["Edit"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Delete) || (CurrentUser.Id.HasValue && CurrentUser.Id == Model.Post.CreatorId))
{
<span class="seperator">|</span>
<a href="#" id="DeletePostLink" data-postid="@Model.Post.Id" data-blogShortName="@Model.BlogShortName">
<i class="fa fa-trash"></i> @L["Delete"]
</a>
}
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Update))
{
<span class="seperator">|</span>
<a asp-page="./Edit" asp-route-postId="@Model.Post.Id" asp-route-blogShortName="@Model.BlogShortName">
<i class="fa fa-pencil"></i> @L["Edit"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Delete) || (CurrentUser.Id.HasValue && CurrentUser.Id == Model.Post.CreatorId))
{
<span class="seperator">|</span>
<a href="#" id="DeletePostLink" data-postid="@Model.Post.Id" data-blogShortName="@Model.BlogShortName">
<i class="fa fa-trash"></i> @L["Delete"]
</a>
}
<div class="float-end">
<a href="#" target="_blank" class="me-2" id="TwitterShareLink" title="Twitter">
<i class="fa fa-twitter fa-lg"></i>
</a>
<a href="#" target="_blank" class="me-2" id="LinkedinShareLink" title="LinkedIn">
<i class="fa fa-linkedin fa-lg"></i>
</a>
<a href="#" target="_blank" class="me-2" id="FacebookShareLink" title="Facebook">
<i class="fa fa-facebook fa-lg"></i>
</a>
<a href="#" target="_blank" class="me-2" id="EmailShareLink" title="E-mail">
<i class="fa fa-envelope-square fa-lg"></i>
</a>
<button class="copy-link me-2" id="CopyLink" title="CopyLink">
<i class="fa fa-link fa-lg"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="img-container mb-3">
<img src="@Model.Post.CoverImage" alt="Cover Image" />
</div>
</div>
</section>
</div>
</div>
<div class="row">
<div class="col-12 col-md-8 col-lg-7 mx-auto">
<section class="post-content">
<p>
@Html.Raw(BloggingPageHelper.RenderMarkdownToHtml(Model.Post.Content))
</p>
</section>
</div>
<div class="img-container mb-3">
<img src="@Model.Post.CoverImage" alt="Cover Image"/>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-md-8 col-lg-7 mx-auto">
<hr />
<div class="mb-2 mt-1">
@(L["ShareOn"].Value + " :")
<a href="#" target="_blank" class="me-2" id="TwitterShareLink" title="Twitter">
Twitter <i class="fa fa-twitter"></i>
</a>
<a href="#" target="_blank" class="me-2" id="LinkedinShareLink" title="LinkedIn">
Linkedin <i class="fa fa-linkedin"></i>
</section>
<section class="post-content">
<p>
@Html.Raw(BloggingPageHelper.RenderMarkdownToHtml(Model.Post.Content))
</p>
</section>
</div>
<div class="col-12 col-md-4 col-lg-3">
<div class="list-group">
<div class="col-auto pe-2">
@if (Model.Post.Writer != null)
{
<a href="/Members/@Model.Post.Writer.UserName" aria-label="Go to user profile">
<img gravatar-email="@Model.Post.Writer.Email" default-image="Identicon" class="article-avatar rounded-circle" alt="User Avatar"/>
</a>
<a href="#" target="_blank" class="me-2" id="EmailShareLink" title="E-mail">
E-mail <i class="fa fa-envelope-square"></i>
}
</div>
<div class="col ps-1">
<h5 class="mt-2 mb-1">
<a href="/Members/@Model.Post.Writer.UserName">
@if (Model.Post.Writer.Name != null && Model.Post.Writer.Surname != null)
{
<p class="fw-bold pt-2 fs-5">@Model.Post.Writer.Name @Model.Post.Writer.Surname</p>
}
else
{
<p class="fw-bold pt-2 fs-5">@Model.Post.Writer.UserName</p>
}
</a>
</h5>
<div class="position-relative">
@if (Model.Post.Writer.JobTitle != null)
{
<p class="fw-lighter">@Model.Post.Writer.JobTitle</p>
}
</div>
@if (Model.Post.Tags.Count > 0)
@if (CurrentUser.UserName == Model.Post.Writer.UserName)
{
<div class="tags">
<h5>@L["TagsInThisArticle"]</h5>
@foreach (var tag in Model.Post.Tags)
<a class="fw-lighter" href="/Members/@Model.Post.Writer.UserName#edit-profile">@L["EditProfile"] <i class="fas fa-edit"></i></a>
}
</div>
@if (Model.LatestPosts.Count > 1)
{
<hr/>
<p class="fs-3 fw-bold text-dark">@L["MoreFromBlog"]</p>
@for (var index = 0; index < Model.LatestPosts.Count && index < 5; index++)
{
if (Model.LatestPosts[index].Id != Model.Post.Id)
{
var post = Model.LatestPosts[index];
<section class="box-articles p-0">
<div class="row align-middle">
<div class="article-owner">
<div class="article-infos">
<div class="user-card pt-3">
<div class="row">
<div class="col-auto pe-1">
@if (post.Writer != null)
{
<a href="/Members/@post.Writer.UserName" aria-label="Go to user profile">
<img gravatar-email="@post.Writer.Email" default-image="Identicon" class="last-post-image" alt="User Avatar"/>
</a>
}
</div>
<div class="col">
<h5 class="last-post-name">
<a href="/Members/@post.Writer.UserName">
@(post.Writer.UserName)
</a>
</h5>
</div>
</div>
</div>
</div>
<div class="col mt-2">
<p>
<a class="last-post-title" asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">@post.Title</a>
</p>
</div>
</div>
</div>
</section>
}
}
}
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-md-8 col-lg-8 mx-auto">
@if (Model.Post.Tags.Count > 0)
{
<div class="tags">
<h5>@L["TagsInThisArticle"]</h5>
@foreach (var tag in Model.Post.Tags)
{
<a asp-page="/Blogs/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</div>
}
@if (Model.CommentsWithReplies.Count > 0)
{
<abp-row v-align="Start">
<abp-column size-sm="_12">
<p class="float-start"><i class="fa fa-comment"></i> @L["CommentWithCount", @Model.CommentCount]</p>
@if (hasCommentingPermission)
{
<a abp-button="Primary" class="btn-rounded float-end active" href="#LeaveComment">@L["LeaveComment"]</a>
}
else
{
<a abp-button="Primary" class="btn-rounded float-end active" href="/Account/Login?returnUrl=@System.Web.HttpUtility.UrlEncode(@Request.Path)">@L["LeaveComment"]</a>
}
</abp-column>
</abp-row>
<div class="comment-area">
@foreach (var commentWithRepliesDto in Model.CommentsWithReplies)
{
<div class="media">
<img gravatar-email="@commentWithRepliesDto.Comment.Writer.Email" default-image="Identicon" class="d-flex me-3 rounded-circle comment-avatar" alt="User Avatar"/>
<div class="media-body">
<h5 class="comment-owner">
@(commentWithRepliesDto.Comment.Writer == null ? "" : commentWithRepliesDto.Comment.Writer.UserName)
<span>@BloggingPageHelper.ConvertDatetimeToTimeAgo(commentWithRepliesDto.Comment.CreationTime)</span>
</h5>
<p id="@commentWithRepliesDto.Comment.Id">
@commentWithRepliesDto.Comment.Text
</p>
<div class="comment-buttons">
@if (hasCommentingPermission)
{
<a asp-page="/Blogs/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
<a href="#" class="tag replyLink" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
}
</div>
}
@if (Model.CommentsWithReplies.Count > 0)
{
<abp-row v-align="Start">
<abp-column size-sm="_12">
<p class="float-start"><i class="fa fa-comment"></i> @L["CommentWithCount", @Model.CommentCount]</p>
@if (hasCommentingPermission)
{
<a abp-button="Primary" class="btn-rounded float-end active" href="#LeaveComment">@L["LeaveComment"]</a>
}
else
{
<a abp-button="Primary" class="btn-rounded float-end active" href="/Account/Login?returnUrl=@System.Web.HttpUtility.UrlEncode(@Request.Path)">@L["LeaveComment"]</a>
}
</abp-column>
</abp-row>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag deleteLink" data-deleteid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
</a>
}
<div class="comment-area">
@foreach (var commentWithRepliesDto in Model.CommentsWithReplies)
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="media">
<img gravatar-email="@commentWithRepliesDto.Comment.Writer.Email" default-image="Identicon" class="d-flex me-3 rounded-circle comment-avatar" alt="User Avatar" />
<div class="media-body">
<h5 class="comment-owner">
@(commentWithRepliesDto.Comment.Writer == null ? "" : commentWithRepliesDto.Comment.Writer.UserName)
<span>@BloggingPageHelper.ConvertDatetimeToTimeAgo(commentWithRepliesDto.Comment.CreationTime)</span>
</h5>
<p id="@commentWithRepliesDto.Comment.Id">
@commentWithRepliesDto.Comment.Text
</p>
<div class="comment-buttons">
<span class="seperator">|</span>
<a href="#" class="tag updateLink" data-updateid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
@if (hasCommentingPermission)
{
<a href="#" class="tag replyLink" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
}
@if (hasCommentingPermission)
{
<div class="comment-form mt-4 replyForm">
<div class="clearfix p-4">
<h3 class="mt-0">
@L["ReplyTo", commentWithRepliesDto.Comment.Writer == null ? "" : commentWithRepliesDto.Comment.Writer.UserName]
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag deleteLink" data-deleteid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
</a>
}
</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" type="hidden"/>
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden/>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag updateLink" data-updateid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Comment"].Value"/>
<abp-button button-type="Danger" class="btn-rounded float-end replyCancelButton" text="@L["Cancel"].Value"/>
</form>
</div>
</div>
</div>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="clearfix p-4">
<div>
<form class="editFormClass">
<input name="commentId" value="@commentWithRepliesDto.Comment.Id" hidden/>
<input name="concurrencyStamp" value="@commentWithRepliesDto.Comment.ConcurrencyStamp" hidden/>
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4">@commentWithRepliesDto.Comment.Text</textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value"/>
<abp-button button-type="Danger" class="btn-rounded float-end editCancelButton" text="@L["Cancel"].Value"/>
</form>
</div>
</div>
</div>
}
@foreach (var reply in commentWithRepliesDto.Replies)
{
<div class="media">
<img gravatar-email="@reply.Writer.Email" default-image="Identicon" class="d-flex me-3 rounded-circle comment-avatar" alt="User Avatar"/>
<div class="media-body">
<h5 class="comment-owner">
@(reply.Writer == null ? "" : reply.Writer.UserName)
<span>@BloggingPageHelper.ConvertDatetimeToTimeAgo(reply.CreationTime)</span>
</h5>
<p id="@reply.Id">
@reply.Text
</p>
<div class="comment-buttons">
@if (hasCommentingPermission)
{
<div class="comment-form mt-4 replyForm">
<div class="clearfix p-4">
<h3 class="mt-0">
@L["ReplyTo", commentWithRepliesDto.Comment.Writer == null ? "" : commentWithRepliesDto.Comment.Writer.UserName]
</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" type="hidden" />
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Comment"].Value" />
<abp-button button-type="Danger" class="btn-rounded float-end replyCancelButton" text="@L["Cancel"].Value" />
</form>
</div>
</div>
</div>
<a href="#" class="tag replyLink" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="clearfix p-4">
<div>
<form class="editFormClass">
<input name="commentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<input name="concurrencyStamp" value="@commentWithRepliesDto.Comment.ConcurrencyStamp" hidden />
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4">@commentWithRepliesDto.Comment.Text</textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value" />
<abp-button button-type="Danger" class="btn-rounded float-end editCancelButton" text="@L["Cancel"].Value" />
</form>
</div>
</div>
</div>
<span class="seperator">|</span>
<a href="#" class="tag deleteLink" data-deleteid="@reply.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
</a>
}
@foreach (var reply in commentWithRepliesDto.Replies)
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="media">
<img gravatar-email="@reply.Writer.Email" default-image="Identicon" class="d-flex me-3 rounded-circle comment-avatar" alt="User Avatar" />
<div class="media-body">
<h5 class="comment-owner">
@(reply.Writer == null ? "" : reply.Writer.UserName)
<span>@BloggingPageHelper.ConvertDatetimeToTimeAgo(reply.CreationTime)</span>
</h5>
<p id="@reply.Id">
@reply.Text
</p>
<div class="comment-buttons">
@if (hasCommentingPermission)
{
<a href="#" class="tag replyLink" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag deleteLink" data-deleteid="@reply.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag updateLink" data-updateid="@reply.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
<span class="seperator">|</span>
<a href="#" class="tag updateLink" data-updateid="@reply.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
@if (hasCommentingPermission)
{
<div class="comment-form mt-4 replyForm">
<div class="clearfix bg-light py-4">
<h3 class="mt-0">
@L["ReplyTo", commentWithRepliesDto.Comment.Writer == null ? "" : commentWithRepliesDto.Comment.Writer.UserName]
</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value" />
<abp-button button-type="Danger" class="btn-rounded float-end replyCancelButton" text="@L["Cancel"].Value" />
</form>
</div>
</div>
@if (hasCommentingPermission)
{
<div class="comment-form mt-4 replyForm">
<div class="clearfix bg-light py-4">
<h3 class="mt-0">
@L["ReplyTo", commentWithRepliesDto.Comment.Writer == null ? "" : commentWithRepliesDto.Comment.Writer.UserName]
</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden/>
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden/>
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4"></textarea>
</div>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="clearfix bg-light py-4">
<div>
<form class="editFormClass">
<input name="commentId" value="@reply.Id" hidden />
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4">@reply.Text</textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value" />
<abp-button button-type="Danger" class="btn-rounded float-end editCancelButton" text="@L["Cancel"].Value" />
</form>
</div>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value"/>
<abp-button button-type="Danger" class="btn-rounded float-end replyCancelButton" text="@L["Cancel"].Value"/>
</form>
</div>
</div>
</div>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="clearfix bg-light py-4">
<div>
<form class="editFormClass">
<input name="commentId" value="@reply.Id" hidden/>
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4">@reply.Text</textarea>
</div>
}
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value"/>
<abp-button button-type="Danger" class="btn-rounded float-end editCancelButton" text="@L["Cancel"].Value"/>
</form>
</div>
</div>
}
</div>
</div>
}
</div>
}
</div>
}
</div>
}
</div>
</div>
}
</div>
}
@if (hasCommentingPermission)
@if (hasCommentingPermission)
{
<div class="comment-form mt-4" id="LeaveComment">
<div class="vs-blog-title mb-0">
<h3>@L["LeaveComment"]</h3>
</div>
<div class="clearfix bg-light py-4">
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden/>
<input name="repliedCommentId" id="repliedCommentId" hidden/>
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value"/>
</form>
</div>
</div>
</div>
}
else
{
<a abp-button="Primary" class="btn-rounded float-end active" href="/Account/Login?returnUrl=@System.Web.HttpUtility.UrlEncode(@Request.Path)">@L["LeaveComment"]</a>
}
<div class="hero articles">
<div class="hero content">
@if (Model.PostsList.Count > 1)
{
var userName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Model.Post.Writer.UserName);
<p class="fs-3 fw-bold text-dark">@L["MoreFromUser", userName]</p>
for (var index = 0; index < Model.PostsList.Count; index++)
{
if (Model.PostsList[index].Id != Model.Post.Id)
{
<div class="comment-form mt-4" id="LeaveComment">
<div class="vs-blog-title mb-0">
<h3>@L["LeaveComment"]</h3>
var post = Model.PostsList[index];
<div class="post-item">
<div class="post-type-cont">
<a href="/members/@Model.Post.Writer.UserName" class="text-decoration-none">
<img gravatar-email="@Model.Post.Writer.Email" default-image="Identicon" class="post-member-img rounded-circle d-block"/>
</a>
<span class="post-type">
<i class="fas fa-pen-nib"></i>
@L["Blog"].Value.ToUpper()
</span>
</div>
<div class="clearfix bg-light py-4">
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" id="repliedCommentId" hidden />
<div class="mb-3">
<textarea class="form-control" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-end" type="submit" text="@L["Submit"].Value" />
</form>
<div class="post-detail-cont">
<div class="post-info fs-12 mb-2">
<a href="/members/@Model.Post.Writer.UserName" class="text-decoration-none">
<span class="text-dark dot">@Model.Post.Writer.UserName</span>
</a>
<span class="text-dark-200">@post.CreationTime.ToString("MMMM yyyy")</span>
</div>
<h2 class="post-title mt-2">
<a asp-page="./Detail" asp-route-postUrl="@post.Url">
@post.Title
</a>
</h2>
<p class="post-desc">
<a asp-page="./Detail" asp-route-postUrl="@post.Url">
@post.Description.TruncateWithPostfix(150)
</a>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" class="readMore">@L["ReadMore"]</a>
</p>
</div>
<div class="post-img-cont">
<div class="post-list-span text-center post">
<img src="@post.CoverImage" class="box-articles">
</div>
</div>
</div>
}
else
{
<a abp-button="Primary" class="btn-rounded float-end active mt-3" href="/Account/Login?returnUrl=@System.Web.HttpUtility.UrlEncode(@Request.Path)">@L["LeaveComment"]</a>
}
</div>
</div>
}
}
</div>
</div>
</div>
<div class="col-12 col-md-4 col-lg-3">
</div>
</div>
</div>
</div>
<p id="BlogFullName" name="@Model.Blog.Name" hidden></p>

9
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml.cs

@ -40,6 +40,13 @@ namespace Volo.Blogging.Pages.Blog.Posts
public BlogDto Blog { get; set; }
public List<PostWithDetailsDto> PostsList { get; set; }
public IReadOnlyList<PostWithDetailsDto> LatestPosts { get; set; }
[BindProperty(SupportsGet = true)]
public string TagName { get; set; }
public DetailModel(IPostAppService postAppService, IBlogAppService blogAppService, ICommentAppService commentAppService)
{
_postAppService = postAppService;
@ -79,6 +86,8 @@ namespace Volo.Blogging.Pages.Blog.Posts
{
Blog = await _blogAppService.GetByShortNameAsync(BlogShortName);
Post = await _postAppService.GetForReadingAsync(new GetPostInput { BlogId = Blog.Id, Url = PostUrl });
PostsList = await _postAppService.GetListByUserIdAsync(Post.Writer.Id);
LatestPosts = await _postAppService.GetLatestBlogPostsAsync(Blog.Id, 5);
CommentsWithReplies = await _commentAppService.GetHierarchicalListOfPostAsync(Post.Id);
CountComments();
}

28
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/detail.css

@ -0,0 +1,28 @@
.last-post-title{
font-size: 15px;
line-height: 20px;
font-weight: 700;
letter-spacing: 0px;
text-decoration: none;
color: black;
}
.last-post-image{
width: 30px;
height: 30px;
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.last-post-name{
padding-right: 2px;
max-height: 16px;
padding-top: 0.5em;
padding-right: 0.5em;
}
#CopyLink{
padding: 0;
border: none;
background: none;
color: rgba(0,0,0,.6);
}

17
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/detail.js

@ -15,6 +15,12 @@
pageHeader + ' | ' + blogName + ' | ' + window.location.href
)
);
$('#FacebookShareLink').attr(
'href',
'https://www.facebook.com/sharer/sharer.php?u=' +
encodeURI(window.location.href)
);
$('#LinkedinShareLink').attr(
'href',
@ -44,7 +50,16 @@
'&'
);
};
$('#CopyLink').click(function (event) {
event.preventDefault();
var $temp = $('<input>');
$('body').append($temp);
$temp.val(window.location.href).select();
document.execCommand('copy');
$temp.remove();
});
$('div .replyForm').hide();
$('div .editForm').hide();

1
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Shared/Styles/blog.css

@ -320,3 +320,4 @@ div.vs-blog {
text-decoration: none; }
div.vs-blog > .form-group {
margin: 0 !important; }

193
modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml

@ -1,7 +1,12 @@
@page
@using System.Globalization
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Utils
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.Users
@using Volo.Blogging
@using Volo.Blogging.Areas.Blog.Helpers.TagHelpers
@using Volo.Blogging.Localization
@model Volo.Blogging.Pages.Members.IndexModel
@inject IStringLocalizer<BloggingResource> L
@ -10,6 +15,10 @@
ViewBag.Title = @Model.User.UserName.ToUpper() + " - " + L["Blogs"].Value;
}
@section scripts {
<abp-script src="/Pages/Members/Index.js" />
}
@section styles {
<abp-style src="/Pages/Members/Index.css"/>
}
@ -23,20 +32,79 @@
<div class="d-inline-block position-relative">
<img gravatar-email="@Model.User.Email" default-image="Identicon" class="post-member-img rounded-circle d-block"/>
</div>
@if (Model.User.UserName != null)
@if (Model.User.Name != null && Model.User.Surname != null)
{
<h2 class="m-1">@Model.User.Name @Model.User.Surname</h2>
}
@if (Model.User.Company != null)
{
<h2 class="m-0">@Model.User.UserName</h2>
<h4 class="m-2">@Model.User.Company</h4>
}
<small class="d-block mt-4">@L["UserName"].Value.ToUpper()</small>
@if (Model.User.JobTitle != null)
{
<h4>@Model.User.JobTitle</h4>
}
<small class="d-block">@L["UserName"].Value.ToUpper()</small>
<h5>@Model.User.UserName</h5>
@if (Model.User.WebSite != null)
{
<small>@L["PersonalWebsite"].Value.ToUpper()</small>
<h5>
<a href="@Model.User.WebSite">@Model.User.WebSite</a>
</h5>
}
@if (Model.User.Twitter != null || Model.User.Github != null || Model.User.Linkedin != null)
{
<small>@L["Social"].Value.ToUpper()</small>
<ul class="d-flex justify-content-center">
@if (Model.User.Twitter != null)
{
<li class="mx-3">
<a href="https://twitter.com/@Model.User.Twitter">
<div class="icon-twitter-v1"></div>
</a>
</li>
}
@if (Model.User.Github != null)
{
<li class="mx-3">
<a href="https://github.com/@Model.User.Github">
<div class="icon-github large bg-dark"></div>
</a>
</li>
}
@if (Model.User.Linkedin != null)
{
<li class="mx-3">
<a href="@Model.User.Linkedin">
<div class="icon-linkedin-v1"></div>
</a>
</li>
}
</ul>
}
@if (Model.User.Biography != null)
{
<div class="m-2 mt-4">
<small>@L["Biography"].Value.ToUpper()</small>
<p>@Model.User.Biography</p>
</div>
}
</div>
</div>
</div>
@if (Model.Posts is not null && Model.Posts.Any())
<div class="col-md-8">
@if (CurrentUser.Id == Model.User.Id)
{
<div class="col-md-8">
<abp-tabs>
<abp-tab name="all-posts" title="All Blog Posts">
<abp-tabs>
@if (Model.Posts is not null && Model.Posts.Any())
{
<abp-tab name="all-posts" title="Posts">
<div class="mt-4 pt-3">
@foreach (var post in Model.Posts)
{
@ -80,17 +148,108 @@
}
</div>
</abp-tab>
</abp-tabs>
</div>
}
else
{
<div class="col-md-8">
<div class="mt-5 pt-6">
<p>@L["MemberNotPublishedPostYet"]</p>
</div>
}
else
{
<div class="col-md-8">
<div class="mt-5 pt-6">
<p>@L["MemberNotPublishedPostYet"]</p>
</div>
</div>
}
<abp-tab name="edit-profile" title="Edit Profile">
<div class="mt-4 mb-3 pt-3">
<form method="post">
<abp-row>
<abp-column size="_12" v-align="Center">
<abp-input class="form-control" asp-for="CustomUserUpdate.Name" required-symbol="false" label="@($"{L["Name"].Value} ({L["Optional"].Value})")" value="@Model.User.Name"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.Surname" required-symbol="false" label="@($"{L["Surname"].Value} ({L["Optional"].Value})")" value="@Model.User.Surname"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.WebSite" required-symbol="false" label="@($"{L["WebSite"].Value} ({L["Optional"].Value})")" value="@Model.User.WebSite" info="@L["UpdateUserWebSiteInfo"].Value"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.Twitter" required-symbol="false" label="Twitter @($"{L["UserName"].Value} ({L["Optional"].Value})")" value="@Model.User.Twitter" info="@L["UpdateUserTwitterInfo"].Value"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.Github" required-symbol="false" label="Github @($"{L["UserName"].Value} ({L["Optional"].Value})")" value="@Model.User.Github" info="@L["UpdateUserGithubInfo"].Value"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.Linkedin" required-symbol="false" label="Linkedin @($"{L["FullURL"].Value} ({L["Optional"].Value})")" value="@Model.User.Linkedin" info="@L["UpdateUserLinkedinInfo"].Value"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.Company" required-symbol="false" label="@($"{L["Company"].Value} ({L["Optional"].Value})")" value="@Model.User.Company" info="@L["UpdateUserCompanyInfo"].Value"></abp-input>
<abp-input class="form-control" asp-for="CustomUserUpdate.JobTitle" required-symbol="false" label="@($"{L["JobTitle"].Value} ({L["Optional"].Value})")" value="@Model.User.JobTitle" info="@L["UpdateUserJobTitleInfo"].Value"></abp-input>
<div class="mb-3">
<label class="form-label">@L["Biography"] (@L["Optional"])</label>
<textarea id="CustomUserUpdate_Biography" name="CustomUserUpdate.Biography" class="form-control " rows="7" data-val-length="The field Biography must be a string with a maximum length of 1000." data-val-length-max="1000" maxlength="1000">@Model.User.Biography</textarea>
</div>
</abp-column>
</abp-row>
<div class="d-grid gap-2">
<button id="btnSubmit" type="submit" class="btn btn-primary">@L["Submit"]</button>
</div>
</form>
</div>
</abp-tab>
</abp-tabs>
}
else
{
if (Model.Posts is not null && Model.Posts.Any())
{
<h2>@L["BlogPosts"]</h2>
<div class="mt-4 pt-3">
@foreach (var post in Model.Posts)
{
<div class="post-item">
<div class="post-type-cont">
<a href="@Model.GetMemberProfileUrl(Model.User)" class="text-decoration-none">
<img gravatar-email="@Model.User.Email" default-image="Identicon" class="post-member-img rounded-circle d-block"/>
</a>
<span class="post-type">
<i class="fas fa-pen-nib"></i>
@L["Blog"].Value.ToUpper()
</span>
</div>
<div class="post-detail-cont">
<div class="post-info fs-12 mb-2">
<a href="@Model.GetMemberProfileUrl(Model.User)" class="text-decoration-none">
<span class="text-dark dot">@Model.User.UserName</span>
</a>
<span class="text-dark-200 dot">@post.CreationTime.ToString("MMMM yyyy")</span>
<span class="text-dark-200">@post.ReadCount.ToString() @L["Views"]</span>
</div>
<h3 class="post-title mb-3">
<a href="@Model.GetBlogPostUrl(post)">
@post.Title
</a>
</h3>
<p class="post-desc">
<a href="@Model.GetBlogPostUrl(post)">
@post.Description.TruncateWithPostfix(150)
</a>
<a href="@Model.GetBlogPostUrl(post)" class="readMore">@L["ReadMore"]</a>
</p>
</div>
<div class="post-img-cont">
<div class="post-list-span text-center post">
<img src="@post.CoverImage" class="box-articles">
</div>
</div>
</div>
}
</div>
}
else
{
<div class="col-md-8">
<div class="mt-5 pt-6">
<p>@L["MemberNotPublishedPostYet"]</p>
</div>
</div>
}
}
</div>
}
</div>
</div>
</main>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save