Browse Source

Merge branch 'dev' into RequireEmailVerificationToRegister

pull/21973/head
maliming 2 years ago
parent
commit
cea913b271
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 101
      .github/scripts/update_versions.py
  2. 4
      Directory.Packages.props
  3. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  4. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
  5. 5
      common.props
  6. 3
      docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/Post.md
  7. 4
      docs/en/Community-Articles/2024-01-15-Abp-Supports-NET8/Post.md
  8. 6
      docs/en/Community-Articles/2024-08-28-Understanding-AOT-vs-JIT/POST.md
  9. 4
      docs/en/Community-Articles/2024-08-29-What-is-Angular-Schematics/Post.md
  10. 2
      docs/en/Community-Articles/2024-09-01-Do-You-Need-MultiTenancy/Post.md
  11. 2
      docs/en/Community-Articles/2024-09-18-Blazor-9-New-Features/post.md
  12. 4
      docs/en/Community-Articles/2024-09-24-Angular-Difference-Btw-Promise-Observable/post.md
  13. 5
      docs/en/Community-Articles/2024-10-01-SignalR-9-New-Features/Post.md
  14. 6
      docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/Post.md
  15. 2
      docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/Post.md
  16. 2
      docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/POST.md
  17. 4
      docs/en/Community-Articles/2024-10-23-Abp-Net9-Upgrade/post.md
  18. 2
      docs/en/Community-Articles/2024-11-13-BuiltIn-OpenApi-Documentation/post.md
  19. 4
      docs/en/Community-Articles/2024-12-01-OpenAI-Integration/POST.md
  20. 2
      docs/en/Community-Articles/2025-01-03-ABP-Background-Workers-vs-Jobs/background-jobs-vs-background-workers.md
  21. 2
      docs/en/Community-Articles/2025-01-24-Understanding-Transactions-in-ABP-Unit-Of-Work/POST.md
  22. 66
      docs/en/docs-nav.json
  23. 12
      docs/en/solution-templates/layered-web-application/deployment/azure-deployment/step3-deployment-github-action.md
  24. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/ar.json
  25. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/cs.json
  26. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/de-DE.json
  27. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/de.json
  28. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/en.json
  29. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/es.json
  30. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/fi.json
  31. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/fr.json
  32. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/hi.json
  33. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/hr.json
  34. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/hu.json
  35. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/is.json
  36. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/it.json
  37. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/nl.json
  38. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/pl-PL.json
  39. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/pt-BR.json
  40. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/ro-RO.json
  41. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/ru.json
  42. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/sk.json
  43. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/sl.json
  44. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/sv.json
  45. 5
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/tr.json
  46. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/vi.json
  47. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hans.json
  48. 3
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hant.json
  49. 3
      modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs
  50. 6
      modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs
  51. 20
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js
  52. 30
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs
  53. 34
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.Password.cs
  54. 10
      npm/ng-packs/packages/core/src/lib/services/local-storage-listener.service.ts
  55. 2
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html
  56. 6
      npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.html

101
.github/scripts/update_versions.py

@ -1,54 +1,79 @@
import os import os
import json import json
import re
import xml.etree.ElementTree as ET
from github import Github from github import Github
def update_latest_versions(): def get_target_release_branch(version):
version = os.environ["GITHUB_REF"].split("/")[-1] """
Extracts the first two numbers from the release version (`9.0.5` → `rel-9.0`)
to determine the corresponding `rel-x.x` branch.
"""
match = re.match(r"(\d+)\.(\d+)\.\d+", version)
if not match:
raise ValueError(f"Invalid version format: {version}")
if "rc" in version: major, minor = match.groups()
return False target_branch = f"rel-{major}.{minor}"
return target_branch
with open("latest-versions.json", "r") as f: def get_version_from_common_props(branch):
latest_versions = json.load(f) """
Retrieves `Version` and `LeptonXVersion` from the `common.props` file in the specified branch.
"""
g = Github(os.environ["GITHUB_TOKEN"])
repo = g.get_repo("abpframework/abp")
latest_versions[0]["version"] = version try:
file_content = repo.get_contents("common.props", ref=branch)
common_props_content = file_content.decoded_content.decode("utf-8")
with open("latest-versions.json", "w") as f: root = ET.fromstring(common_props_content)
json.dump(latest_versions, f, indent=2) version = root.find(".//Version").text
leptonx_version = root.find(".//LeptonXVersion").text
return True return version, leptonx_version
except Exception as e:
raise FileNotFoundError(f"common.props not found in branch {branch}: {e}")
def create_pr(): def update_latest_versions():
g = Github(os.environ["GITHUB_TOKEN"]) """
repo = g.get_repo("abpframework/abp") Updates `latest-versions.json` based on the most relevant release branch.
"""
# Get the release version from GitHub reference
release_version = os.environ["GITHUB_REF"].split("/")[-1] # Example: "refs/tags/v9.0.5" → "v9.0.5"
if release_version.startswith("v"):
release_version = release_version[1:] # Convert to "9.0.5" format
branch_name = f"update-latest-versions-{os.environ['GITHUB_REF'].split('/')[-1]}" # Determine the correct `rel-x.x` branch
base = repo.get_branch("dev") target_branch = get_target_release_branch(release_version)
repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=base.commit.sha)
# Retrieve `common.props` data from the target branch
version, leptonx_version = get_version_from_common_props(target_branch)
# Get the current latest-versions.json file and its sha # Skip if the version is a preview or release candidate
contents = repo.get_contents("latest-versions.json", ref="dev") if "preview" in version or "rc" in version:
file_sha = contents.sha return False
# Update the file in the repo # Read the `latest-versions.json` file
repo.update_file( with open("latest-versions.json", "r") as f:
path="latest-versions.json", latest_versions = json.load(f)
message=f"Update latest-versions.json to version {os.environ['GITHUB_REF'].split('/')[-1]}",
content=open("latest-versions.json", "r").read().encode("utf-8"),
sha=file_sha,
branch=branch_name,
)
try: # Add the new version entry
pr = repo.create_pull(title="Update latest-versions.json", new_version_entry = {
body="Automated PR to update the latest-versions.json file.", "version": version,
head=branch_name, base="dev") "releaseDate": "",
except Exception as e: "type": "stable",
print(f"Error while creating PR: {e}") "message": "",
"leptonx": {
"version": leptonx_version
}
}
latest_versions.insert(0, new_version_entry) # Insert the new version at the top
pr.create_review_request(reviewers=["ebicoglu", "gizemmutukurt", "skoc10"]) # Update the file
with open("latest-versions.json", "w") as f:
json.dump(latest_versions, f, indent=2)
if __name__ == "__main__": return True
should_create_pr = update_latest_versions()
if should_create_pr:
create_pr()

4
Directory.Packages.props

@ -164,7 +164,7 @@
<PackageVersion Include="System.Collections.Immutable" Version="9.0.0" /> <PackageVersion Include="System.Collections.Immutable" Version="9.0.0" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" /> <PackageVersion Include="System.Linq.Async" Version="6.0.1" />
<PackageVersion Include="System.Linq.Dynamic.Core" Version="1.4.5" /> <PackageVersion Include="System.Linq.Dynamic.Core" Version="1.6.0.1" />
<PackageVersion Include="System.Linq.Queryable" Version="4.3.0" /> <PackageVersion Include="System.Linq.Queryable" Version="4.3.0" />
<PackageVersion Include="System.Runtime.Loader" Version="4.3.0" /> <PackageVersion Include="System.Runtime.Loader" Version="4.3.0" />
<PackageVersion Include="System.Security.Permissions" Version="9.0.0" /> <PackageVersion Include="System.Security.Permissions" Version="9.0.0" />
@ -183,4 +183,4 @@
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" /> <PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" />
<PackageVersion Include="Fody" Version="6.8.2" /> <PackageVersion Include="Fody" Version="6.8.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

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

@ -645,7 +645,7 @@
"ExtendPaymentInfoSection_Description": "By extending/renewing your license, you will continue to get <a href=\"{0}\" target=\"_blank\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\">ABP Suite</a> which speeds up your development.", "ExtendPaymentInfoSection_Description": "By extending/renewing your license, you will continue to get <a href=\"{0}\" target=\"_blank\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\">ABP Suite</a> which speeds up your development.",
"LicenseRenewalPrice": "License renewal price", "LicenseRenewalPrice": "License renewal price",
"LicensePrice": "License Price", "LicensePrice": "License Price",
"TrialLicensePaymentInfoSection_Description": "<strong>Purchase license:</strong> By purchasing a license, you will continue to get <a href=\"{0}\" target=\"_blank\" rel=\"noopener\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\" rel=\"noopener\">ABP Suite</a> which speeds up your development.<br>See the <a href=\"{2}\" target=\"_blank\" rel=\"noopener\">license comparison table</a> to check the differences between the license types.", "TrialLicensePaymentInfoSection_Description": "<strong>Purchase license:</strong> By purchasing a license, you will continue to get <a href=\"https://abp.io/support/questions\" target=\"_blank\" rel=\"noopener\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\" rel=\"noopener\">ABP Suite</a> which speeds up your development.<br>See the <a href=\"{2}\" target=\"_blank\" rel=\"noopener\">license comparison table</a> to check the differences between the license types.",
"SelectTargetLicense": "Select Target License", "SelectTargetLicense": "Select Target License",
"UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Yes, extend my license expiration date for 1 year.", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Yes, extend my license expiration date for 1 year.",
"UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for 1 more year?", "UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for 1 more year?",

2
abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json

@ -1348,7 +1348,7 @@
"ExtendPaymentInfoSection_Description": "By extending/renewing your license, you will continue to get <a href=\"{0}\" target=\"_blank\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\">ABP Suite</a> which speeds up your development.", "ExtendPaymentInfoSection_Description": "By extending/renewing your license, you will continue to get <a href=\"{0}\" target=\"_blank\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\">ABP Suite</a> which speeds up your development.",
"LicenseRenewalPrice": "License renewal price", "LicenseRenewalPrice": "License renewal price",
"LicensePrice": "License Price", "LicensePrice": "License Price",
"TrialLicensePaymentInfoSection_Description": "<strong>Purchase license:</strong> By purchasing a license, you will continue to get <a href=\"{0}\" target=\"_blank\" rel=\"noopener\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\" rel=\"noopener\">ABP Suite</a> which speeds up your development.<br>See the <a href=\"{2}\" target=\"_blank\" rel=\"noopener\">license comparison table</a> to check the differences between the license types.", "TrialLicensePaymentInfoSection_Description": "<strong>Purchase license:</strong> By purchasing a license, you will continue to get <a href=\"https://abp.io/support/questions\" target=\"_blank\" rel=\"noopener\">premium support</a>. You will also be able to get major or minor updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use <a href=\"{1}\" target=\"_blank\" rel=\"noopener\">ABP Suite</a> which speeds up your development.<br>See the <a href=\"{2}\" target=\"_blank\" rel=\"noopener\">license comparison table</a> to check the differences between the license types.",
"SelectTargetLicense": "Select Target License", "SelectTargetLicense": "Select Target License",
"UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Yes, extend my license expiration date for 1 year.", "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "Yes, extend my license expiration date for 1 year.",
"UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for 1 more year?", "UpgradePaymentInfoSection_WantToExtendLicense": "Do you want to extend your license for 1 more year?",

5
common.props

@ -1,8 +1,13 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<<<<<<< auto-merge/rel-9-1/3468
<Version>9.1.0-rc.2</Version>
<LeptonXVersion>4.1.0-rc.2</LeptonXVersion>
=======
<Version>9.2.0-preview</Version> <Version>9.2.0-preview</Version>
<LeptonXVersion>4.2.0-preview</LeptonXVersion> <LeptonXVersion>4.2.0-preview</LeptonXVersion>
>>>>>>> dev
<NoWarn>$(NoWarn);CS1591;CS0436</NoWarn> <NoWarn>$(NoWarn);CS1591;CS0436</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl> <PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io/</PackageProjectUrl> <PackageProjectUrl>https://abp.io/</PackageProjectUrl>

3
docs/en/Community-Articles/2023-11-06-Blazor-Fullstack-Web-Ui/Post.md

@ -1,8 +1,5 @@
# Blazor's History and Full-stack Web UI # Blazor's History and Full-stack Web UI
![Cover Image](cover-image.png)
Blazor is a web framework that allows developers to build interactive web applications using .NET instead of JavaScript. The first version of Blazor was released on May 14, 2020. Since its initial release, Blazor has evolved with the new versions. Until now, six different versions have been declared. Sometimes, it can be not very clear to see the differences between these approaches. First, let's try to understand these. Blazor is a web framework that allows developers to build interactive web applications using .NET instead of JavaScript. The first version of Blazor was released on May 14, 2020. Since its initial release, Blazor has evolved with the new versions. Until now, six different versions have been declared. Sometimes, it can be not very clear to see the differences between these approaches. First, let's try to understand these.
* **Blazor-Server**: >> *Loads fast at first* >> In this version, heavy things are done in the server. Browsers are thin clients and download a small page for the first load. The page updates are done via SignalR connection. This was released with .NET Core 3. * **Blazor-Server**: >> *Loads fast at first* >> In this version, heavy things are done in the server. Browsers are thin clients and download a small page for the first load. The page updates are done via SignalR connection. This was released with .NET Core 3.

4
docs/en/Community-Articles/2024-01-15-Abp-Supports-NET8/Post.md

@ -1,5 +1,3 @@
![cover](cover.png)
# ABP Now Supports .NET 8 # ABP Now Supports .NET 8
Recently we have published ABP v8.0. With this version [the ABP Framework](https://github.com/abpframework/abp/blob/dev/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj#L6) and ABP Commercial both supports for .NET 8, aligning itself with the latest enhancements and new features of the ASP.NET's new version 8. Recently we have published ABP v8.0. With this version [the ABP Framework](https://github.com/abpframework/abp/blob/dev/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj#L6) and ABP Commercial both supports for .NET 8, aligning itself with the latest enhancements and new features of the ASP.NET's new version 8.
@ -170,4 +168,4 @@ Starting in .NET 8, C# Hot Reload [supports modifying generic types and generic
*References:* *References:*
* https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8 * https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8

6
docs/en/Community-Articles/2024-08-28-Understanding-AOT-vs-JIT/POST.md

@ -1,7 +1,3 @@
![book](images/cover.png)
Ahead-of-Time (AOT) compilation and Just-in-Time (JIT) compilation are two different methods for compiling Angular applications. Here's a breakdown of the differences between them: Ahead-of-Time (AOT) compilation and Just-in-Time (JIT) compilation are two different methods for compiling Angular applications. Here's a breakdown of the differences between them:
### **Ahead-of-Time (AOT) Compilation** ### **Ahead-of-Time (AOT) Compilation**
@ -61,4 +57,4 @@ Ahead-of-Time (AOT) compilation and Just-in-Time (JIT) compilation are two diffe
### **Best Practices:** ### **Best Practices:**
- **Use AOT** for production builds to ensure faster load times, smaller bundle sizes, and more secure applications. - **Use AOT** for production builds to ensure faster load times, smaller bundle sizes, and more secure applications.
- **Use JIT** during development to take advantage of quicker builds and easier debugging. - **Use JIT** during development to take advantage of quicker builds and easier debugging.

4
docs/en/Community-Articles/2024-08-29-What-is-Angular-Schematics/Post.md

@ -1,7 +1,5 @@
# What is Angular Schematics? # What is Angular Schematics?
![Cover Image](cover.png)
**Angular Schematics** is a powerful tool which is part of the Angular CLI that allows developers to automate various development tasks by **generating and modifying code**. Schematics provides a way to create **templates and boilerplate code** for Angular applications or libraries, enabling consistency and reducing the amount of repetitive work. **Angular Schematics** is a powerful tool which is part of the Angular CLI that allows developers to automate various development tasks by **generating and modifying code**. Schematics provides a way to create **templates and boilerplate code** for Angular applications or libraries, enabling consistency and reducing the amount of repetitive work.
### Key Concepts of Angular Schematics: ### Key Concepts of Angular Schematics:
@ -82,4 +80,4 @@ Here are the direct links for the Angular Schematics resources:
### Conclusion: ### Conclusion:
Angular Schematics is a powerful tool for automating repetitive tasks, generating consistent code, and managing project upgrades. By leveraging schematics, Angular developers can save time, reduce errors, and enforce best practices across their projects. Angular Schematics is a powerful tool for automating repetitive tasks, generating consistent code, and managing project upgrades. By leveraging schematics, Angular developers can save time, reduce errors, and enforce best practices across their projects.

2
docs/en/Community-Articles/2024-09-01-Do-You-Need-MultiTenancy/Post.md

@ -2,8 +2,6 @@
This article discusses whether you need a multi-tenancy architecture for your next project. Answer my critical questions to decide if multi-tenancy suits your application or not! This article discusses whether you need a multi-tenancy architecture for your next project. Answer my critical questions to decide if multi-tenancy suits your application or not!
![Cover image](cover.png)
## What’s Multi-tenancy? ## What’s Multi-tenancy?
It’s an architectural approach to building SaaS solutions. In this model, the hardware and software resources are shared between tenants, and application data is virtually or physically isolated between tenants. Here, **the main goal is minimizing costs and maximizing customer count**. It’s an architectural approach to building SaaS solutions. In this model, the hardware and software resources are shared between tenants, and application data is virtually or physically isolated between tenants. Here, **the main goal is minimizing costs and maximizing customer count**.

2
docs/en/Community-Articles/2024-09-18-Blazor-9-New-Features/post.md

@ -2,8 +2,6 @@
In this article, I'll highlight .NET 9's Blazor updates and important features for ASP.NET Core 9.0. These features are based on the latest .NET 9 Preview 7. In this article, I'll highlight .NET 9's Blazor updates and important features for ASP.NET Core 9.0. These features are based on the latest .NET 9 Preview 7.
![Cover](cover.png)
## .NET MAUI Blazor Hybrid App and Web App solution template ## .NET MAUI Blazor Hybrid App and Web App solution template
There's a new solution template to create .**NET MAUI native** and **Blazor web client** apps. This new template allows to choose a Blazor interactive render mode, it uses a shared Razor class library to maintain the UI's Razor components. There's a new solution template to create .**NET MAUI native** and **Blazor web client** apps. This new template allows to choose a Blazor interactive render mode, it uses a shared Razor class library to maintain the UI's Razor components.

4
docs/en/Community-Articles/2024-09-24-Angular-Difference-Btw-Promise-Observable/post.md

@ -2,10 +2,6 @@
In this article, I will mention the differences between `Promise` and `Observable` . They are used in TypeScript (Angular) for handling async operations but have different use cases and behaviors. Let's see these six differences... In this article, I will mention the differences between `Promise` and `Observable` . They are used in TypeScript (Angular) for handling async operations but have different use cases and behaviors. Let's see these six differences...
![Cover](cover.png)
## 1. Eager or Lazy Evaluation ## 1. Eager or Lazy Evaluation
- **Promise**: A `promise` is **eager**! This means that as soon as a `promise` is created, it executes the operation, like initiating immediately an HTTP request. **You can't control the execution start time; it begins right away!** - **Promise**: A `promise` is **eager**! This means that as soon as a `promise` is created, it executes the operation, like initiating immediately an HTTP request. **You can't control the execution start time; it begins right away!**

5
docs/en/Community-Articles/2024-10-01-SignalR-9-New-Features/Post.md

@ -1,11 +1,6 @@
### ASP.NET Core SignalR New Features — Summary ### ASP.NET Core SignalR New Features — Summary
In this article, I’ll highlight the latest .**NET 9 SignalR updates** for ASP.NET Core 9.0. In this article, I’ll highlight the latest .**NET 9 SignalR updates** for ASP.NET Core 9.0.
![Cover](cover.png)
### SignalR Hub Accepts Base Classes ### SignalR Hub Accepts Base Classes
SignalR `Hub` class can now get a base class of a polymorphic class. As you see in the example below, I can send `Animal` to `Process` method. Before .NET 9, we could only pass the derived classes: `Cat` and `Dog`. SignalR `Hub` class can now get a base class of a polymorphic class. As you see in the example below, I can send `Animal` to `Process` method. Before .NET 9, we could only pass the derived classes: `Cat` and `Dog`.

6
docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/Post.md

@ -1,9 +1,5 @@
# When to Use Cookies, When to Use Local Storage? # When to Use Cookies, When to Use Local Storage?
![cover](cover.png)
## Cookies vs Local Storage ## Cookies vs Local Storage
When you want to save client-side data on browsers, you can use `Cookies` or `Local Storage` of the browser. While these methods look similar, they have different behaviors. You need to decide based on the specific use-case, security concerns and the data size being stored. I'll clarify the differences between these methods. When you want to save client-side data on browsers, you can use `Cookies` or `Local Storage` of the browser. While these methods look similar, they have different behaviors. You need to decide based on the specific use-case, security concerns and the data size being stored. I'll clarify the differences between these methods.
@ -60,4 +56,4 @@ When you want to save client-side data on browsers, you can use `Cookies` or `Lo
In many cases, you might use both cookies and local storage, depending on the specific requirements of different parts of your application. There are also other places where you can store the client-side data. You can check out [this article](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage) for more information. In many cases, you might use both cookies and local storage, depending on the specific requirements of different parts of your application. There are also other places where you can store the client-side data. You can check out [this article](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage) for more information.
Happy coding 🧑🏽‍💻 Happy coding 🧑🏽‍💻

2
docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/Post.md

@ -2,8 +2,6 @@
With every release, .NET becomes faster & faster! You get these improvements for free by just updating your project to the latest .NET! With every release, .NET becomes faster & faster! You get these improvements for free by just updating your project to the latest .NET!
![Cover Image](cover.png)
It’s very interesting that **20% of these improvements** are implemented by **open-source volunteers** rather than Microsoft employees. These improvements mostly focus on cloud-native and high-throughput applications. I’ll briefly list them below. It’s very interesting that **20% of these improvements** are implemented by **open-source volunteers** rather than Microsoft employees. These improvements mostly focus on cloud-native and high-throughput applications. I’ll briefly list them below.
![From Microsoft Blog Post](cited-from-microsoft-blog-post.png) ![From Microsoft Blog Post](cited-from-microsoft-blog-post.png)

2
docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/POST.md

@ -2,8 +2,6 @@
In this article, I will compare [.NET Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/) by [ABP Studio](https://abp.io/docs/latest/studio) by explaining their similarities and differences. In this article, I will compare [.NET Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/) by [ABP Studio](https://abp.io/docs/latest/studio) by explaining their similarities and differences.
![cover](cover.png)
## Introduction ## Introduction
While .NET Aspire and ABP Studio are tools for different purpose with different scope and they have different approaches to solve the problems, many developers still may confuse since they also have some similar functionalities and solves some common problems. While .NET Aspire and ABP Studio are tools for different purpose with different scope and they have different approaches to solve the problems, many developers still may confuse since they also have some similar functionalities and solves some common problems.

4
docs/en/Community-Articles/2024-10-23-Abp-Net9-Upgrade/post.md

@ -1,9 +1,5 @@
# ABP Now Supports .NET 9 # ABP Now Supports .NET 9
![Cover image](cover.png)
**.NET 9.0.100-rc.2** has been released on **October 8, 2024**. To align with the latest .NET, we also released the ABP Platform [9.0.0-rc.1](https://github.com/abpframework/abp/releases/tag/9.0.0-rc.1) version. **.NET 9.0.100-rc.2** has been released on **October 8, 2024**. To align with the latest .NET, we also released the ABP Platform [9.0.0-rc.1](https://github.com/abpframework/abp/releases/tag/9.0.0-rc.1) version.
**With this release, ABP now supports .NET 9.** **With this release, ABP now supports .NET 9.**

2
docs/en/Community-Articles/2024-11-13-BuiltIn-OpenApi-Documentation/post.md

@ -1,8 +1,6 @@
Built-in OpenAPI Document Generation with .NET 9 — No more SwaggerUI! 👋 Built-in OpenAPI Document Generation with .NET 9 — No more SwaggerUI! 👋
======================================================================== ========================================================================
![Cover](cover.png)
What’s Swagger UI? What’s Swagger UI?
------------------ ------------------

4
docs/en/Community-Articles/2024-12-01-OpenAI-Integration/POST.md

@ -2,8 +2,6 @@
In this article, I will show you how to integrate and use the [OpenAI API](https://github.com/openai/openai-dotnet?tab=readme-ov-file#getting-started) with the [ABP Framework](https://abp.io/). We will explore step-by-step how these technologies can work together to enhance your application with powerful AI capabilities, such as natural language processing, image generation, and more. In this article, I will show you how to integrate and use the [OpenAI API](https://github.com/openai/openai-dotnet?tab=readme-ov-file#getting-started) with the [ABP Framework](https://abp.io/). We will explore step-by-step how these technologies can work together to enhance your application with powerful AI capabilities, such as natural language processing, image generation, and more.
![cover-image](cover-image.png)
## Creating an ABP Project ## Creating an ABP Project
To begin integrating OpenAI API with ABP Framework, you first need to create an ABP project. Follow these steps to create and set up your ABP project: To begin integrating OpenAI API with ABP Framework, you first need to create an ABP project. Follow these steps to create and set up your ABP project:
@ -384,4 +382,4 @@ To showcase the integration of the OpenAI API with the ABP Framework, we impleme
## Conclusion ## Conclusion
In this article, we covered how to integrate the OpenAI API with the ABP Framework by creating a sample project, setting up the OpenAI services, and implementing examples for conversational AI, knowledge-based assistance, and image generation. By following these steps, you can add powerful AI-driven capabilities to your application, making it more interactive, intelligent, and capable of meeting user needs effectively. In this article, we covered how to integrate the OpenAI API with the ABP Framework by creating a sample project, setting up the OpenAI services, and implementing examples for conversational AI, knowledge-based assistance, and image generation. By following these steps, you can add powerful AI-driven capabilities to your application, making it more interactive, intelligent, and capable of meeting user needs effectively.

2
docs/en/Community-Articles/2025-01-03-ABP-Background-Workers-vs-Jobs/background-jobs-vs-background-workers.md

@ -1,7 +1,5 @@
# ABP Framework: Background Jobs vs Background Workers — When to Use Which? # ABP Framework: Background Jobs vs Background Workers — When to Use Which?
![cover](cover.png)
In the ABP Framework, **Background Jobs** and **Background Workers** serve different purposes but can sometimes seem interchangeable. Sometimes it can be confusing. Let’s clarify their differences, and I'll show you some real-world cases to help you understand how to decide between these two. We have official documents for these: In the ABP Framework, **Background Jobs** and **Background Workers** serve different purposes but can sometimes seem interchangeable. Sometimes it can be confusing. Let’s clarify their differences, and I'll show you some real-world cases to help you understand how to decide between these two. We have official documents for these:
📕 **Background Workers ABP Document** https://abp.io/docs/latest/framework/infrastructure/background-workers 📕 **Background Workers ABP Document** https://abp.io/docs/latest/framework/infrastructure/background-workers

2
docs/en/Community-Articles/2025-01-24-Understanding-Transactions-in-ABP-Unit-Of-Work/POST.md

@ -2,8 +2,6 @@
[The Unit of Work](https://en.wikipedia.org/wiki/Unit_of_work) is a software design pattern that maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems to ensure that all changes are made within a single transaction. [The Unit of Work](https://en.wikipedia.org/wiki/Unit_of_work) is a software design pattern that maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems to ensure that all changes are made within a single transaction.
![pic](./pic.png)
## Transaction Management Overview ## Transaction Management Overview
One of the primary responsibilities of the Unit of Work is managing database transactions. It provides the following transaction management features: One of the primary responsibilities of the Unit of Work is managing database transactions. It provides the following transaction management features:

66
docs/en/docs-nav.json

@ -487,7 +487,8 @@
}, },
{ {
"text": "Exception Handling", "text": "Exception Handling",
"path": "framework/fundamentals/exception-handling.md" "path": "framework/fundamentals/exception-handling.md",
"keywords": ["Error"]
}, },
{ {
"text": "Localization", "text": "Localization",
@ -1974,7 +1975,68 @@
}, },
{ {
"text": "Single-Layer Solution", "text": "Single-Layer Solution",
"path": "solution-templates/single-layer-web-application" "isLazyExpandable": true,
"path": "solution-templates/single-layer-web-application",
"items": [
{
"text": "Overview",
"path": "solution-templates/single-layer-web-application/overview.md"
},
{
"text": "Solution Structure",
"path": "solution-templates/single-layer-web-application/solution-structure.md"
},
{
"text": "Main Components",
"isLazyExpandable": true,
"path": "solution-templates/single-layer-web-application/main-components.md",
"items": [
{
"text": "Web Applications",
"path": "solution-templates/single-layer-web-application/web-applications.md"
},
{
"text": "Db Migrator",
"path": "solution-templates/single-layer-web-application/db-migrator.md"
}
]
},
{
"text": "Built-In Features",
"isLazyExpandable": true,
"path": "solution-templates/single-layer-web-application/built-in-features.md",
"items": [
{
"text": "Authentication",
"path": "solution-templates/single-layer-web-application/authentication.md"
},
{
"text": "Database configurations",
"path": "solution-templates/single-layer-web-application/database-configurations.md"
},
{
"text": "Logging (with Serilog)",
"path": "solution-templates/single-layer-web-application/logging.md"
},
{
"text": "Swagger integration",
"path": "solution-templates/single-layer-web-application/swagger-integration.md"
},
{
"text": "Multi-Tenancy",
"path": "solution-templates/single-layer-web-application/multi-tenancy.md"
},
{
"text": "BLOB Storing",
"path": "solution-templates/single-layer-web-application/blob-storing.md"
},
{
"text": "CORS configuration",
"path": "solution-templates/single-layer-web-application/cors-configuration.md"
}
]
}
]
}, },
{ {
"text": "Layered Solution", "text": "Layered Solution",

12
docs/en/solution-templates/layered-web-application/deployment/azure-deployment/step3-deployment-github-action.md

@ -49,7 +49,7 @@ jobs:
- name: Set up .NET Core - name: Set up .NET Core
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: '8.x' dotnet-version: '9.x'
include-prerelease: true include-prerelease: true
- name: Install ABP CLI - name: Install ABP CLI
@ -150,7 +150,7 @@ jobs:
- name: Set up .NET Core - name: Set up .NET Core
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: '8.x' dotnet-version: '9.x'
include-prerelease: true include-prerelease: true
- name: Install ABP CLI - name: Install ABP CLI
@ -250,7 +250,7 @@ jobs:
- name: Set up .NET Core - name: Set up .NET Core
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: '8.x' dotnet-version: '9.x'
include-prerelease: true include-prerelease: true
- name: Install ABP CLI - name: Install ABP CLI
@ -355,7 +355,7 @@ jobs:
- name: Set up .NET Core - name: Set up .NET Core
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: '8.x' dotnet-version: '9.x'
include-prerelease: true include-prerelease: true
- name: Install ABP CLI - name: Install ABP CLI
@ -489,7 +489,7 @@ build:
- name: Set up .NET Core - name: Set up .NET Core
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: '8.x' dotnet-version: '9.x'
include-prerelease: true include-prerelease: true
- name: Install ABP CLI - name: Install ABP CLI
@ -569,7 +569,7 @@ jobs:
- name: Set up .NET Core - name: Set up .NET Core
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: '8.x' dotnet-version: '9.x'
include-prerelease: true include-prerelease: true
- name: Install ABP CLI - name: Install ABP CLI

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/ar.json

@ -78,6 +78,7 @@
"EndDate": "تاريخ الانتهاء", "EndDate": "تاريخ الانتهاء",
"Feature:AuditLoggingGroup": "تدوين التسجيل", "Feature:AuditLoggingGroup": "تدوين التسجيل",
"Feature:AuditLoggingEnable": "تمكين صفحة تسجيل التدقيق", "Feature:AuditLoggingEnable": "تمكين صفحة تسجيل التدقيق",
"Feature:AuditLoggingEnableDescription": "تفعيل صفحة تسجيل التدقيق في التطبيق." "Feature:AuditLoggingEnableDescription": "تفعيل صفحة تسجيل التدقيق في التطبيق.",
"TenantId": "معرف المستأجر"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/cs.json

@ -78,6 +78,7 @@
"EndDate": "Datum ukončení", "EndDate": "Datum ukončení",
"Feature:AuditLoggingGroup": "Protokolování auditu", "Feature:AuditLoggingGroup": "Protokolování auditu",
"Feature:AuditLoggingEnable": "Povolena stránka protokolování auditu", "Feature:AuditLoggingEnable": "Povolena stránka protokolování auditu",
"Feature:AuditLoggingEnableDescription": "Povolit stránku protokolování auditu v aplikaci." "Feature:AuditLoggingEnableDescription": "Povolit stránku protokolování auditu v aplikaci.",
"TenantId": "ID nájemce"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/de-DE.json

@ -77,6 +77,7 @@
"EndDate": "Endtermin", "EndDate": "Endtermin",
"Feature:AuditLoggingGroup": "Audit-Protokollierung", "Feature:AuditLoggingGroup": "Audit-Protokollierung",
"Feature:AuditLoggingEnable": "Aktivieren Sie die Überwachungsprotokollseite", "Feature:AuditLoggingEnable": "Aktivieren Sie die Überwachungsprotokollseite",
"Feature:AuditLoggingEnableDescription": "Aktivieren Sie die Überwachungsprotokollseite in der App." "Feature:AuditLoggingEnableDescription": "Aktivieren Sie die Überwachungsprotokollseite in der App.",
"TenantId": "Mandanten-ID"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/de.json

@ -78,6 +78,7 @@
"EndDate": "Endtermin", "EndDate": "Endtermin",
"Feature:AuditLoggingGroup": "Audit-Protokollierung", "Feature:AuditLoggingGroup": "Audit-Protokollierung",
"Feature:AuditLoggingEnable": "Aktivierte Audit-Logging-Seite", "Feature:AuditLoggingEnable": "Aktivierte Audit-Logging-Seite",
"Feature:AuditLoggingEnableDescription": "Aktivieren Sie die Audit-Logging-Seite in der Anwendung." "Feature:AuditLoggingEnableDescription": "Aktivieren Sie die Audit-Logging-Seite in der Anwendung.",
"TenantId": "Mandanten-ID"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/en.json

@ -93,6 +93,7 @@
"DisplayName:ExpiredDeleterPeriod": "Expired item deletion period", "DisplayName:ExpiredDeleterPeriod": "Expired item deletion period",
"Description:ExpiredDeleterPeriod": "Set the number of days after which expired items will be automatically deleted.", "Description:ExpiredDeleterPeriod": "Set the number of days after which expired items will be automatically deleted.",
"ExpiredDeleterPeriodUnit": "day(s)", "ExpiredDeleterPeriodUnit": "day(s)",
"AuditLogsBeforeXWillBeDeleted": "Audit logs before {0} will be deleted." "AuditLogsBeforeXWillBeDeleted": "Audit logs before {0} will be deleted.",
"TenantId": "Tenant Id"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/es.json

@ -78,6 +78,7 @@
"EndDate": "Fecha final", "EndDate": "Fecha final",
"Feature:AuditLoggingGroup": "Registros de auditoría", "Feature:AuditLoggingGroup": "Registros de auditoría",
"Feature:AuditLoggingEnable": "Habilitar la página de registro de auditoría", "Feature:AuditLoggingEnable": "Habilitar la página de registro de auditoría",
"Feature:AuditLoggingEnableDescription": "Habilite la página de registro de auditoría en la aplicación." "Feature:AuditLoggingEnableDescription": "Habilite la página de registro de auditoría en la aplicación.",
"TenantId": "ID de inquilino"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/fi.json

@ -78,6 +78,7 @@
"EndDate": "Päättymispäivä", "EndDate": "Päättymispäivä",
"Feature:AuditLoggingGroup": "Tarkastusten kirjaaminen", "Feature:AuditLoggingGroup": "Tarkastusten kirjaaminen",
"Feature:AuditLoggingEnable": "Aktivoi auditointilokisivu", "Feature:AuditLoggingEnable": "Aktivoi auditointilokisivu",
"Feature:AuditLoggingEnableDescription": "Ota käyttöön tarkastuksen kirjaussivu sovelluksessa." "Feature:AuditLoggingEnableDescription": "Ota käyttöön tarkastuksen kirjaussivu sovelluksessa.",
"TenantId": "Vuokralaisen tunnus"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/fr.json

@ -78,6 +78,7 @@
"EndDate": "Date de fin", "EndDate": "Date de fin",
"Feature:AuditLoggingGroup": "Journalisation d'audit", "Feature:AuditLoggingGroup": "Journalisation d'audit",
"Feature:AuditLoggingEnable": "Page de journalisation d'audit activée", "Feature:AuditLoggingEnable": "Page de journalisation d'audit activée",
"Feature:AuditLoggingEnableDescription": "Activez la page de journalisation d'audit dans l'application." "Feature:AuditLoggingEnableDescription": "Activez la page de journalisation d'audit dans l'application.",
"TenantId": "ID du locataire"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/hi.json

@ -78,6 +78,7 @@
"EndDate": "समाप्ति तिथि", "EndDate": "समाप्ति तिथि",
"Feature:AuditLoggingGroup": "ऑडिट लॉगिंग", "Feature:AuditLoggingGroup": "ऑडिट लॉगिंग",
"Feature:AuditLoggingEnable": "सक्षम ऑडिट लॉगिंग पृष्ठ", "Feature:AuditLoggingEnable": "सक्षम ऑडिट लॉगिंग पृष्ठ",
"Feature:AuditLoggingEnableDescription": "एप्लिकेशन में ऑडिट लॉगिंग पृष्ठ सक्षम करें।" "Feature:AuditLoggingEnableDescription": "एप्लिकेशन में ऑडिट लॉगिंग पृष्ठ सक्षम करें।",
"TenantId": "किरायेदार आईडी"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/hr.json

@ -78,6 +78,7 @@
"EndDate": "Datum završetka", "EndDate": "Datum završetka",
"Feature:AuditLoggingGroup": "Zapisivanje revizije", "Feature:AuditLoggingGroup": "Zapisivanje revizije",
"Feature:AuditLoggingEnable": "Omogućena stranica za bilježenje revizije", "Feature:AuditLoggingEnable": "Omogućena stranica za bilježenje revizije",
"Feature:AuditLoggingEnableDescription": "Omogućite stranicu za bilježenje revizije u aplikaciji." "Feature:AuditLoggingEnableDescription": "Omogućite stranicu za bilježenje revizije u aplikaciji.",
"TenantId": "ID stanara"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/hu.json

@ -78,6 +78,7 @@
"EndDate": "Befejezés dátuma", "EndDate": "Befejezés dátuma",
"Feature:AuditLoggingGroup": "Audit naplózás", "Feature:AuditLoggingGroup": "Audit naplózás",
"Feature:AuditLoggingEnable": "Engedélyezett naplózási oldal", "Feature:AuditLoggingEnable": "Engedélyezett naplózási oldal",
"Feature:AuditLoggingEnableDescription": "Engedélyezze a naplózási oldalt az alkalmazásban." "Feature:AuditLoggingEnableDescription": "Engedélyezze a naplózási oldalt az alkalmazásban.",
"TenantId": "Bérlő azonosító"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/is.json

@ -78,6 +78,7 @@
"EndDate": "Loka dagsetning", "EndDate": "Loka dagsetning",
"Feature:AuditLoggingGroup": "Endurskoðunarskráning", "Feature:AuditLoggingGroup": "Endurskoðunarskráning",
"Feature:AuditLoggingEnable": "Virkjað endurskoðunarskráningarsíða", "Feature:AuditLoggingEnable": "Virkjað endurskoðunarskráningarsíða",
"Feature:AuditLoggingEnableDescription": "Virkjaðu endurskoðunarskráningarsíðu í forritinu." "Feature:AuditLoggingEnableDescription": "Virkjaðu endurskoðunarskráningarsíðu í forritinu.",
"TenantId": "Leigutakaauðkenni"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/it.json

@ -78,6 +78,7 @@
"EndDate": "Data di fine", "EndDate": "Data di fine",
"Feature:AuditLoggingGroup": "Registrazione di controllo", "Feature:AuditLoggingGroup": "Registrazione di controllo",
"Feature:AuditLoggingEnable": "Pagina di registrazione di controllo abilitata", "Feature:AuditLoggingEnable": "Pagina di registrazione di controllo abilitata",
"Feature:AuditLoggingEnableDescription": "Abilita la pagina di registrazione dell'audit nell'applicazione." "Feature:AuditLoggingEnableDescription": "Abilita la pagina di registrazione dell'audit nell'applicazione.",
"TenantId": "ID inquilino"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/nl.json

@ -78,6 +78,7 @@
"EndDate": "Einddatum", "EndDate": "Einddatum",
"Feature:AuditLoggingGroup": "Auditregistratie", "Feature:AuditLoggingGroup": "Auditregistratie",
"Feature:AuditLoggingEnable": "Pagina voor auditregistratie ingeschakeld", "Feature:AuditLoggingEnable": "Pagina voor auditregistratie ingeschakeld",
"Feature:AuditLoggingEnableDescription": "Schakel de auditlogboekpagina in de applicatie in." "Feature:AuditLoggingEnableDescription": "Schakel de auditlogboekpagina in de applicatie in.",
"TenantId": "Huurder-ID"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/pl-PL.json

@ -78,6 +78,7 @@
"EndDate": "Data końcowa", "EndDate": "Data końcowa",
"Feature:AuditLoggingGroup": "Rejestrowanie audytu", "Feature:AuditLoggingGroup": "Rejestrowanie audytu",
"Feature:AuditLoggingEnable": "Włączono stronę rejestrowania audytu", "Feature:AuditLoggingEnable": "Włączono stronę rejestrowania audytu",
"Feature:AuditLoggingEnableDescription": "Włącz stronę rejestrowania audytu w aplikacji." "Feature:AuditLoggingEnableDescription": "Włącz stronę rejestrowania audytu w aplikacji.",
"TenantId": "Identyfikator najemcy"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/pt-BR.json

@ -78,6 +78,7 @@
"EndDate": "Data final", "EndDate": "Data final",
"Feature:AuditLoggingGroup": "Registro de auditoria", "Feature:AuditLoggingGroup": "Registro de auditoria",
"Feature:AuditLoggingEnable": "Página de registro de auditoria habilitada", "Feature:AuditLoggingEnable": "Página de registro de auditoria habilitada",
"Feature:AuditLoggingEnableDescription": "Habilite a página de registro de auditoria no aplicativo." "Feature:AuditLoggingEnableDescription": "Habilite a página de registro de auditoria no aplicativo.",
"TenantId": "ID do inquilino"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/ro-RO.json

@ -78,6 +78,7 @@
"EndDate": "Data de încheiere", "EndDate": "Data de încheiere",
"Feature:AuditLoggingGroup": "Înregistrare de audit", "Feature:AuditLoggingGroup": "Înregistrare de audit",
"Feature:AuditLoggingEnable": "Pagina de înregistrare a auditului activată", "Feature:AuditLoggingEnable": "Pagina de înregistrare a auditului activată",
"Feature:AuditLoggingEnableDescription": "Activați pagina de înregistrare a auditului în aplicație." "Feature:AuditLoggingEnableDescription": "Activați pagina de înregistrare a auditului în aplicație.",
"TenantId": "ID chiriaș"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/ru.json

@ -78,6 +78,7 @@
"EndDate": "Дата окончания", "EndDate": "Дата окончания",
"Feature:AuditLoggingGroup": "Ведение журнала аудита", "Feature:AuditLoggingGroup": "Ведение журнала аудита",
"Feature:AuditLoggingEnable": "Включенная страница ведения журнала аудита", "Feature:AuditLoggingEnable": "Включенная страница ведения журнала аудита",
"Feature:AuditLoggingEnableDescription": "Включить страницу ведения журнала аудита в приложении." "Feature:AuditLoggingEnableDescription": "Включить страницу ведения журнала аудита в приложении.",
"TenantId": "Идентификатор арендатора"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/sk.json

@ -78,6 +78,7 @@
"EndDate": "Dátum konca", "EndDate": "Dátum konca",
"Feature:AuditLoggingGroup": "Audit logovanie", "Feature:AuditLoggingGroup": "Audit logovanie",
"Feature:AuditLoggingEnable": "Povoliť stránku audit logovania", "Feature:AuditLoggingEnable": "Povoliť stránku audit logovania",
"Feature:AuditLoggingEnableDescription": "Povolená stránka audit logovania v aplikácii." "Feature:AuditLoggingEnableDescription": "Povolená stránka audit logovania v aplikácii.",
"TenantId": "ID nájomníka"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/sl.json

@ -78,6 +78,7 @@
"EndDate": "Končni datum", "EndDate": "Končni datum",
"Feature:AuditLoggingGroup": "Revizijsko beleženje", "Feature:AuditLoggingGroup": "Revizijsko beleženje",
"Feature:AuditLoggingEnable": "Omogočena stran za beleženje revizije", "Feature:AuditLoggingEnable": "Omogočena stran za beleženje revizije",
"Feature:AuditLoggingEnableDescription": "Omogočite stran za beleženje revizije v aplikaciji." "Feature:AuditLoggingEnableDescription": "Omogočite stran za beleženje revizije v aplikaciji.",
"TenantId": "ID najemnika"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/sv.json

@ -93,6 +93,7 @@
"DisplayName:ExpiredDeleterPeriod": "Utgången raderingsperiod för objekt", "DisplayName:ExpiredDeleterPeriod": "Utgången raderingsperiod för objekt",
"Description:ExpiredDeleterPeriod": "Ställ in antalet dagar efter vilka utgångna objekt automatiskt ska raderas.", "Description:ExpiredDeleterPeriod": "Ställ in antalet dagar efter vilka utgångna objekt automatiskt ska raderas.",
"ExpiredDeleterPeriodUnit": "dag(ar)", "ExpiredDeleterPeriodUnit": "dag(ar)",
"AuditLogsBeforeXWillBeDeleted": "Granskningsloggar före {0} kommer att raderas." "AuditLogsBeforeXWillBeDeleted": "Granskningsloggar före {0} kommer att raderas.",
"TenantId": "Hyresgäst-ID"
} }
} }

5
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/tr.json

@ -46,7 +46,7 @@
"Date": "Tarih", "Date": "Tarih",
"Url": "Url", "Url": "Url",
"UserName": "Kullanıcı adı", "UserName": "Kullanıcı adı",
"TenantImpersonator": "Kiracı Taklitçisi", "TenantImpersonator": "Müşteri Taklitçisi",
"UserImpersonator": "Kullanıcı Taklitçisi", "UserImpersonator": "Kullanıcı Taklitçisi",
"UrlFilter": "Url Filtresi", "UrlFilter": "Url Filtresi",
"User": "Kullanıcı", "User": "Kullanıcı",
@ -78,6 +78,7 @@
"Feature:AuditLoggingGroup": "İşlem Kayıtları", "Feature:AuditLoggingGroup": "İşlem Kayıtları",
"Feature:AuditLoggingEnable": "İşlem kayıtları sayfasını etkinleştirin", "Feature:AuditLoggingEnable": "İşlem kayıtları sayfasını etkinleştirin",
"Feature:AuditLoggingEnableDescription": "Uygulamadanızdaki işlem kayıtları sayfasını etkinleştirir.", "Feature:AuditLoggingEnableDescription": "Uygulamadanızdaki işlem kayıtları sayfasını etkinleştirir.",
"MinMaxDuration": "Süre (Min. - Max.)" "MinMaxDuration": "Süre (Min. - Max.)",
"TenantId": "Müşteri Id"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/vi.json

@ -78,6 +78,7 @@
"EndDate": "Ngày cuối", "EndDate": "Ngày cuối",
"Feature:AuditLoggingGroup": "Ghi nhật ký kiểm tra", "Feature:AuditLoggingGroup": "Ghi nhật ký kiểm tra",
"Feature:AuditLoggingEnable": "Đã bật trang ghi nhật ký kiểm tra", "Feature:AuditLoggingEnable": "Đã bật trang ghi nhật ký kiểm tra",
"Feature:AuditLoggingEnableDescription": "Kích hoạt trang ghi nhật ký kiểm tra trong ứng dụng." "Feature:AuditLoggingEnableDescription": "Kích hoạt trang ghi nhật ký kiểm tra trong ứng dụng.",
"TenantId": "ID người thuê"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hans.json

@ -78,6 +78,7 @@
"EndDate": "结束日期", "EndDate": "结束日期",
"Feature:AuditLoggingGroup": "审计日志", "Feature:AuditLoggingGroup": "审计日志",
"Feature:AuditLoggingEnable": "启用审计记录页面", "Feature:AuditLoggingEnable": "启用审计记录页面",
"Feature:AuditLoggingEnableDescription": "在应用程序中启用审计日志页面。" "Feature:AuditLoggingEnableDescription": "在应用程序中启用审计日志页面。",
"TenantId": "租户 ID"
} }
} }

3
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hant.json

@ -78,6 +78,7 @@
"EndDate": "結束時間", "EndDate": "結束時間",
"Feature:AuditLoggingGroup": "審計日誌", "Feature:AuditLoggingGroup": "審計日誌",
"Feature:AuditLoggingEnable": "啟用審計日誌頁面", "Feature:AuditLoggingEnable": "啟用審計日誌頁面",
"Feature:AuditLoggingEnableDescription": "在應用程序中啟用審計日誌頁面." "Feature:AuditLoggingEnableDescription": "在應用程序中啟用審計日誌頁面.",
"TenantId": "租戶 ID"
} }
} }

3
modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs

@ -21,6 +21,9 @@ namespace Volo.Docs.Documents
[JsonPropertyName("isIndex")] [JsonPropertyName("isIndex")]
public bool IsIndex { get; set; } public bool IsIndex { get; set; }
[JsonPropertyName("keywords")]
public string[] Keywords { get; set; }
public bool IsLeaf => !HasChildItems; public bool IsLeaf => !HasChildItems;

6
modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.AspNetCore.Razor.TagHelpers;
@ -23,7 +24,7 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
private const string LiItemTemplateWithLink = @"<li class='{0}'><span class='plus-icon'><i class='fa fa-{1}'></i></span>{2}{3}</li>"; private const string LiItemTemplateWithLink = @"<li class='{0}'><span class='plus-icon'><i class='fa fa-{1}'></i></span>{2}{3}</li>";
private const string ListItemAnchor = @"<a href='{0}' class='{1}'>{2}</a>"; private const string ListItemAnchor = @"<a href='{0}' {1} class='{2}'>{3}</a>";
private const string ListItemSpan = @"<span class='{0}'>{1}</span>"; private const string ListItemSpan = @"<span class='{0}'>{1}</span>";
@ -155,7 +156,8 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
sb.Clear(); sb.Clear();
listInnerItem = string.Format(ListItemAnchor, NormalizePath(node.Path), textCss, var additionalAttributes = node.Keywords.IsNullOrEmpty() ? "" : "data-keywords=\"" + node.Keywords.JoinAsString(",") + "\"";
listInnerItem = string.Format(ListItemAnchor, NormalizePath(node.Path), additionalAttributes ,textCss,
node.Text.IsNullOrEmpty() node.Text.IsNullOrEmpty()
? "?" ? "?"
: sb.Append(node.Text).Append(badgeStringBuilder.ToString()).ToString()); : sb.Append(node.Text).Append(badgeStringBuilder.ToString()).ToString());

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

@ -29,7 +29,8 @@ var doc = doc || {};
var $ul = $(`<ul class="nav nav-list tree" ${uiCss}></ul>`); var $ul = $(`<ul class="nav nav-list tree" ${uiCss}></ul>`);
var $li = $(`<li class="${node.hasChildItems ? 'nav-header' : 'last-link'}"></li>`); var $li = $(`<li class="${node.hasChildItems ? 'nav-header' : 'last-link'}"></li>`);
$li.append(`<span class="plus-icon"> <i class="fa fa-${node.hasChildItems ? 'chevron-right' : node.path === "javascript:;" ? 'has-link' : 'no-link'}"></i></span><a href="${node.path}" class="${textCss}">${node.text}</a>`) var dataKeywords = node.keywords ? `data-keywords="${node.keywords}"` : "";
$li.append(`<span class="plus-icon"> <i class="fa fa-${node.hasChildItems ? 'chevron-right' : node.path === "javascript:;" ? 'has-link' : 'no-link'}"></i></span><a href="${node.path}" ${dataKeywords} class="${textCss}">${node.text}</a>`)
if(node.isLazyExpandable){ if(node.isLazyExpandable){
$li.addClass("lazy-expand"); $li.addClass("lazy-expand");
@ -111,12 +112,17 @@ var doc = doc || {};
var filteredItems = $navigation var filteredItems = $navigation
.find('li > a') .find('li > a')
.filter(function () { .filter(function () {
return ( var keywords = ($(this).data('keywords') || "").split(",");
$(this) var text = $(this).text();
.text()
.toUpperCase() if(text.toUpperCase().indexOf(filterText.toUpperCase()) > -1)
.indexOf(filterText.toUpperCase()) > -1 {
); return true;
}
return keywords.some(function(keyword){
return keyword.toUpperCase().indexOf(filterText.toUpperCase()) > -1;
});
}); });
filteredItems.each(function () { filteredItems.each(function () {

30
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs

@ -128,21 +128,29 @@ public class AbpResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
} }
else if (result.IsNotAllowed) else if (result.IsNotAllowed)
{ {
Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName); if (!await UserManager.CheckPasswordAsync(user, context.Password))
if (user.ShouldChangePasswordOnNextLogin)
{ {
await HandleShouldChangePasswordOnNextLoginAsync(context, user, context.Password); Logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName);
return; errorDescription = Localizer["InvalidUserNameOrPassword"];
} }
else
if (await UserManager.ShouldPeriodicallyChangePasswordAsync(user))
{ {
await HandlePeriodicallyChangePasswordAsync(context, user, context.Password); Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName);
return;
}
errorDescription = Localizer["LoginIsNotAllowed"]; if (user.ShouldChangePasswordOnNextLogin)
{
await HandleShouldChangePasswordOnNextLoginAsync(context, user, context.Password);
return;
}
if (await UserManager.ShouldPeriodicallyChangePasswordAsync(user))
{
await HandlePeriodicallyChangePasswordAsync(context, user, context.Password);
return;
}
errorDescription = Localizer["LoginIsNotAllowed"];
}
} }
else else
{ {

34
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.Password.cs

@ -115,24 +115,32 @@ public partial class TokenController
} }
else if (result.IsNotAllowed) else if (result.IsNotAllowed)
{ {
Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", request.Username); if (!await UserManager.CheckPasswordAsync(user, request.Password))
if (user.ShouldChangePasswordOnNextLogin)
{ {
return await HandleShouldChangePasswordOnNextLoginAsync(request, user, request.Password); Logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", request.Username);
errorDescription = "Invalid username or password!";
} }
else
if (await UserManager.ShouldPeriodicallyChangePasswordAsync(user))
{ {
return await HandlePeriodicallyChangePasswordAsync(request, user, request.Password); Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", request.Username);
}
if (user.IsActive) if (user.ShouldChangePasswordOnNextLogin)
{ {
return await HandleConfirmUserAsync(request, user); return await HandleShouldChangePasswordOnNextLoginAsync(request, user, request.Password);
} }
errorDescription = "You are not allowed to login! Your account is inactive."; if (await UserManager.ShouldPeriodicallyChangePasswordAsync(user))
{
return await HandlePeriodicallyChangePasswordAsync(request, user, request.Password);
}
if (user.IsActive)
{
return await HandleConfirmUserAsync(request, user);
}
errorDescription = "You are not allowed to login! Your account is inactive.";
}
} }
else else
{ {

10
npm/ng-packs/packages/core/src/lib/services/local-storage-listener.service.ts

@ -1,6 +1,5 @@
import { DOCUMENT } from '@angular/common'; import { DOCUMENT } from '@angular/common';
import { Injectable, inject } from '@angular/core'; import { Injectable, inject } from '@angular/core';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
@ -9,8 +8,13 @@ export class LocalStorageListenerService {
constructor() { constructor() {
this.window.addEventListener('storage', event => { this.window.addEventListener('storage', event => {
if (event.key === 'access_token' && event.newValue === null) { if (event.key === 'access_token') {
this.window.location.reload(); const tokenRemoved = event.newValue === null;
const tokenAdded = event.oldValue === null && event.newValue !== null;
if (tokenRemoved || tokenAdded) {
this.window.location.assign('/');
}
} }
}); });
} }

2
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html

@ -40,7 +40,7 @@
</div> </div>
</div> </div>
<fieldset class="border rounded-4 p-3"> <fieldset class="border rounded-4 p-3">
<legend class="px-1 h5 mb-0">{{ 'Permission Group' }}</legend> <legend class="px-1 h5 mb-0">{{ 'AbpPermissionManagement::PermissionGroup' | abpLocalization }}</legend>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="overflow-auto lpx-scroll-pills-container scroll-in-modal"> <div class="overflow-auto lpx-scroll-pills-container scroll-in-modal">

6
npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.html

@ -131,9 +131,11 @@
formName="emailTestForm" formName="emailTestForm"
[disabled]="emailTestForm.invalid && emailTestForm.dirty" [disabled]="emailTestForm.invalid && emailTestForm.dirty"
> >
<span>{{ 'AbpTenantManagement::Send' | abpLocalization }}</span> <span>{{ 'AbpSettingManagement::Send' | abpLocalization }}</span>
</abp-button> </abp-button>
<button type="button" class="btn btn-secondary" abpClose>Close</button> <button type="button" class="btn btn-secondary" abpClose>
{{ 'AbpUi::Close' | abpLocalization }}
</button>
</ng-template> </ng-template>
</abp-modal> </abp-modal>

Loading…
Cancel
Save